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

class StockBuyButton extends React.Component {
  render () {
    const {amount, stockAmount, cash, incrementStock, stockCost, maxStock} = this.props
    return (

        <button className='btn btn-default'
                onClick={() => incrementStock(amount, stockCost)}
                disabled={stockAmount > maxStock - amount || cash < stockCost * amount}>
          x {amount} (${stockCost * amount})
        </button>

    )
  }
  static propTypes = {
    stockAmount: PropTypes.number.isRequired,
    amount: PropTypes.number.isRequired,
    cash: PropTypes.number.isRequired,
    stockCost: PropTypes.number.isRequired,
    maxStock: PropTypes.number.isRequired,
    incrementStock: PropTypes.func.isRequired
  };
}

class Business extends React.Component {
  start_stock_take (seconds, sellStock) {
    this.timer = setTimeout(() => {
      if (this.props.stockAmount > 0) {
        sellStock()
      }
      this.start_stock_take(seconds, sellStock)
    }, seconds)
  }
  componentDidMount () {
    this.start_stock_take(1000, this.props.sellStock)
  }
  componentWillUnmount () {
    if (this.timer) {
      clearTimeout(this.timer)
    }
  }
  getPanelType (stockAmount) {
    var panel_type = 'panel '
    if (stockAmount <= 0) {
      panel_type = panel_type.concat('panel-danger')
    } else if (stockAmount < 5) {
      panel_type = panel_type.concat('panel-warning')
    } else panel_type = panel_type.concat('panel-success')

    return panel_type
  }
  render () {
    const {name, stockAmount, cash, incrementStock, sellBusiness, stockCost, sellPrice, maxStock} = this.props
    var panel_type = this.getPanelType(stockAmount)

    return (

{name}

Stock Remaining: {stockAmount}

Sale Price: {sellPrice}

          Buy Stock @ ${stockCost}:

            <StockBuyButton amount={1} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount}/>
            <StockBuyButton amount={5} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount} />
            <StockBuyButton amount={maxStock - stockAmount} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount} />

          <button className='btn btn-danger' onClick={() => sellBusiness(stockAmount * stockCost)}>Sell @ ${stockAmount * stockCost}</button>

    )
  }
  static propTypes = {
    name: PropTypes.string.isRequired,
    stockAmount: PropTypes.number.isRequired,
    cash: PropTypes.number.isRequired,
    stockCost: PropTypes.number.isRequired,
    maxStock: PropTypes.number.isRequired,
    sellPrice: PropTypes.number.isRequired,
    incrementStock: PropTypes.func.isRequired,
    sellBusiness: PropTypes.func.isRequired,
    sellStock: PropTypes.func.isRequired
  };
}
export default Business
<commit_msg>confirm on delete<commit_after>import React, { PropTypes } from 'react'

class StockBuyButton extends React.Component {
  render () {
    const {amount, stockAmount, cash, incrementStock, stockCost, maxStock} = this.props
    return (

        <button className='btn btn-default'
                onClick={() => incrementStock(amount, stockCost)}
                disabled={stockAmount > maxStock - amount || cash < stockCost * amount}>
          x {amount} (${stockCost * amount})
        </button>

    )
  }
  static propTypes = {
    stockAmount: PropTypes.number.isRequired,
    amount: PropTypes.number.isRequired,
    cash: PropTypes.number.isRequired,
    stockCost: PropTypes.number.isRequired,
    maxStock: PropTypes.number.isRequired,
    incrementStock: PropTypes.func.isRequired
  };
}

class Business extends React.Component {
  start_stock_take (seconds, sellStock) {
    this.timer = setTimeout(() => {
      if (this.props.stockAmount > 0) {
        sellStock()
      }
      this.start_stock_take(seconds, sellStock)
    }, seconds)
  }
  componentDidMount () {
    this.start_stock_take(1000, this.props.sellStock)
  }
  componentWillUnmount () {
    if (this.timer) {
      clearTimeout(this.timer)
    }
  }
  getPanelType (stockAmount) {
    var panel_type = 'panel '
    if (stockAmount <= 0) {
      panel_type = panel_type.concat('panel-danger')
    } else if (stockAmount < 5) {
      panel_type = panel_type.concat('panel-warning')
    } else panel_type = panel_type.concat('panel-success')

    return panel_type
  }
  delete_business (stockAmount, stockCost, sellBusiness) {
    if (confirm('Are you sure you want to delete?')) {
      sellBusiness(stockAmount * stockCost)
    }
  }
  render () {
    const {name, stockAmount, cash, incrementStock, sellBusiness, stockCost, sellPrice, maxStock} = this.props
    var panel_type = this.getPanelType(stockAmount)

    return (

{name}

Stock Remaining: {stockAmount}

Sale Price: {sellPrice}

          Buy Stock @ ${stockCost}:

            <StockBuyButton amount={1} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount}/>
            <StockBuyButton amount={5} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount} />
            <StockBuyButton amount={maxStock - stockAmount} cash={cash} stockCost={stockCost} incrementStock={incrementStock} maxStock={maxStock} stockAmount={stockAmount} />

          <button className='btn btn-danger' onClick={() => this.delete_business(stockAmount, stockCost, sellBusiness)}>Sell @ ${stockAmount * stockCost}</button>

    )
  }
  static propTypes = {
    name: PropTypes.string.isRequired,
    stockAmount: PropTypes.number.isRequired,
    cash: PropTypes.number.isRequired,
    stockCost: PropTypes.number.isRequired,
    maxStock: PropTypes.number.isRequired,
    sellPrice: PropTypes.number.isRequired,
    incrementStock: PropTypes.func.isRequired,
    sellBusiness: PropTypes.func.isRequired,
    sellStock: PropTypes.func.isRequired
  };
}
export default Business
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

import {addToCart} from '../store/actions/cart';

const addQty = (item, qty, options) => ev => {
    ev.preventDefault();
    addToCart(item._id, qty, options);
}

const CartItem = ({
    item,
    quantity,
    options
}) => (

                {item.name}

{item.name}

{item.shortDescription}

                            { Object.keys(options).map(key => (
{ `${key}: ${options[key]}`}
)) }

            -
            {quantity}
            +

);

CartItem.propTypes = {
    item: PropTypes.shape({
        name: PropTypes.string,
        description: PropTypes.string,
        shortDescription: PropTypes.string,
        files: PropTypes.array
    }).isRequired,
    quantity: PropTypes.number.isRequired,
    options: PropTypes.object,
};

CartItem.defaultProps = {
    options: {}
};

export default CartItem;

<commit_msg>missgin key on cart item option<commit_after>import React from 'react';
import PropTypes from 'prop-types';

import {addToCart} from '../store/actions/cart';

const addQty = (item, qty, options) => ev => {
    ev.preventDefault();
    addToCart(item._id, qty, options);
}

const CartItem = ({
    item,
    quantity,
    options
}) => (

                {item.name}

{item.name}

{item.shortDescription}

                            { Object.keys(options).map(key => (
{ `${key}: ${options[key]}`}
)) }

            -
            {quantity}
            +

);

CartItem.propTypes = {
    item: PropTypes.shape({
        name: PropTypes.string,
        description: PropTypes.string,
        shortDescription: PropTypes.string,
        files: PropTypes.array
    }).isRequired,
    quantity: PropTypes.number.isRequired,
    options: PropTypes.object,
};

CartItem.defaultProps = {
    options: {}
};

export default CartItem;

<|endoftext|>


<commit_before>window.config = {
  routerBasename: '/',
  enableGoogleCloudAdapter: true,
  servers: {
    // This is an array, but we'll only use the first entry for now
    dicomWeb: [],
  },
  // This is an array, but we'll only use the first entry for now
  oidc: [
    {
      // ~ REQUIRED
      // Authorization Server URL
      authority: 'https://accounts.google.com',
      client_id:
        '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
      redirect_uri: '/callback', // `OHIFStandaloneViewer.js`
      response_type: 'id_token token',
      scope:
        'email profile openid https://www.googleapis.com/auth/cloudplatformprojects.readonly https://www.googleapis.com/auth/cloud-healthcare', // email profile openid
      // ~ OPTIONAL
      post_logout_redirect_uri: '/logout-redirect.html',
      revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
      automaticSilentRenew: true,
      revokeAccessTokenOnSignout: true,
    },
  ],
  studyListFunctionsEnabled: true,
};
<commit_msg>clean back default config (#2438)<commit_after>window.config = {
  // default: '/'
  routerBasename: '/',
  extensions: [],
  showStudyList: true,
  filterQueryParam: false,
  disableServersCache: false,
  servers: {
    dicomWeb: [
      {
        name: 'DCM4CHEE',
        wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
        qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        qidoSupportsIncludeField: true,
        imageRendering: 'wadors',
        thumbnailRendering: 'wadors',
        enableStudyLazyLoad: true,
        supportsFuzzyMatching: true,
      },
    ],
  },
  // Extensions should be able to suggest default values for these?
  // Or we can require that these be explicitly set
  hotkeys: [
    // ~ Global
    {
      commandName: 'incrementActiveViewport',
      label: 'Next Viewport',
      keys: ['right'],
    },
    {
      commandName: 'decrementActiveViewport',
      label: 'Previous Viewport',
      keys: ['left'],
    },
    // Supported Keys: https://craig.is/killing/mice
    // ~ Cornerstone Extension
    { commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
    { commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
    { commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
    {
      commandName: 'flipViewportVertical',
      label: 'Flip Horizontally',
      keys: ['h'],
    },
    {
      commandName: 'flipViewportHorizontal',
      label: 'Flip Vertically',
      keys: ['v'],
    },
    { commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
    { commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
    { commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
    { commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
    // clearAnnotations
    { commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
    { commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
    // firstImage
    // lastImage
    {
      commandName: 'previousViewportDisplaySet',
      label: 'Previous Series',
      keys: ['pagedown'],
    },
    {
      commandName: 'nextViewportDisplaySet',
      label: 'Next Series',
      keys: ['pageup'],
    },
    // ~ Cornerstone Tools
    { commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
    // ~ Window level presets
    {
      commandName: 'windowLevelPreset1',
      label: 'W/L Preset 1',
      keys: ['1'],
    },
    {
      commandName: 'windowLevelPreset2',
      label: 'W/L Preset 2',
      keys: ['2'],
    },
    {
      commandName: 'windowLevelPreset3',
      label: 'W/L Preset 3',
      keys: ['3'],
    },
    {
      commandName: 'windowLevelPreset4',
      label: 'W/L Preset 4',
      keys: ['4'],
    },
    {
      commandName: 'windowLevelPreset5',
      label: 'W/L Preset 5',
      keys: ['5'],
    },
    {
      commandName: 'windowLevelPreset6',
      label: 'W/L Preset 6',
      keys: ['6'],
    },
    {
      commandName: 'windowLevelPreset7',
      label: 'W/L Preset 7',
      keys: ['7'],
    },
    {
      commandName: 'windowLevelPreset8',
      label: 'W/L Preset 8',
      keys: ['8'],
    },
    {
      commandName: 'windowLevelPreset9',
      label: 'W/L Preset 9',
      keys: ['9'],
    },
  ],
  cornerstoneExtensionConfig: {},
  // Following property limits number of simultaneous series metadata requests.
  // For http/1.x-only servers, set this to 5 or less to improve
  //  on first meaningful display in viewer
  // If the server is particularly slow to respond to series metadata
  //  requests as it extracts the metadata from raw files everytime,
  //  try setting this to even lower value
  // Leave it undefined for no limit, sutiable for HTTP/2 enabled servers
  // maxConcurrentMetadataRequests: 5,
};
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import CodeMirror from 'react-codemirror'
import 'codemirror/mode/python/python'
import Slider from 'rc-slider'
import Tooltip from 'rc-tooltip'
import _ from 'lodash'

class DataHint extends Component {
  constructor(props) {
    super(props)
    this.state = {
      id: 0,
      step: 0,
      stop: false,
      message: '',
      code: '',
      origin: '',
      traces: [],
    }
    window.dataHint = this
  }

  componentDidMount() {
    setTimeout(() => {
      this.init()
    }, 500)
  }

  init() {
    this.setState({
      id: this.props.id,
      code: this.props.beforeCode,
      origin: this.props.beforeCode,
      traces: this.props.traces,
    })
    this.cm = this.refs.editor.getCodeMirror()
  }

  playStep() {
    let interval = 100
    this.setState({ stop: false })
    let timer = setInterval(() => {
      if (this.state.step >= this.state.traces.length || this.state.stop) {
        clearInterval(timer)
        this.setState({ stop: false })
      } else {
        this.updateStep(this.state.step+1)
      }
    }, interval)
  }

  updateStep(value) {
    let step = Math.floor(value)
    this.cm.setValue(this.state.origin)

    let current = this.state.traces[step]
    if (current.error) {
      this.cm.addLineClass(current.line-1, '', 'highlight')
      this.setState({ stop: true })
    } else {
      this.cm.addLineClass(current.line-1, '', 'current-line')
    }

    for (let line of Object.keys(current.outputs)) {
      let output = current.outputs[line]
      output = JSON.stringify(output)
      let fixedOutput = current.fixedOutputs ? current.fixedOutputs[line] : null
      if (fixedOutput && !_.isEqual(output, fixedOutput)) {
        output += ' should be '
        output += JSON.stringify(fixedOutput)
      }

      let ch = this.state.origin.split('\n')[line-1].length
      let space = ' '
      // for (let i = ch; i < 30; i++) {
      //   space += ' '
      // }
      let msg = `${space} # ${JSON.stringify(output)}`
      this.cm.replaceRange(msg, { line: line-1, ch: ch }, { line: line-1, ch: Infinity })
    }
    let code = this.cm.getValue()
    this.setState({ step: step, code: code })
  }

  render() {
    return (

            Data Hint

{ this.state.message }

          <button className="ui basic button play-button" onClick={ this.playStep.bind(this) }>

          </button>
          <Slider
            dots
            min={ 0 }
            max={ this.state.traces.length-1 }
            value={ this.state.step }
            onChange={ this.updateStep.bind(this) }
          />

        <CodeMirror
          value={ this.state.code }
          ref="editor"
          options={ this.props.options }
        />

    )
  }
}

export default DataHint
<commit_msg>Finish data tracing hint<commit_after>import React, { Component } from 'react'
import CodeMirror from 'react-codemirror'
import 'codemirror/mode/python/python'
import Slider from 'rc-slider'
import Tooltip from 'rc-tooltip'
import _ from 'lodash'

class DataHint extends Component {
  constructor(props) {
    super(props)
    this.state = {
      id: 0,
      step: 0,
      stop: false,
      message: '',
      code: '',
      origin: '',
      traces: [],
    }
    window.dataHint = this
  }

  componentDidMount() {
    setTimeout(() => {
      this.init()
    }, 500)
  }

  init() {
    this.setState({
      id: this.props.id,
      code: this.props.beforeCode,
      origin: this.props.beforeCode,
      traces: this.props.traces,
    })
    this.cm = this.refs.editor.getCodeMirror()
  }

  playStep() {
    let interval = 100
    this.setState({ stop: false })
    let timer = setInterval(() => {
      if (this.state.step >= this.state.traces.length || this.state.stop) {
        clearInterval(timer)
        this.setState({ stop: false })
      } else {
        this.updateStep(this.state.step+1)
      }
    }, interval)
  }

  updateStep(value) {
    let step = Math.floor(value)
    this.cm.setValue(this.state.origin)

    let current = this.state.traces[step]
    if (current.error) {
      this.cm.addLineClass(current.line-1, '', 'highlight')
      this.setState({ stop: true })
    } else {
      this.cm.addLineClass(current.line-1, '', 'current-line')
    }

    const getMsg = (output) => {
      let msg = ''
      for (let key of Object.keys(output)) {
        if (output[key] instanceof Object) {
          msg += key
          msg += '('
          msg += _.map(output[key]).join(', ')
          msg += ')'
        } else {
          if (key === '__return__') {
            msg += 'return'
          } else {
            msg += key
          }
          msg += ': '
          if (output[key]) msg += output[key]
        }
      }
      return msg
    }

    window.current = current
    for (let line of Object.keys(current.outputs)) {
      let output = current.outputs[line]
      // output = JSON.stringify(output)
      let msg = getMsg(output)

      let fixedOutput = current.fixedOutputs ? current.fixedOutputs[line] : null
      if (fixedOutput && !_.isEqual(output, fixedOutput)) {
        msg += ' should be '
        msg += getMsg(fixedOutput)
      }

      let ch = this.state.origin.split('\n')[line-1].length
      let space = ' '
      // for (let i = ch; i < 30; i++) {
      //   space += ' '
      // }
      msg = `${space} # ${msg}`
      this.cm.replaceRange(msg, { line: line-1, ch: ch }, { line: line-1, ch: Infinity })
    }
    let code = this.cm.getValue()
    this.setState({ step: step, code: code })
  }

  render() {
    return (

            Data Hint

{ this.state.message }

          <button className="ui basic button play-button" onClick={ this.playStep.bind(this) }>

          </button>
          <Slider
            dots
            min={ 0 }
            max={ this.state.traces.length-1 }
            value={ this.state.step }
            onChange={ this.updateStep.bind(this) }
          />

        <CodeMirror
          value={ this.state.code }
          ref="editor"
          options={ this.props.options }
        />

    )
  }
}

export default DataHint
<|endoftext|>


<commit_before>import React from 'react';
import logo from '../logo.svg';
import '../css/App.css';
import { Form, FormGroup, FormControl, Button } from 'react-bootstrap';

const FormBook = (props) => {
  return (
    <Form inline onSubmit={props.onSubmit}>
      <FormGroup bsSize="small">
        <FormControl id="searchForm" type="text" placeholder="Search for books" onChange={props.onChange} style={{"width": "40em", "marginLeft": "100px"}}></FormControl>
      </FormGroup>
      {' '}
      <Button type="submit">Search </Button>
    </Form>
  )
}

// FormBook.propTypes = {
//   onSubmit: React.PropTypes.func,
//   onChange: React.PropTypes.func
// }

export default FormBook;<commit_msg>add propTypes<commit_after>import React from 'react';
import logo from '../logo.svg';
import '../css/App.css';
import { Form, FormGroup, FormControl, Button } from 'react-bootstrap';

const FormBook = (props) => {
  return (
    <Form inline onSubmit={props.onSubmit}>
      <FormGroup bsSize="small">
        <FormControl id="searchForm" type="text" placeholder="Search for books" onChange={props.onChange} style={{"width": "40em", "marginLeft": "100px"}}></FormControl>
      </FormGroup>
      {' '}
      <Button type="submit">Search </Button>
    </Form>
  )
}

FormBook.propTypes = {
  onSubmit: React.PropTypes.func,
  onChange: React.PropTypes.func
}

export default FormBook;
<|endoftext|>


<commit_before>import React from 'react';
import {Link} from 'react-router';

const HomePage = () => {
  return (

React Slingshot

Get Started

Review the <Link to="fuel-savings">demo app</Link>

Remove the demo and start coding: npm run remove-demo

  );
};

export default HomePage;
<commit_msg>removed HomePage<commit_after><|endoftext|>


<commit_before>'use strict'
var nodemailer = require('nodemailer')
var sparkPostTransport = require('nodemailer-sparkpost-transport')

var Promise = require('bluebird')
var appInfo = require('../appInfo.json')
var sparkPostApiKey = process.env.sparkPostApiKey
var transporter = nodemailer.createTransport(sparkPostTransport({
  sparkPostApiKey: sparkPostApiKey
}))
var send = Promise.promisify(transporter.sendMail, {
  context: transporter
})

function emailer(recipient, subject, message) {
  return send({
    recipients: [{
      address: {
        email: recipient
      }
    }],
    content: {
      from: {
        name: appInfo.name,
        email: 'app@' + appInfo.host
      },
      subject: subject,
      text: message
    }
  })
}

module.exports = emailer
<commit_msg>Added development mode for emailer.<commit_after>'use strict'
var nodemailer = require('nodemailer')
var sparkPostTransport = require('nodemailer-sparkpost-transport')

var Promise = require('bluebird')
var appInfo = require('../appInfo.json')
var sparkPostApiKey = process.env.sparkPostApiKey
var transporter = nodemailer.createTransport(sparkPostTransport({
  sparkPostApiKey: sparkPostApiKey
}))
var send = Promise.promisify(transporter.sendMail, {
  context: transporter
})

function emailer(recipient, subject, message) {
  if (process.env.NODE_ENV === 'production') {
    return send({
      recipients: [{
        address: {
          email: recipient
        }
      }],
      content: {
        from: {
          name: appInfo.name,
          email: 'app@' + appInfo.host
        },
        subject: subject,
        text: message
      }
    })
  } else {
    console.info('Pretended to send an email.', recipient, subject, message)
    return Promise.resolve()
  }
}

module.exports = emailer
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { getChart } from '../helpers/backendInterface';
import { log, LOW } from '../helpers/log';
import { setDisplayChartAction } from '../actions/chartActions';

function updateOldChartData(token, id, chart, cb){
  getChart(token, id)
  .then(function({ info }){
    if(chart.id !== info[0].id){
      cb(info[0]);
    }
  })
  .catch(function(err){
    log('Error': err, LOW);
  });
}

function PollPage(props){
  updateOldChartData(
    props.token,
    props.params.pollid,
    props.chart,
    props.setDisplayChart
  );
  const chart = props.chart;
  return(

Poll Page

      id : {chart.id}

      title: {chart.title}

      description: {chart.description}

  );
}
PollPage.propTypes = {
  token: PropTypes.string,
  chart: PropTypes.object,
  setDisplayChart: PropTypes.func
};
const mapStateToProps = (state) => {
  return {
    token: localStorage.token,
    chart: state.chart
  };
};
const mapDispatchToProps = (dispatch) => {
  return {
    setDisplayChart: (chart) => dispatch(setDisplayChartAction(chart))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(PollPage);
<commit_msg>fixed proptype<commit_after>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { getChart } from '../helpers/backendInterface';
import { log, LOW } from '../helpers/log';
import { setDisplayChartAction } from '../actions/chartActions';

function updateOldChartData(token, id, chart, cb){
  getChart(token, id)
  .then(function({ info }){
    if(chart.id !== info[0].id){
      cb(info[0]);
    }
  })
  .catch(function(err){
    log('Error': err, LOW);
  });
}

function PollPage(props){
  updateOldChartData(
    props.token,
    props.params.pollid,
    props.chart,
    props.setDisplayChart
  );
  const chart = props.chart;
  return(

Poll Page

      id : {chart.id}

      title: {chart.title}

      description: {chart.description}

  );
}
PollPage.propTypes = {
  params: PropTypes.object,
  token: PropTypes.string,
  chart: PropTypes.object,
  setDisplayChart: PropTypes.func
};
const mapStateToProps = (state) => {
  return {
    token: localStorage.token,
    chart: state.chart
  };
};
const mapDispatchToProps = (dispatch) => {
  return {
    setDisplayChart: (chart) => dispatch(setDisplayChartAction(chart))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(PollPage);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ProjectDetailsModal from './ProjectDetailsModal';

class Projects extends Component {
  constructor(props) {
    super(props);
    this.state = {
      deps: {},
      detailsModalShow: false,
    };
  }

  render() {
    let detailsModalShow = (data) => {
      this.setState({ detailsModalShow: true, deps: data });
    };

    let detailsModalClose = () => this.setState({ detailsModalShow: false });
    if (this.props.data) {
      var sectionName = document.documentElement.lang === 'pl' ? 'Projekty' : 'Projects';
      var projects = this.props.data.map(function (projects) {
        return (

 detailsModalShow(projects)}>

{projects.title}

        );
      });
    }

    return (

          {sectionName}

{projects}

          <ProjectDetailsModal
            show={this.state.detailsModalShow}
            onHide={detailsModalClose}
            data={this.state.deps}
          />

    );
  }
}

export default Projects;
<commit_msg>Set projects placeholder height<commit_after>import React, { Component } from 'react';
import ProjectDetailsModal from './ProjectDetailsModal';

class Projects extends Component {
  constructor(props) {
    super(props);
    this.state = {
      deps: {},
      detailsModalShow: false,
    };
  }

  render() {
    let detailsModalShow = (data) => {
      this.setState({ detailsModalShow: true, deps: data });
    };

    let detailsModalClose = () => this.setState({ detailsModalShow: false });
    if (this.props.data) {
      var sectionName = document.documentElement.lang === 'pl' ? 'Projekty' : 'Projects';
      var projects = this.props.data.map(function (projects) {
        return (

 detailsModalShow(projects)}>

{projects.title}

        );
      });
    }

    return (

          {sectionName}

{projects}

          <ProjectDetailsModal
            show={this.state.detailsModalShow}
            onHide={detailsModalClose}
            data={this.state.deps}
          />

    );
  }
}

export default Projects;
<|endoftext|>


<commit_before>'use strict';

var React = require('react/addons');
var {SvgIcon} = require('material-ui');

var Line = React.createClass({

  render() {
    return (
      <SvgIcon>
        <line stroke="black" strokeWidth="3" strokeLinecap="round" x1="20" y1="4" x2="4" y2="20"/>
      </SvgIcon>
    );
  }

});

var Curve = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="none" stroke="black" strokeWidth="2.75" strokeLinecap="round" d="M20,4C7.3,6,19,17,4,20"/>
      </SvgIcon>
    );
  }

});

var MultiLine = React.createClass({

  render() {
    return (
      <SvgIcon>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="8" y1="10" x2="20" y2="4"/>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="6" y1="15" x2="17" y2="11"/>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="4" y1="20" x2="14" y2="18"/>
      </SvgIcon>
    );
  }

});

var Viewfinder = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="none" stroke="black" strokeWidth="2.22" strokeLinecap="round" d="M3.1,9.3c7.9,9,8.7,0.6,17.8,3.2"/>
        <path d="M19.8,17.6H4.2V6.4h15.6 M19.8,4.2H4.2C3,4.2,2,5.2,2,6.4v11.1c0,1.2,1,2.2,2.2,2.2h15.6c1.2,0,2.2-1,2.2-2.2V6.4,C22,5.2,21,4.2,19.8,4.2z"/>
      </SvgIcon>
    );
  }

});

var CursorMove = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="black" d="M13,6V11H18V7.75L22.25,12L18,16.25V13H13V18H16.25L12,22.25L7.75,18H11V13H6V16.25L1.75,12L6,7.75V11H11V6H7.75L12,1.75L16.25,6H13Z" />
      </SvgIcon>
    );
  }

});

module.exports = {Line, Curve, MultiLine, Viewfinder, CursorMove};
<commit_msg>add OnionSkin SvgIcon<commit_after>'use strict';

var React = require('react/addons');
var {SvgIcon} = require('material-ui');

var Line = React.createClass({

  render() {
    return (
      <SvgIcon>
        <line stroke="black" strokeWidth="3" strokeLinecap="round" x1="20" y1="4" x2="4" y2="20"/>
      </SvgIcon>
    );
  }

});

var Curve = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="none" stroke="black" strokeWidth="2.75" strokeLinecap="round" d="M20,4C7.3,6,19,17,4,20"/>
      </SvgIcon>
    );
  }

});

var MultiLine = React.createClass({

  render() {
    return (
      <SvgIcon>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="8" y1="10" x2="20" y2="4"/>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="6" y1="15" x2="17" y2="11"/>
        <line stroke="black" strokeWidth="2.5" strokeLinecap="round" x1="4" y1="20" x2="14" y2="18"/>
      </SvgIcon>
    );
  }

});

var Viewfinder = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="none" stroke="black" strokeWidth="2.22" strokeLinecap="round" d="M3.1,9.3c7.9,9,8.7,0.6,17.8,3.2"/>
        <path d="M19.8,17.6H4.2V6.4h15.6 M19.8,4.2H4.2C3,4.2,2,5.2,2,6.4v11.1c0,1.2,1,2.2,2.2,2.2h15.6c1.2,0,2.2-1,2.2-2.2V6.4,C22,5.2,21,4.2,19.8,4.2z"/>
      </SvgIcon>
    );
  }

});

var CursorMove = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="black" d="M13,6V11H18V7.75L22.25,12L18,16.25V13H13V18H16.25L12,22.25L7.75,18H11V13H6V16.25L1.75,12L6,7.75V11H11V6H7.75L12,1.75L16.25,6H13Z" />
      </SvgIcon>
    );
  }

});

var OnionSkin = React.createClass({

  render() {
    return (
      <SvgIcon>
        <path fill="black" d="M4.2,8.7V6.4H2v2.2 M17.6,4.2c0-1.2-1-2.2-2.2-2.2v2.2 M8.7,4.2V2H6.4v2.2 M13.1,4.2V2h-2.2v2.2 M17.6,15.3h-2.2v2.2,C16.6,17.6,17.6,16.6,17.6,15.3 M2,10.9v2.2h2.2v-2.2 M2,4.2h2.2V2C3,2,2,3,2,4.2 M15.3,10.9v2.2h2.2v-2.2 M2,15.3,c0,1.2,1,2.2,2.2,2.2v-2.2 M10.9,15.3v2.2h2.2v-2.2"/>
        <path fill="black" d="M8.7,19.8V8.7h11.1v11.1 M22,19.8V8.7c0-1.2-1-2.2-2.2-2.2H8.7c-1.2,0-2.2,1-2.2,2.2v5.6v4.4v1.1c0,1.2,1,2.2,2.2,2.2h11.1,C21,22,22,21,22,19.8"/>
      </SvgIcon>
    );
  }

});

module.exports = {Line, Curve, MultiLine, Viewfinder, CursorMove, OnionSkin};
<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const puppeteer = require('../..');
const path = require('path');
const Source = require('./Source');

const PROJECT_DIR = path.join(__dirname, '..', '..');
const VERSION = require(path.join(PROJECT_DIR, 'package.json')).version;

const RED_COLOR = '\x1b[31m';
const YELLOW_COLOR = '\x1b[33m';
const RESET_COLOR = '\x1b[0m';

run();

async function run() {
  const startTime = Date.now();

  /** @type {!Array<!Message>} */
  const messages = [];
  let changedFiles = false;

  // Documentation checks.
  const readme = await Source.readFile(path.join(PROJECT_DIR, 'README.md'));
  const contributing = await Source.readFile(path.join(PROJECT_DIR, 'CONTRIBUTING.md'));
  const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));
  const troubleshooting = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'troubleshooting.md'));
  const mdSources = [readme, api, troubleshooting, contributing];

  const preprocessor = require('./preprocessor');
  messages.push(...await preprocessor.runCommands(mdSources, VERSION));
  messages.push(...await preprocessor.ensureReleasedAPILinks([readme], VERSION));

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const checkPublicAPI = require('./check_public_api');
  const jsSources = await Source.readdir(path.join(PROJECT_DIR, 'lib'));
  messages.push(...await checkPublicAPI(page, mdSources, jsSources));

  await browser.close();

  for (const source of mdSources) {
    if (!source.hasUpdatedText())
      continue;
    await source.save();
    changedFiles = true;
  }

  // Report results.
  const errors = messages.filter(message => message.type === 'error');
  if (errors.length) {
    console.log('DocLint Failures:');
    for (let i = 0; i < errors.length; ++i) {
      let error = errors[i].text;
      error = error.split('\n').join('\n      ');
      console.log(`  ${i + 1}) ${RED_COLOR}${error}${RESET_COLOR}`);
    }
  }
  const warnings = messages.filter(message => message.type === 'warning');
  if (warnings.length) {
    console.log('DocLint Warnings:');
    for (let i = 0; i < warnings.length; ++i) {
      let warning = warnings[i].text;
      warning = warning.split('\n').join('\n      ');
      console.log(`  ${i + 1}) ${YELLOW_COLOR}${warning}${RESET_COLOR}`);
    }
  }
  let clearExit = messages.length === 0;
  if (changedFiles) {
    if (clearExit)
      console.log(`${YELLOW_COLOR}Some files were updated.${RESET_COLOR}`);
    clearExit = false;
  }
  console.log(`${errors.length} failures, ${warnings.length} warnings.`);
  const runningTime = Date.now() - startTime;
  console.log(`DocLint Finished in ${runningTime / 1000} seconds`);
  process.exit(clearExit ? 0 : 1);
}
<commit_msg>chore: Log reminder about tsc if DocLint fails locally (#5652)<commit_after>#!/usr/bin/env node
/**
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const puppeteer = require('../..');
const path = require('path');
const Source = require('./Source');

const PROJECT_DIR = path.join(__dirname, '..', '..');
const VERSION = require(path.join(PROJECT_DIR, 'package.json')).version;

const RED_COLOR = '\x1b[31m';
const YELLOW_COLOR = '\x1b[33m';
const RESET_COLOR = '\x1b[0m';

run();

async function run() {
  const startTime = Date.now();

  /** @type {!Array<!Message>} */
  const messages = [];
  let changedFiles = false;

  // Documentation checks.
  const readme = await Source.readFile(path.join(PROJECT_DIR, 'README.md'));
  const contributing = await Source.readFile(path.join(PROJECT_DIR, 'CONTRIBUTING.md'));
  const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));
  const troubleshooting = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'troubleshooting.md'));
  const mdSources = [readme, api, troubleshooting, contributing];

  const preprocessor = require('./preprocessor');
  messages.push(...await preprocessor.runCommands(mdSources, VERSION));
  messages.push(...await preprocessor.ensureReleasedAPILinks([readme], VERSION));

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const checkPublicAPI = require('./check_public_api');
  const jsSources = await Source.readdir(path.join(PROJECT_DIR, 'lib'));
  messages.push(...await checkPublicAPI(page, mdSources, jsSources));

  await browser.close();

  for (const source of mdSources) {
    if (!source.hasUpdatedText())
      continue;
    await source.save();
    changedFiles = true;
  }

  // Report results.
  const errors = messages.filter(message => message.type === 'error');
  if (errors.length) {
    console.log('DocLint Failures:');
    for (let i = 0; i < errors.length; ++i) {
      let error = errors[i].text;
      error = error.split('\n').join('\n      ');
      console.log(`  ${i + 1}) ${RED_COLOR}${error}${RESET_COLOR}`);
    }
  }
  const warnings = messages.filter(message => message.type === 'warning');
  if (warnings.length) {
    console.log('DocLint Warnings:');
    for (let i = 0; i < warnings.length; ++i) {
      let warning = warnings[i].text;
      warning = warning.split('\n').join('\n      ');
      console.log(`  ${i + 1}) ${YELLOW_COLOR}${warning}${RESET_COLOR}`);
    }
  }
  let clearExit = messages.length === 0;
  if (changedFiles) {
    if (clearExit)
      console.log(`${YELLOW_COLOR}Some files were updated.${RESET_COLOR}`);
    clearExit = false;
  }
  console.log(`${errors.length} failures, ${warnings.length} warnings.`);

  if (!clearExit && !process.env.TRAVIS)
    console.log('\nIs your lib/ directory up to date? You might need to `npm run tsc`.\n');

  const runningTime = Date.now() - startTime;
  console.log(`DocLint Finished in ${runningTime / 1000} seconds`);
  process.exit(clearExit ? 0 : 1);
}
<|endoftext|>


<commit_before>import React from 'react';
import Avatar from './avatar';
import TimeAgo from './time-ago';
import previewer from '../previewer';

class Headline extends React.Component {
  render() {
    const { post } = this.props;
    const preview = previewer(post.body);
    const ts = Number(post.created);
    let commentCount = 'Read More';
    if (post.commentCount === 1) {
      commentCount = '1 Comment';
    } else if (post.commentCount > 1) {
      commentCount = post.commentCount + ' Comments';
    }
    return (

· · ·

{post.title}

            <Avatar name={post.name} hex={post.color} />

              <TimeAgo timestamp={ts} />

{post.name}

{commentCount}

    );
  }
}

Headline.propTypes = {
  post: React.PropTypes.shape({
    urlstring: React.PropTypes.string,
    title: React.PropTypes.string,
  }),
};

export default Headline;
<commit_msg>Comment text<commit_after>import React from 'react';
import Avatar from './avatar';
import TimeAgo from './time-ago';
import previewer from '../previewer';

class Headline extends React.Component {
  render() {
    const { post } = this.props;
    const preview = previewer(post.body);
    const ts = Number(post.created);
    const commentCount = Number(post.commentCount);
    let commentCountText = 'Read More';
    if (commentCount === 1) {
      commentCountText = '1 Comment';
    } else if (commentCount > 1) {
      commentCountText = post.commentCount + ' Comments';
    }
    return (

· · ·

{post.title}

            <Avatar name={post.name} hex={post.color} />

              <TimeAgo timestamp={ts} />

{post.name}

{commentCountText}

    );
  }
}

Headline.propTypes = {
  post: React.PropTypes.shape({
    urlstring: React.PropTypes.string,
    title: React.PropTypes.string,
  }),
};

export default Headline;
<|endoftext|>


<commit_before>// constants
const NO_USER_RECIPES = "You have not uploaded any recipes yet.";
const USER_RECIPES_ID = "user-recipes";

// Can be passed to API onload to guarantee auth2 is loaded before execution.
function initUserPageGoogleSignin() {
  initGoogleUserWithListener(loadRecipes);
}

// loads all the recipes when the recipe loads
async function loadRecipes() {
  loadUserRecipes();
  loadTypeRecipes("planner");
  loadTypeRecipes("cookbook");
  document.getElementById("idToken").value = getIdToken();
}

// loads the user made/uploaded recipes specifically from the
// general createRecipeCard function and adds the necessary buttons
async function loadUserRecipes() {
  const response = await fetch('/list-user-recipes?idToken='+ getIdToken());
  const recipes = await response.json();

  let recipesDiv = document.getElementById(USER_RECIPES_ID);
  recipesDiv.innerHTML = "";

  if (Object.keys(recipes)) {
    if (Object.keys(recipes).length == 0) {
      setUpDivWithNoRecipes(USER_RECIPES_ID, NO_USER_RECIPES);
    }
    else {
      for (let key of Object.keys(recipes)) {
        let value = recipes[key];
        createRecipeCard(USER_RECIPES_ID, value);

        // since these cards are the user recipe cards, they need edit/delete buttons
        let elementsToAddToImageDiv = [
          createElement("button", "", {"class": "card-button icon top left far fa-trash-alt"}),
          createElement("button", "", {"class": "card-button icon top right fa fa-edit"}),
        ];
        let imageDivs = document.getElementsByClassName("image-div");
        for (let i = 0; i < imageDivs.length; i++) {
          elementsToAddToImageDiv.forEach(elem => imageDivs[i].appendChild(elem));
        }
      }
      addDeleteFunctionality(recipes);
      addEditFunctionality(recipes);
      changeIcons(recipesDiv, "planner");
      changeIcons(recipesDiv, "cookbook");
    }
  }
}

// loads the recipes the user has added to cookbook
async function loadTypeRecipes(type) {
  const response = await fetch('/list-type-recipes?idToken='+ getIdToken() + "&type="+type);
  const recipes = await response.json();

  let recipesDivID = type + "-recipes";
  document.getElementById(recipesDivID).innerHTML = "";

  // other will be used to set up the icon of the other add to list button
  let other;
  if (type == "planner") {
    other = "cookbook";
  } else {
    other = "planner";
  }

  if (Object.keys(recipes)) {
    if (Object.keys(recipes).length == 0) {
      setUpDivWithNoRecipes(recipesDivID, "You have not added any recipes to your " + type + " yet.");
    }
    else {
      for (let key of Object.keys(recipes)) {
        let value = recipes[key];
        createRecipeCard(recipesDivID, value);
      }
      const recipesDiv = document.getElementById(recipesDivID);
      const addToListButtons = recipesDiv.getElementsByClassName("add-to-" + type + "-btn");
      const removeFromListButtons = recipesDiv.getElementsByClassName("remove-from-" + type + "-btn");
      // there are as many buttons as there are recipes
      for (let i = 0; i < recipes.length; i++) {
        const addToListButton = addToListButtons[i];
        const removeFromListButton = removeFromListButtons[i];

        addToListButton.style.display = "none";
        removeFromListButton.style.display = "inline-block";
      }
      // sets up the icon of the other add to list button to a checkmark if it is contained
      changeIcons(recipesDiv, other);
    }
  }
}

function changeIcons(recipesDiv, type) {
    console.log("changeIcons");
  // TODO: check if they're logged in
  const recipeIDs = recipesDiv.getElementsByClassName("recipe-id");
  const addToListButtons = recipesDiv.getElementsByClassName("add-to-" + type + "-btn");
  const removeFromListButtons = recipesDiv.getElementsByClassName("remove-from-" + type + "-btn");
  // there are as many buttons as there are recipes
  for (let i = 0; i < recipeIDs.length; i++) {
    const recipeID = recipeIDs[i].innerText;
    const addToListButton = addToListButtons[i];

    setIcon(addToListButton, recipeID, type);
  }
}

// adds delete functionality to the delete button in the recipe cards
function addDeleteFunctionality(recipes){
  let recipeDiv = document.getElementById(USER_RECIPES_ID);
  const recipeCards = recipeDiv.getElementsByClassName('recipe-card');
  const deleteButtons = document.getElementsByClassName('fa-trash-alt');
  // there are as many delete buttons as there are recipe cards
  for (let i = 0; i < deleteButtons.length; i++) {
    let recipe = recipes[i];
    let recipeCard = recipeCards[i];
    let recipeID = recipeCard.getElementsByClassName("recipe-id")[0];

    deleteButtons[i].addEventListener('click', () => {
      let message = "Are you sure you want to delete the " + recipe.name + " recipe?\n";
      if (recipe.published) {
        message += "This recipe will no longer be able to be accessed by any user.\n";
      }
      message += "This action cannot be undone.";
      const deleteConfirmed = confirm(message);
      if (deleteConfirmed) {
        deleteRecipe(recipe);
        // Remove the recipe from the DOM.
        removeRecipeCardFromLists(recipeID, "planner");
        removeRecipeCardFromLists(recipeID, "cookbook");
        recipeCard.remove();
      }
      if (recipeCards.length == 0) {
        setUpDivWithNoRecipes(USER_RECIPES_ID, NO_USER_RECIPES);
      }
    });
  }
}

// input is recipe id and type of list
// removes the recipe card from the DOM
function removeRecipeCardFromLists(id, type) {
  const recipeDivID = type + "-recipes";
  let recipeDiv = document.getElementById(recipeDivID);
  let recipeCards = recipeDiv.getElementsByClassName('recipe-card');

  for (let i = 0; i < recipeCards.length; i++) {
    let recipeCard = recipeCards[i];
    let recipeID = recipeCard.getElementsByClassName("recipe-id")[0];
    if (recipeID.innerText == id.innerText) {
      recipeCard.remove();
    }
  }

  if (recipeCards.length == 0) {
    setUpDivWithNoRecipes(recipeDivID, "You have not added any recipes to your " + type + " yet.");
  }
}

// tells the server to delete the recipe.
// input is a recipe js object
function deleteRecipe(recipe) {
  const params = new URLSearchParams();
  params.append("id", recipe.id);
  fetch("/delete-recipe", {method: "POST", body: params});
}

// adds edit functionality to the edit button in the recipe cards
function addEditFunctionality(recipes) {
  const editButtons = document.getElementsByClassName('fa-edit');
  const recipeCards = document.getElementsByClassName('recipe-card');
  // there are as many edit buttons as there are recipe cards
  for (let i = 0; i < editButtons.length; i++) {
    let recipe = recipes[i];
    let recipeCard = recipeCards[i];
    editButtons[i].addEventListener('click', () => {
      openModal("edit-recipe-modal");
      addExistingValuesToEditForm(recipe);
    });
  }
}

// adds values of stored recipe to edit recipe form
function addExistingValuesToEditForm(recipe) {
  document.getElementById("recipeID").value = recipe.id;
  document.getElementById("edit-name").value = recipe.name;
  document.getElementById("edit-description").value = recipe.description;
  // sets up tags
  if (recipe.tags.length > 0) {
    document.getElementById("edit-tags").value = recipe.tags[0];
    for (let i = 1; i < recipe.tags.length; i++) {
      document.getElementById("edit-tags").value += ", " + recipe.tags[i];
    }
  }
  // sets up ingredients
  if (recipe.ingredients.length > 0) {
    document.getElementById("edit-ingredients").value = recipe.ingredients[0];
    for (let i = 1; i < recipe.ingredients.length; i++) {
      document.getElementById("edit-ingredients").value += "\n" + recipe.ingredients[i];
    }
  }
  // sets up steps
  if (recipe.steps.length > 0) {
    document.getElementById("edit-steps").value = recipe.steps[0];
    for (let i = 1; i < recipe.steps.length; i++) {
      document.getElementById("edit-steps").value += "\n" + recipe.steps[i];
    }
  }
  // TODO: figure out image value (low priority)

  // sets the default to the current value
  if (recipe.published) {
    setOption("first", "public");
    setOption("second", "private");
  } else {
    setOption("first", "private");
    setOption("second", "public");
  }
}

function setOption(id, text) {
  document.getElementById(id).value = text;
  document.getElementById(id).innerText = text;
}

// opens the recipe form modal
function openModal(id) {
  document.getElementById(id).style.display = "block";
  // edit-recipe-modal doesn't have image functionality rn
  if (id == "new-recipe-modal") {
    fetchBlobstoreUrl(id);
  }
}

// takes in div id and message
// makes the recipes container bigger and gives it the message
// to use when there are no recipes in planner/cookbook/user-recipes
setUpDivWithNoRecipes = (divID, message) => {
  let recipesDiv = document.getElementById(divID);
  recipesDiv.innerText = message;
  recipesDiv.style.height = "80px";
}

// not quite sure what this does; something with blobs and images
function fetchBlobstoreUrl(id) {
  fetch('/blobstore-upload-url?divID='+id)
      .then((response) => {
        return response.text();
      })
      .then((imageUploadUrl) => {
        let form;
        if (id == "new-recipe-modal") {
          form = document.getElementById("new-recipe-form");
        } else if (id == "edit-recipe-modal") {
          form = document.getElementById("edit-recipe-form");
        } else {
          console.log("invalid modal id");
        }
        form.action = imageUploadUrl;
      });
}

// closes the recipe form modal
function closeModal(id) {
  document.getElementById(id).style.display = "none";
}
<commit_msg>remove outdated code<commit_after>// constants
const NO_USER_RECIPES = "You have not uploaded any recipes yet.";
const USER_RECIPES_ID = "user-recipes";

// Can be passed to API onload to guarantee auth2 is loaded before execution.
function initUserPageGoogleSignin() {
  initGoogleUserWithListener(loadRecipes);
}

// loads all the recipes when the recipe loads
async function loadRecipes() {
  loadUserRecipes();
  loadTypeRecipes("planner");
  loadTypeRecipes("cookbook");
  document.getElementById("idToken").value = getIdToken();
}

// loads the user made/uploaded recipes specifically from the
// general createRecipeCard function and adds the necessary buttons
async function loadUserRecipes() {
  const response = await fetch('/list-user-recipes?idToken='+ getIdToken());
  const recipes = await response.json();

  let recipesDiv = document.getElementById(USER_RECIPES_ID);
  recipesDiv.innerHTML = "";

  if (Object.keys(recipes)) {
    if (Object.keys(recipes).length == 0) {
      setUpDivWithNoRecipes(USER_RECIPES_ID, NO_USER_RECIPES);
    }
    else {
      for (let key of Object.keys(recipes)) {
        let value = recipes[key];
        createRecipeCard(USER_RECIPES_ID, value);

        // since these cards are the user recipe cards, they need edit/delete buttons
        let elementsToAddToImageDiv = [
          createElement("button", "", {"class": "card-button icon top left far fa-trash-alt"}),
          createElement("button", "", {"class": "card-button icon top right fa fa-edit"}),
        ];
        let imageDivs = document.getElementsByClassName("image-div");
        for (let i = 0; i < imageDivs.length; i++) {
          elementsToAddToImageDiv.forEach(elem => imageDivs[i].appendChild(elem));
        }
      }
      addDeleteFunctionality(recipes);
      addEditFunctionality(recipes);
      changeIcons(recipesDiv, "planner");
      changeIcons(recipesDiv, "cookbook");
    }
  }
}

// loads the recipes the user has added to cookbook
async function loadTypeRecipes(type) {
  const response = await fetch('/list-type-recipes?idToken='+ getIdToken() + "&type="+type);
  const recipes = await response.json();

  let recipesDivID = type + "-recipes";
  document.getElementById(recipesDivID).innerHTML = "";

  if (Object.keys(recipes)) {
    if (Object.keys(recipes).length == 0) {
      setUpDivWithNoRecipes(recipesDivID, "You have not added any recipes to your " + type + " yet.");
    }
    else {
      for (let key of Object.keys(recipes)) {
        let value = recipes[key];
        createRecipeCard(recipesDivID, value);
      }
      const recipesDiv = document.getElementById(recipesDivID);
      const addToListButtons = recipesDiv.getElementsByClassName("add-to-" + type + "-btn");
      const removeFromListButtons = recipesDiv.getElementsByClassName("remove-from-" + type + "-btn");
      // there are as many buttons as there are recipes
      for (let i = 0; i < recipes.length; i++) {
        const addToListButton = addToListButtons[i];
        const removeFromListButton = removeFromListButtons[i];

        addToListButton.style.display = "none";
        removeFromListButton.style.display = "inline-block";
      }
      // sets up the icon of the other add to list button to a checkmark if it is contained
      if (type == "planner") {
        changeIcons(recipesDiv, "cookbook");
      } else {
        changeIcons(recipesDiv, "planner");
      }
    }
  }
}

function changeIcons(recipesDiv, type) {
  // TODO: check if they're logged in
  const recipeIDs = recipesDiv.getElementsByClassName("recipe-id");
  const addToListButtons = recipesDiv.getElementsByClassName("add-to-" + type + "-btn");
  // there are as many buttons as there are recipeIDs
  for (let i = 0; i < recipeIDs.length; i++) {
    const recipeID = recipeIDs[i].innerText;
    const addToListButton = addToListButtons[i];

    setIcon(addToListButton, recipeID, type);
  }
}

// adds delete functionality to the delete button in the recipe cards
function addDeleteFunctionality(recipes){
  let recipeDiv = document.getElementById(USER_RECIPES_ID);
  const recipeCards = recipeDiv.getElementsByClassName('recipe-card');
  const deleteButtons = document.getElementsByClassName('fa-trash-alt');
  // there are as many delete buttons as there are recipe cards
  for (let i = 0; i < deleteButtons.length; i++) {
    let recipe = recipes[i];
    let recipeCard = recipeCards[i];
    let recipeID = recipeCard.getElementsByClassName("recipe-id")[0];

    deleteButtons[i].addEventListener('click', () => {
      let message = "Are you sure you want to delete the " + recipe.name + " recipe?\n";
      if (recipe.published) {
        message += "This recipe will no longer be able to be accessed by any user.\n";
      }
      message += "This action cannot be undone.";
      const deleteConfirmed = confirm(message);
      if (deleteConfirmed) {
        deleteRecipe(recipe);
        // Remove the recipe from the DOM.
        removeRecipeCardFromLists(recipeID, "planner");
        removeRecipeCardFromLists(recipeID, "cookbook");
        recipeCard.remove();
      }
      if (recipeCards.length == 0) {
        setUpDivWithNoRecipes(USER_RECIPES_ID, NO_USER_RECIPES);
      }
    });
  }
}

// input is recipe id and type of list
// removes the recipe card from the DOM
function removeRecipeCardFromLists(id, type) {
  const recipeDivID = type + "-recipes";
  let recipeDiv = document.getElementById(recipeDivID);
  let recipeCards = recipeDiv.getElementsByClassName('recipe-card');

  for (let i = 0; i < recipeCards.length; i++) {
    let recipeCard = recipeCards[i];
    let recipeID = recipeCard.getElementsByClassName("recipe-id")[0];
    if (recipeID.innerText == id.innerText) {
      recipeCard.remove();
    }
  }

  if (recipeCards.length == 0) {
    setUpDivWithNoRecipes(recipeDivID, "You have not added any recipes to your " + type + " yet.");
  }
}

// tells the server to delete the recipe.
// input is a recipe js object
function deleteRecipe(recipe) {
  const params = new URLSearchParams();
  params.append("id", recipe.id);
  fetch("/delete-recipe", {method: "POST", body: params});
}

// adds edit functionality to the edit button in the recipe cards
function addEditFunctionality(recipes) {
  const editButtons = document.getElementsByClassName('fa-edit');
  const recipeCards = document.getElementsByClassName('recipe-card');
  // there are as many edit buttons as there are recipe cards
  for (let i = 0; i < editButtons.length; i++) {
    let recipe = recipes[i];
    let recipeCard = recipeCards[i];
    editButtons[i].addEventListener('click', () => {
      openModal("edit-recipe-modal");
      addExistingValuesToEditForm(recipe);
    });
  }
}

// adds values of stored recipe to edit recipe form
function addExistingValuesToEditForm(recipe) {
  document.getElementById("recipeID").value = recipe.id;
  document.getElementById("edit-name").value = recipe.name;
  document.getElementById("edit-description").value = recipe.description;
  // sets up tags
  if (recipe.tags.length > 0) {
    document.getElementById("edit-tags").value = recipe.tags[0];
    for (let i = 1; i < recipe.tags.length; i++) {
      document.getElementById("edit-tags").value += ", " + recipe.tags[i];
    }
  }
  // sets up ingredients
  if (recipe.ingredients.length > 0) {
    document.getElementById("edit-ingredients").value = recipe.ingredients[0];
    for (let i = 1; i < recipe.ingredients.length; i++) {
      document.getElementById("edit-ingredients").value += "\n" + recipe.ingredients[i];
    }
  }
  // sets up steps
  if (recipe.steps.length > 0) {
    document.getElementById("edit-steps").value = recipe.steps[0];
    for (let i = 1; i < recipe.steps.length; i++) {
      document.getElementById("edit-steps").value += "\n" + recipe.steps[i];
    }
  }
  // TODO: figure out image value (low priority)

  // sets the default to the current value
  if (recipe.published) {
    setOption("first", "public");
    setOption("second", "private");
  } else {
    setOption("first", "private");
    setOption("second", "public");
  }
}

function setOption(id, text) {
  document.getElementById(id).value = text;
  document.getElementById(id).innerText = text;
}

// opens the recipe form modal
function openModal(id) {
  document.getElementById(id).style.display = "block";
  // edit-recipe-modal doesn't have image functionality rn
  if (id == "new-recipe-modal") {
    fetchBlobstoreUrl(id);
  }
}

// takes in div id and message
// makes the recipes container bigger and gives it the message
// to use when there are no recipes in planner/cookbook/user-recipes
setUpDivWithNoRecipes = (divID, message) => {
  let recipesDiv = document.getElementById(divID);
  recipesDiv.innerText = message;
  recipesDiv.style.height = "80px";
}

// not quite sure what this does; something with blobs and images
function fetchBlobstoreUrl(id) {
  fetch('/blobstore-upload-url?divID='+id)
      .then((response) => {
        return response.text();
      })
      .then((imageUploadUrl) => {
        let form;
        if (id == "new-recipe-modal") {
          form = document.getElementById("new-recipe-form");
        } else if (id == "edit-recipe-modal") {
          form = document.getElementById("edit-recipe-form");
        } else {
          console.log("invalid modal id");
        }
        form.action = imageUploadUrl;
      });
}

// closes the recipe form modal
function closeModal(id) {
  document.getElementById(id).style.display = "none";
}
<|endoftext|>


<commit_before>'use strict';

// NOTE: ADVANCED_OPTIMIZATIONS mode.
//
// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using
// constructs incompatible with that mode.

/* global $interpolateMinErr: false */
/* global MessageFormatParser: false */
/* global stringify: false */

/**
 * @ngdoc service
 * @name $$messageFormat
 *
 * @description
 * Angular internal service to recognize MessageFormat extensions in interpolation expressions.
 * For more information, see:
 * https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit
 *
 * ## Example
 *
 * <example name="ngMessageFormat-example" module="msgFmtExample" deps="angular-message-format.min.js">
 * <file name="index.html">
 *

 *     <button ng-click="decreaseRecipients()" id="decreaseRecipients">decreaseRecipients</button>

 *     {{recipients.length, plural, offset:1
 *             =0    {{{sender.name}} gave no gifts (\#=#)}
 *             =1    {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)}
 *             one   {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)}
 *             other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)}
 *           }}
 *

 * </file>
 *
 * <file name="script.js">
 *   function Person(name, gender) {
 *     this.name = name;
 *     this.gender = gender;
 *   }
 *
 *   var alice   = new Person("Alice", "female"),
 *       bob     = new Person("Bob", "male"),
 *       charlie = new Person("Charlie", "male"),
 *       harry   = new Person("Harry Potter", "male");
 *
 *   angular.module('msgFmtExample', ['ngMessageFormat'])
 *     .controller('AppController', ['$scope', function($scope) {
 *         $scope.recipients = [alice, bob, charlie];
 *         $scope.sender = harry;
 *         $scope.decreaseRecipients = function() {
 *           --$scope.recipients.length;
 *         };
 *       }]);
 * </file>
 *
 * <file name="protractor.js" type="protractor">
 *   describe('MessageFormat plural', function() {
 *     it('should pluralize initial values', function() {
 *       var messageElem = element(by.binding('recipients.length')), decreaseRecipientsBtn = element(by.id('decreaseRecipients'));
 *       expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)');
 *       decreaseRecipientsBtn.click();
 *       expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)');
 *       decreaseRecipientsBtn.click();
 *       expect(messageElem.getText()).toEqual('Harry Potter gave one gift to Alice (#=0)');
 *       decreaseRecipientsBtn.click();
 *       expect(messageElem.getText()).toEqual('Harry Potter gave no gifts (#=-1)');
 *     });
 *   });
 * </file>
 * </example>
 */
var $$MessageFormatFactory = ['$parse', '$locale', '$sce', '$exceptionHandler', function $$messageFormat(
                   $parse,   $locale,   $sce,   $exceptionHandler) {

  function getStringifier(trustedContext, allOrNothing, text) {
    return function stringifier(value) {
      try {
        value = trustedContext ? $sce['getTrusted'](trustedContext, value) : $sce['valueOf'](value);
        return allOrNothing && (value === void 0) ? value : stringify(value);
      } catch (err) {
        $exceptionHandler($interpolateMinErr['interr'](text, err));
      }
    };
  }

  function interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
    var stringifier = getStringifier(trustedContext, allOrNothing, text);
    var parser = new MessageFormatParser(text, 0, $parse, $locale['pluralCat'], stringifier,
                                         mustHaveExpression, trustedContext, allOrNothing);
    parser.run(parser.ruleInterpolate);
    return parser.parsedFn;
  }

  return {
    'interpolate': interpolate
  };
}];

var $$interpolateDecorator = ['$$messageFormat', '$delegate', function $$interpolateDecorator($$messageFormat, $interpolate) {
  if ($interpolate['startSymbol']() !== "{{" || $interpolate['endSymbol']() !== "}}") {
    throw $interpolateMinErr('nochgmustache', 'angular-message-format.js currently does not allow you to use custom start and end symbols for interpolation.');
  }
  var interpolate = $$messageFormat['interpolate'];
  interpolate['startSymbol'] = $interpolate['startSymbol'];
  interpolate['endSymbol'] = $interpolate['endSymbol'];
  return interpolate;
}];

/**
 * @ngdoc module
 * @name ngMessageFormat
 * @packageName angular-message-format
 * @description
 */
var module = window['angular']['module']('ngMessageFormat', ['ng']);
module['factory']('$$messageFormat', $$MessageFormatFactory);
module['config'](['$provide', function($provide) {
  $provide['decorator']('$interpolate', $$interpolateDecorator);
}]);
<commit_msg>docs(ngMessageFormat): add more examples<commit_after>'use strict';

// NOTE: ADVANCED_OPTIMIZATIONS mode.
//
// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using
// constructs incompatible with that mode.

/* global $interpolateMinErr: false */
/* global MessageFormatParser: false */
/* global stringify: false */

/**
 * @ngdoc service
 * @name $$messageFormat
 *
 * @description
 * Angular internal service to recognize MessageFormat extensions in interpolation expressions.
 * For more information, see:
 * https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit
 *
 * @example
 * ## Gender
 *
 * This example uses the "select" keyword to specify the message based on gender.
 *
 * <example name="ngMessageFormat-example-gender" module="msgFmtExample" deps="angular-message-format.min.js">
 * <file name="index.html">
 *

 *    Select Recipient:

      <select ng-model="recipient" ng-options="person as person.name for person in recipients">
      </select>

{{recipient.gender, select,
                male {{{recipient.name}} unwrapped his gift. }
                female {{{recipient.name}} unwrapped her gift. }
                other {{{recipient.name}} unwrapped their gift. }
      }}

 *

 * </file>
 * <file name="script.js">
 *   function Person(name, gender) {
 *     this.name = name;
 *     this.gender = gender;
 *   }
 *
 *   var alice   = new Person("Alice", "female"),
 *       bob     = new Person("Bob", "male"),
 *       ashley = new Person("Ashley", "");
 *
 *   angular.module('msgFmtExample', ['ngMessageFormat'])
 *     .controller('AppController', ['$scope', function($scope) {
 *         $scope.recipients = [alice, bob, ashley];
 *         $scope.recipient = $scope.recipients[0];
 *       }]);
 * </file>
 * </example>
 *
 * @example
 * ## Plural
 *
 * This example shows how the "plural" keyword is used to account for a variable number of entities.
 * The "#" variable holds the current number and can be embedded in the message.
 *
 * Note that "=1" takes precedence over "one".
 *
 * The example also shows the "offset" keyword, which allows you to offset the value of the "#" variable.
 *
 * <example name="ngMessageFormat-example-plural" module="msgFmtExample" deps="angular-message-format.min.js">
 * <file name="index.html">
 *

      Select recipients:

      <select multiple size=5 ng-model="recipients" ng-options="person as person.name for person in people">
      </select>

 *
{{recipients.length, plural, offset:1
 *             =0    {{{sender.name}} gave no gifts (\#=#)}
 *             =1    {{{sender.name}} gave a gift to {{recipients[0].name}} (\#=#)}
 *             one   {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)}
 *             other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)}
 *           }}

 *

 * </file>
 *
 * <file name="script.js">
 *   function Person(name, gender) {
 *     this.name = name;
 *     this.gender = gender;
 *   }
 *
 *   var alice   = new Person("Alice", "female"),
 *       bob     = new Person("Bob", "male"),
 *       sarah     = new Person("Sarah", "female"),
 *       harry   = new Person("Harry Potter", "male"),
 *       ashley   = new Person("Ashley", "");
 *
 *   angular.module('msgFmtExample', ['ngMessageFormat'])
 *     .controller('AppController', ['$scope', function($scope) {
 *         $scope.people = [alice, bob, sarah, ashley];
 *         $scope.recipients = [alice, bob, sarah];
 *         $scope.sender = harry;
 *       }]);
 * </file>
 *
 * <file name="protractor.js" type="protractor">
 *   describe('MessageFormat plural', function() {
 *     function clickOptionCtrl(select, index) {
 *      element.all(by.css('select option')).then(function(arr) {
           browser.actions()
              .mouseMove(arr[index])
              .keyDown(protractor.Key.CONTROL)
              .click()
              .keyUp(protractor.Key.CONTROL)
              .perform();
        });
 *     }
 *
 *     it('should pluralize initial values', function() {
 *       var messageElem = element(by.binding('recipients.length')),
 *         select = element(by.css('select'));
 *
 *       expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)');
         clickOptionCtrl(select, 2);
 *       expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)');
         clickOptionCtrl(select, 1);
 *       expect(messageElem.getText()).toEqual('Harry Potter gave a gift to Alice (#=0)');
         clickOptionCtrl(select, 0);
 *       expect(messageElem.getText()).toEqual('Harry Potter gave no gifts (#=-1)');
 *     });
 *   });
 * </file>
 * </example>
 *
 * @example
 * ## Plural and Gender
 *
 * This example shows how you can specify gender rules for specific plural matches - in this case,
 * =1 is special cased for gender.
 * <example name="ngMessageFormat-example-plural-gender" module="msgFmtExample" deps="angular-message-format.min.js">
 *   <file name="index.html">
 *

       Select recipients:

       <select multiple size=5 ng-model="recipients" ng-options="person as person.name for person in people">
       </select>

{{recipients.length, plural,
          =0 {{{sender.name}} has not given any gifts to anyone.}
          =1 {  {{recipients[0].gender, select,
                 female { {{sender.name}} gave {{recipients[0].name}} her gift.}
                 male { {{sender.name}} gave {{recipients[0].name}} his gift.}
                 other { {{sender.name}} gave {{recipients[0].name}} their gift.}
                }}
              }
          other {{{sender.name}} gave {{recipients.length}} people gifts.}
          }}

      </file>
 *    <file name="script.js">
 *      function Person(name, gender) {
 *        this.name = name;
 *        this.gender = gender;
 *      }
 *
 *      var alice   = new Person("Alice", "female"),
 *          bob     = new Person("Bob", "male"),
 *          harry   = new Person("Harry Potter", "male"),
 *          ashley   = new Person("Ashley", "");
 *
 *      angular.module('msgFmtExample', ['ngMessageFormat'])
 *        .controller('AppController', ['$scope', function($scope) {
 *            $scope.people = [alice, bob, ashley];
 *            $scope.recipients = [alice];
 *            $scope.sender = harry;
 *          }]);
 *    </file>
    </example>
 */
var $$MessageFormatFactory = ['$parse', '$locale', '$sce', '$exceptionHandler', function $$messageFormat(
                   $parse,   $locale,   $sce,   $exceptionHandler) {

  function getStringifier(trustedContext, allOrNothing, text) {
    return function stringifier(value) {
      try {
        value = trustedContext ? $sce['getTrusted'](trustedContext, value) : $sce['valueOf'](value);
        return allOrNothing && (value === void 0) ? value : stringify(value);
      } catch (err) {
        $exceptionHandler($interpolateMinErr['interr'](text, err));
      }
    };
  }

  function interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
    var stringifier = getStringifier(trustedContext, allOrNothing, text);
    var parser = new MessageFormatParser(text, 0, $parse, $locale['pluralCat'], stringifier,
                                         mustHaveExpression, trustedContext, allOrNothing);
    parser.run(parser.ruleInterpolate);
    return parser.parsedFn;
  }

  return {
    'interpolate': interpolate
  };
}];

var $$interpolateDecorator = ['$$messageFormat', '$delegate', function $$interpolateDecorator($$messageFormat, $interpolate) {
  if ($interpolate['startSymbol']() !== "{{" || $interpolate['endSymbol']() !== "}}") {
    throw $interpolateMinErr('nochgmustache', 'angular-message-format.js currently does not allow you to use custom start and end symbols for interpolation.');
  }
  var interpolate = $$messageFormat['interpolate'];
  interpolate['startSymbol'] = $interpolate['startSymbol'];
  interpolate['endSymbol'] = $interpolate['endSymbol'];
  return interpolate;
}];

/**
 * @ngdoc module
 * @name ngMessageFormat
 * @packageName angular-message-format
 * @description
 */
var module = window['angular']['module']('ngMessageFormat', ['ng']);
module['factory']('$$messageFormat', $$MessageFormatFactory);
module['config'](['$provide', function($provide) {
  $provide['decorator']('$interpolate', $$interpolateDecorator);
}]);
<|endoftext|>


<commit_before>/* global TL */

const angular = require('angular');
const $ = require('jquery');
const union = require('lodash/union');

let deps = union(window.dependencies || [], [
  'ngAria',
  'ngAnimate',
  'ui.bootstrap',
  'irida.session',
  'irida.notifications',
  'irida.cart'
]);

const app = angular.module('irida', deps)
  .config(function($httpProvider) {
    $httpProvider.defaults.headers
      .post['Content-Type'] = 'application/x-www-form-urlencoded';

    // Make sure that all ajax form data is sent in the correct format.
    $httpProvider.defaults.transformRequest = function(data) {
      if (data === undefined) {
        return data;
      }
      return $.param(data);
    };
  })
  .run(function(uibPaginationConfig) {
    uibPaginationConfig.firstText = TL.lang.page.first;
    uibPaginationConfig.previousText = TL.lang.page.prev;
    uibPaginationConfig.nextText = TL.lang.page.next;
    uibPaginationConfig.lastText = TL.lang.page.last;
    uibPaginationConfig.boundaryLinks = true;
    uibPaginationConfig.directionLinks = true;
    uibPaginationConfig.maxSize = 8;
    uibPaginationConfig.rotate = false;
  });

export default app;
<commit_msg>Function cleanup<commit_after>/* global TL */

const angular = require('angular');
const $ = require('jquery');
const union = require('lodash/union');

let deps = union(window.dependencies || [], [
  'ngAria',
  'ngAnimate',
  'ui.bootstrap',
  'irida.session',
  'irida.notifications',
  'irida.cart'
]);

const app = angular.module('irida', deps)
  .config($httpProvider => {
    $httpProvider.defaults.headers
      .post['Content-Type'] = 'application/x-www-form-urlencoded';

    // Make sure that all ajax form data is sent in the correct format.
    $httpProvider.defaults.transformRequest = data => {
      if (data === undefined) {
        return data;
      }
      return $.param(data);
    };
  })
  .run(uibPaginationConfig => {
    uibPaginationConfig.firstText = TL.lang.page.first;
    uibPaginationConfig.previousText = TL.lang.page.prev;
    uibPaginationConfig.nextText = TL.lang.page.next;
    uibPaginationConfig.lastText = TL.lang.page.last;
    uibPaginationConfig.boundaryLinks = true;
    uibPaginationConfig.directionLinks = true;
    uibPaginationConfig.maxSize = 8;
    uibPaginationConfig.rotate = false;
  });

export default app;
<|endoftext|>


<commit_before>import React from 'react';
import Avatar from './avatar';
import TimeAgo from './time-ago';
import previewer from '../previewer';
import uriParser from '../uri-parser';

class Headline extends React.Component {
  render() {
    const { post } = this.props;
    const preview = previewer(post.body);
    const ts = Number(post.created);
    const commentCount = Number(post.commentcount);
    let commentCountText = 'Read More';
    if (commentCount === 1) {
      commentCountText = '1 Comment';
    } else if (commentCount > 1) {
      commentCountText = commentCount + ' Comments';
    }

    const link = (post.url) ? {uriParser(post.url).host} ↵ : null;

    return (

· · ·

{post.title}

          {link}

            <Avatar name={post.name} hex={post.color} />

              <TimeAgo timestamp={ts} />

{post.name}

{commentCountText}

    );
  }
}

Headline.propTypes = {
  post: React.PropTypes.shape({
    urlstring: React.PropTypes.string,
    title: React.PropTypes.string,
  }),
};

export default Headline;
<commit_msg>Real links<commit_after>import React from 'react';
import Avatar from './avatar';
import TimeAgo from './time-ago';
import previewer from '../previewer';
import uriParser from '../uri-parser';

class Headline extends React.Component {
  render() {
    const { post } = this.props;
    const preview = previewer(post.body);
    const ts = Number(post.created);
    const commentCount = Number(post.commentcount);
    let commentCountText = 'Read More';
    if (commentCount === 1) {
      commentCountText = '1 Comment';
    } else if (commentCount > 1) {
      commentCountText = commentCount + ' Comments';
    }

    const link = (post.url) ? uriParser(post.url).host : null;
    const postLink = '/p/' + post.urlstring;
    if (link) {
      return (

· · ·

{post.title}

              {link} ↵

              <Avatar name={post.name} hex={post.color} />

                <TimeAgo timestamp={ts} />

{post.name}

{commentCountText}

      );
    }
    return (

· · ·

{post.title}

            <Avatar name={post.name} hex={post.color} />

              <TimeAgo timestamp={ts} />

{post.name}

{commentCountText}

    );
  }
}

Headline.propTypes = {
  post: React.PropTypes.shape({
    urlstring: React.PropTypes.string,
    title: React.PropTypes.string,
  }),
};

export default Headline;
<|endoftext|>


<commit_before>var _ = require('lodash');
var assert = require('assert');
var async = require('async');
var Request = require('../lib/external-request');
var USER_HOST = process.env.USER_API || "https://user-api-example.com";
var avatar = require('../lib/avatar');
var P = require('bluebird');

var Org = module.exports = function(bearer) {
  assert(_.isString(bearer), "Must pass a bearer (loggedInUser) to Org agent");

  if (!(this instanceof Org)) {
    return new Org(bearer);
  }

  this.bearer = bearer;
};

Org.prototype.create = function(name, callback) {
  var url = USER_HOST + '/org';

  var opts = {
    url: url,
    json: true,
    body: {
      name: name
    },
    headers: {
      bearer: this.bearer
    },
  };

  return new P(function(accept, reject) {
    Request.put(opts, function(err, resp, body) {
      if (err) {
        return reject(err);
      }

      if (resp.statusCode === 401) {
        err = Error('no bearer token included in creation of ' + name);
        err.statusCode = resp.statusCode;
        return reject(err);
      }

      if (resp.statusCode >= 400) {
        err = new Error(body);
        err.statusCode = resp.statusCode;
        return reject(err);
      }

      return accept(body);
    });
  }).nodeify(callback);
};

Org.prototype.get = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var self = this;
  var orgUrl = USER_HOST + '/org/' + name;
  var userUrl = USER_HOST + '/org/' + name + '/user';
  var packageUrl = USER_HOST + '/org/' + name + '/package';

  var makeRequest = function(url) {
    return new P(function(accept, reject) {

      Request({
        url: url,
        json: true,
        headers: {
          bearer: self.bearer
        }
      }, function(err, resp, body) {
        if (err) {
          return reject(err);
        }

        if (resp.statusCode >= 400) {
          err = new Error(body);
          err.statusCode = resp.statusCode;
          return reject(err);
        }

        return accept(body);
      });
    });
  };

  var requests = [
    makeRequest(orgUrl),
    makeRequest(userUrl),
    makeRequest(packageUrl)
  ];

  return P.all(requests).spread(function(org, users, pkg) {
    var ret = {};

    ret.info = org;
    ret.users = users;
    ret.users.items = users.items.map(function(user) {
      user.avatar = avatar(user.email);
      return user;
    });
    ret.packages = pkg;

    return ret;
  }).nodeify(callback);
};

Org.prototype.update = function(data, callback) {
  var url = USER_HOST + '/org/' + data.name;

  // shall we use joi to ensure the data is legit?

  var opts = {
    url: url,
    json: true,
    body: data,
    headers: {
      bearer: this.bearer
    }
  };

  Request.post(opts, function(err, resp, body) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('user is unauthorized to modify this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, body);
  });
};

Org.prototype.delete = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var url = USER_HOST + '/org/' + name;

  Request.del({
    url: url,
    json: true,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, body) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('user is unauthorized to delete this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, body);
  });
};

Org.prototype.addUser = function(name, user, callback) {
  assert(_.isString(name), "name must be a string");
  assert(_.isObject(user), "must pass a user");

  var url = USER_HOST + '/org/' + name + '/user';

  Request.put({
    url: url,
    json: true,
    body: user,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, user) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('bearer is unauthorized to add this user to this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org or user not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, user);
  });
};

Org.prototype.getUsers = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var url = USER_HOST + '/org/' + name + '/user';

  Request.get({
    url: url,
    json: true,
    headers: {
      bearer: this.bearer
    },
  }, function(err, resp, users) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, users);
  });
};

Org.prototype.getTeams = function(name, callback) {
  var url = USER_HOST + '/org/' + name + '/team';

  Request.get({
    url: url,
    json: true,
    id: name,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, teams) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, teams);
  });

};

Org.prototype.removeUser = function(name, userId, callback) {
  var url = USER_HOST + '/org/' + name + '/user/' + userId;

  Request.del({
    url: url,
    json: true,
    id: name,
    userId: userId,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, removedUser) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org or user not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, removedUser);
  });
};<commit_msg>little cleanup<commit_after>var _ = require('lodash');
var assert = require('assert');
var Request = require('../lib/external-request');
var USER_HOST = process.env.USER_API || "https://user-api-example.com";
var avatar = require('../lib/avatar');
var P = require('bluebird');

var Org = module.exports = function(bearer) {
  assert(_.isString(bearer), "Must pass a bearer (loggedInUser) to Org agent");

  if (!(this instanceof Org)) {
    return new Org(bearer);
  }

  this.bearer = bearer;
};

Org.prototype.create = function(name, callback) {
  var url = USER_HOST + '/org';

  var opts = {
    url: url,
    json: true,
    body: {
      name: name
    },
    headers: {
      bearer: this.bearer
    },
  };

  return new P(function(accept, reject) {
    Request.put(opts, function(err, resp, body) {
      if (err) {
        return reject(err);
      }

      if (resp.statusCode === 401) {
        err = Error('no bearer token included in creation of ' + name);
        err.statusCode = resp.statusCode;
        return reject(err);
      }

      if (resp.statusCode >= 400) {
        err = new Error(body);
        err.statusCode = resp.statusCode;
        return reject(err);
      }

      return accept(body);
    });
  }).nodeify(callback);
};

Org.prototype.get = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var self = this;
  var orgUrl = USER_HOST + '/org/' + name;
  var userUrl = USER_HOST + '/org/' + name + '/user';
  var packageUrl = USER_HOST + '/org/' + name + '/package';

  var makeRequest = function(url) {
    return new P(function(accept, reject) {

      Request({
        url: url,
        json: true,
        headers: {
          bearer: self.bearer
        }
      }, function(err, resp, body) {
        if (err) {
          return reject(err);
        }

        if (resp.statusCode >= 400) {
          err = new Error(body);
          err.statusCode = resp.statusCode;
          return reject(err);
        }

        return accept(body);
      });
    });
  };

  var requests = [
    makeRequest(orgUrl),
    makeRequest(userUrl),
    makeRequest(packageUrl)
  ];

  return P.all(requests).spread(function(org, users, pkg) {
    var ret = {};

    ret.info = org;
    ret.users = users;
    ret.users.items = users.items.map(function(user) {
      user.avatar = avatar(user.email);
      return user;
    });
    ret.packages = pkg;

    return ret;
  }).nodeify(callback);
};

Org.prototype.update = function(data, callback) {
  var url = USER_HOST + '/org/' + data.name;

  // shall we use joi to ensure the data is legit?

  var opts = {
    url: url,
    json: true,
    body: data,
    headers: {
      bearer: this.bearer
    }
  };

  Request.post(opts, function(err, resp, body) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('user is unauthorized to modify this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, body);
  });
};

Org.prototype.delete = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var url = USER_HOST + '/org/' + name;

  Request.del({
    url: url,
    json: true,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, body) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('user is unauthorized to delete this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, body);
  });
};

Org.prototype.addUser = function(name, user, callback) {
  assert(_.isString(name), "name must be a string");
  assert(_.isObject(user), "must pass a user");

  var url = USER_HOST + '/org/' + name + '/user';

  Request.put({
    url: url,
    json: true,
    body: user,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, user) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 401) {
      err = Error('bearer is unauthorized to add this user to this organization');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org or user not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, user);
  });
};

Org.prototype.getUsers = function(name, callback) {
  assert(_.isString(name), "name must be a string");

  var url = USER_HOST + '/org/' + name + '/user';

  Request.get({
    url: url,
    json: true,
    headers: {
      bearer: this.bearer
    },
  }, function(err, resp, users) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, users);
  });
};

Org.prototype.getTeams = function(name, callback) {
  var url = USER_HOST + '/org/' + name + '/team';

  Request.get({
    url: url,
    json: true,
    id: name,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, teams) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, teams);
  });

};

Org.prototype.removeUser = function(name, userId, callback) {
  var url = USER_HOST + '/org/' + name + '/user/' + userId;

  Request.del({
    url: url,
    json: true,
    id: name,
    userId: userId,
    headers: {
      bearer: this.bearer
    }
  }, function(err, resp, removedUser) {
    if (err) {
      callback(err);
    }

    if (resp.statusCode === 404) {
      err = Error('org or user not found');
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    if (resp.statusCode >= 400) {
      err = new Error(body);
      err.statusCode = resp.statusCode;
      return callback(err);
    }

    return callback(null, removedUser);
  });
};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
class PostNew extends Component {
    // {...field.input} is used to wireup the event handllers to the input its a short hand for onChange=field.input.onChange so on..
    renderTitleField(field){
        return (

                Title
                <input
                    className="form-control"
                    type="text"
                    {...field.input}
                />

        );
    }
    // The field attribute doesn't know how to render UI for the element it only checks the under the hood functionalities
    // It calls a function that contains a JSX blob to render the UI(this function is automically called so we dont hav eto call it explicitly)
    render() {
        return (
            <form>
                <Field
                    name="title"
                    component={this.renderTitleField}
                />
            </form>
        );
    }
}

export default reduxForm({
    // Unique name for our form
    form: 'PostNewForm'
})(PostNew);<commit_msg>Generalized renderField method<commit_after>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
class PostNew extends Component {
    // {...field.input} is used to wireup the event handllers to the input its a short hand for onChange=field.input.onChange so on..
    renderField(field){
        return (

                {field.label}
                <input
                    className="form-control"
                    type="text"
                    {...field.input}
                />

        );
    }
    // The field attribute doesn't know how to render UI for the element it only checks the under the hood functionalities
    // It calls a function that contains a JSX blob to render the UI(this function is automically called so we dont hav eto call it explicitly)
    render() {
        return (
            <form>
                <Field
                    label="Title"
                    name="title"
                    component={this.renderField}
                />
                <Field
                    label="Categories"
                    name="tag"
                    component={this.renderField}
                />
                <Field
                    label="Post Content"
                    name="content"
                    component={this.renderField}
                />
            </form>
        );
    }
}

export default reduxForm({
    // Unique name for our form
    form: 'PostNewForm'
})(PostNew);<|endoftext|>


<commit_before>async function resolveFactory (map, context, args, factory, pathDelimiter) {
  let instance;

  if (args instanceof Array && factory instanceof Function) {
    const resolvedArgs = [];

    for (let i = 0; i < args.length; i++) {
      const argItem = args[i];

      if (typeof argItem === 'string') {
        resolvedArgs.push(incarnate(argItem, map, context, pathDelimiter));
      } else if (argItem instanceof Function) {
        resolvedArgs.push(argItem(context));
      }
    }

    instance = factory.apply(
      null,
      await Promise.all(resolvedArgs)
    );
  }

  return instance;
}

async function incarnate (path, map, context, pathDelimiter = '.') {
  const delimiter = typeof pathDelimiter === 'string' ? pathDelimiter : '.';

  let instance;

  if (typeof path === 'string' && map instanceof Object) {
    const pathParts = path.split(delimiter);
    // TRICKY: Use `shift` to remove the current path part.
    const subMapResolver = map[pathParts.shift()];
    const def = map[path];

    if (
      pathParts.length &&
      pathParts.indexOf('') === -1 &&
      subMapResolver instanceof Function
    ) {
      if (subMapResolver instanceof Function) {
        const subPath = pathParts.join(delimiter);
        const subMap = await subMapResolver(context, subPath);

        return incarnate(
          subPath,
          subMap,
          context,
          pathDelimiter
        );
      }
    } else if (def instanceof Object) {
      const args = def.args;
      const factory = def.factory;

      instance = resolveFactory(map, context, args, factory, pathDelimiter);
    }
  }

  return instance;
}

export default incarnate;
<commit_msg>ref(incarnate) Remove an early return.<commit_after>async function resolveFactory (map, context, args, factory, pathDelimiter) {
  let instance;

  if (args instanceof Array && factory instanceof Function) {
    const resolvedArgs = [];

    for (let i = 0; i < args.length; i++) {
      const argItem = args[i];

      if (typeof argItem === 'string') {
        resolvedArgs.push(incarnate(argItem, map, context, pathDelimiter));
      } else if (argItem instanceof Function) {
        resolvedArgs.push(argItem(context));
      }
    }

    instance = factory.apply(
      null,
      await Promise.all(resolvedArgs)
    );
  }

  return instance;
}

async function incarnate (path, map, context, pathDelimiter = '.') {
  const delimiter = typeof pathDelimiter === 'string' ? pathDelimiter : '.';

  let instance;

  if (typeof path === 'string' && map instanceof Object) {
    const pathParts = path.split(delimiter);
    // TRICKY: Use `shift` to remove the current path part.
    const subMapResolver = map[pathParts.shift()];
    const def = map[path];

    if (
      pathParts.length &&
      pathParts.indexOf('') === -1 &&
      subMapResolver instanceof Function
    ) {
      if (subMapResolver instanceof Function) {
        const subPath = pathParts.join(delimiter);
        const subMap = await subMapResolver(context, subPath);

        instance = incarnate(
          subPath,
          subMap,
          context,
          pathDelimiter
        );
      }
    } else if (def instanceof Object) {
      const args = def.args;
      const factory = def.factory;

      instance = resolveFactory(map, context, args, factory, pathDelimiter);
    }
  }

  return instance;
}

export default incarnate;
<|endoftext|>