<commit_before>const React = require('react');
const ReactDOM = require('react-dom');
const moment = require('moment');

const {
  DonutChart,
  Icon,
  Loader,
  Modal,
  RangeSelector,
  Select,
  TimeBasedLineChart,
  ToggleSwitch,
  TypeAhead
} = require('../src/Index');

const styles = {
  block: {
    boxSizing: 'border-box',
    float: 'left',
    width: '20%',
    fontFamily: 'Helvetica, Arial, sans-serif',
    fontSize: '13px',
    color: '#666666',
    textAlign: 'center',
    borderRight: '1px solid #e5e5e5',
    borderBottom: '1px solid #e5e5e5',
    borderLeft: '1px solid #e5e5e5',
    padding: '30px 0',
    marginRight: '-1px'
  },
  type: {
    backgroundColor: '#f5f5f5',
    border: '1px solid #e5e5e5',
    borderRadius: '2px',
    display: 'inline-block',
    margin: '5px 0',
    padding: '3px 5px'
  },
  button: {
    borderRadius: '3px',
    background: '#359BCF',
    padding: '10px 20px',
    display: 'inline-block',
    margin: '0 5px',
    color: '#fff',
    cursor: 'pointer',
    fontSize: '14px',
    WebkitFontSmoothing: 'antialiased'
  }
};

const icons = [
  {
    value: 'accounts',
    displayValue: 'Accounts'
  },
  {
    value: 'add',
    displayValue: 'Add'
  },
  {
    value: 'add-solid',
    displayValue: 'Add Solid'
  },
  {
    value: 'arrow-down',
    displayValue: 'Arrow Down'
  },
  {
    value: 'arrow-left',
    displayValue: 'Arrow Left'
  },
  {
    value: 'arrow-right',
    displayValue: 'Arrow Right'
  },
  {
    value: 'arrow-up',
    displayValue: 'Arrow Up'
  },
  {
    value: 'attention',
    displayValue: 'Attention'
  },
  {
    value: 'auto',
    displayValue: 'Auto'
  },
  {
    value: 'backspace',
    displayValue: 'Backspace'
  },
  {
    value: 'campaigns',
    displayValue: 'Campaigns'
  },
  {
    value: 'caret-down',
    displayValue: 'Caret Down'
  },
  {
    value: 'caret-left',
    displayValue: 'Caret Left'
  },
  {
    value: 'caret-right',
    displayValue: 'Caret Right'
  },
  {
    value: 'caret-up',
    displayValue: 'Caret Up'
  },
  {
    value: 'check',
    displayValue: 'Check'
  },
  {
    value: 'check-solid',
    displayValue: 'Check Solid'
  },
  {
    value: 'checking',
    displayValue: 'Checking'
  },
  {
    value: 'close',
    displayValue: 'Close'
  },
  {
    value: 'close-solid',
    displayValue: 'Close Solid'
  },
  {
    value: 'comparisons',
    displayValue: 'Comparisons'
  },
  {
    value: 'credit-card',
    displayValue: 'Credit Card'
  },
  {
    value: 'delete',
    displayValue: 'Delete'
  },
  {
    value: 'download',
    displayValue: 'Download'
  },
  {
    value: 'edit',
    displayValue: 'Edit'
  },
  {
    value: 'envelope',
    displayValue: 'Envelope'
  },
  {
    value: 'export',
    displayValue: 'Export'
  },
  {
    value: 'folder',
    displayValue: 'Folder'
  },
  {
    value: 'gallery',
    displayValue: 'Gallery'
  },
  {
    value: 'gear',
    displayValue: 'Gear'
  },
  {
    value: 'hamburger',
    displayValue: 'Hamburger'
  },
  {
    value: 'help',
    displayValue: 'Help'
  },
  {
    value: 'home',
    displayValue: 'Home'
  },
  {
    value: 'info',
    displayValue: 'Info'
  },
  {
    value: 'list-view',
    displayValue: 'List View'
  },
  {
    value: 'loans',
    displayValue: 'Loans'
  },
  {
    value: 'md-cash',
    displayValue: 'Cash (MD)'
  },
  {
    value: 'md-check-mark',
    displayValue: 'Check Mark (MD)'
  },
  {
    value: 'md-credit',
    displayValue: 'Creidt (MD)'
  },
  {
    value: 'md-debts',
    displayValue: 'Debts (MD)'
  },
  {
    value: 'md-savings',
    displayValue: 'Savings (MD)'
  },
  {
    value: 'mobile-phone',
    displayValue: 'Mobile Phone'
  },
  {
    value: 'mx',
    displayValue: 'MX'
  },
  {
    value: 'phone',
    displayValue: 'Phone'
  },
  {
    value: 'play',
    displayValue: 'Play'
  },
  {
    value: 'play-solid',
    displayValue: 'Play Solid'
  },
  {
    value: 'savings',
    displayValue: 'Savings'
  },
  {
    value: 'search',
    displayValue: 'Search'
  },
  {
    value: 'segments',
    displayValue: 'Segments'
  },
  {
    value: 'sync',
    displayValue: 'Sync'
  },
  {
    value: 'transactions',
    displayValue: 'Transactions'
  },
  {
    value: 'user',
    displayValue: 'User'
  },
  {
    value: 'view',
    displayValue: 'View'
  },
  {
    value: 'visit',
    displayValue: 'Visit'
  },
  {
    value: 'x-axis',
    displayValue: 'X Axis'
  },
  {
    value: 'y-axis',
    displayValue: 'Y Axis'
  }
];

const Demo = React.createClass({
  getInitialState () {
    return {
      icon: {
        value: 'accounts',
        displayValue: 'Accounts'
      },
      showModal: false,
      showSmallModal: false,
      windowWidth: document.documentElement.clientWidth || document.body.clientWidth
    }
  },

  componentDidMount () {
    window.addEventListener('resize', this._handleWindowResize);
  },

  componentWillUnmount () {
    window.removeEventListener('resize', this._handleWindowResize);
  },

  _handleSelectChange (option) {
    this.setState({
      icon: option
    });
  },

  _handleWindowResize () {
    this.setState({
      windowWidth: document.documentElement.clientWidth || document.body.clientWidth
    });
  },

  render () {
    return (

          Show Default Modal
          Show Small Modal

        <Modal
          isOpen={this.state.showModal}
          isSmall={this.state.showSmallModal}
          onRequestClose={this._handleModalClose}
        >

I am a modal!

        </Modal>

        <DonutChart
          animateOnHover={true}
          chartTotal={300}
          data={[
            {
              name: 'Data Point 1',
              value: 50
            },
            {
              name: 'Data Point 2',
              value: 80
            }
          ]}
          dataPoints={[
            {
              name: 'Data Dot 1',
              value: 200
            }
          ]}
          defaultLabelText='Total Users'
          defaultLabelValue='300'
          style={{ margin: '0 auto' }}
        />

        <TimeBasedLineChart
          breakPointDate={moment().startOf('day').unix()}
          breakPointLabel='Today'
          data={[
            {
              timeStamp: moment().subtract(15, 'days').unix(),
              value: 2000
            },
            {
              timeStamp: moment().subtract(14, 'days').unix(),
              value: 1900
            },
            {
              timeStamp: moment().subtract(13, 'days').unix(),
              value: 1850
            },
            {
              timeStamp: moment().subtract(12, 'days').unix(),
              value: 1550
            },
            {
              timeStamp: moment().subtract(11, 'days').unix(),
              value: 1500
            },
            {
              timeStamp: moment().subtract(10, 'days').unix(),
              value: 1000
            },
            {
              timeStamp: moment().subtract(9, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(8, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(7, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(6, 'days').unix(),
              value: 800
            },
            {
              timeStamp: moment().subtract(5, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(4, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(3, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(2, 'days').unix(),
              value: 1600
            },
            {
              timeStamp: moment().subtract(1, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().unix(),
              value: 1400
            },
            {
              timeStamp: moment().add(1, 'days').unix(),
              value: 1200
            },
            {
              timeStamp: moment().add(2, 'days').unix(),
              value: 1200
            },
            {
              timeStamp: moment().add(3, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(4, 'days').unix(),
              value: 1100
            },
            {
              timeStamp: moment().add(5, 'days').unix(),
              value: 1000
            },
            {
              timeStamp: moment().add(6, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().add(7, 'days').unix(),
              value: 500
            },
            {
              timeStamp: moment().add(8, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(9, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(10, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(11, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(12, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(13, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(14, 'days').unix(),
              value: 1300
            },
            {
              timeStamp: moment().add(15, 'days').unix(),
              value: 900
            },
          ]}
          height={400}
          hoverCallBack={this._handleLineChartHover}
          margin={{ top: 30, right: 50, bottom: 20, left: 50 }}
          shadeAreaBelowZero={true}
          width={700}
        >

            {'$' + this.state.lineChartHoverValue}

        </TimeBasedLineChart>

        <ToggleSwitch />

        <TypeAhead
          items={[
            'JPMorgan Chase',
            'Bank of America',
            'Citigroup',
            'Wells Fargo',
            'The Bank of New York Mellon',
            'U.S. Bancorp',
            'HSBC Bank USA',
            'Capital One',
            'PNC Financial Services',
            'State Street Corporation'
          ]}
          placeholderText='Select a Bank'
        />

        <Select
          isMobile={false}
          onChange={this._handleSelectChange}
          options={icons}
          optionStyle={{
            color: '#333'
          }}
          optionHoverStyle={{
            backgroundColor: '#359BCF',
            color: '#fff'
          }}
          placeholderText='Pick One'
          selected={this.state.icon}
          valid={true}
        />

          <Icon
            type={this.state.icon.value}
            size={150}
            style={{
              color: '#359BCF'
            }}
          />

        <RangeSelector
          defaultLowerValue={18}
          defaultUpperValue={30}
          interval={1}
          presets={[
            {
              lowerValue: 0,
              upperValue: 13,
              label: 'Gen Z'
            },
            {
              lowerValue: 14,
              upperValue: 34,
              label: 'Millenials'
            },
            {
              lowerValue: 10,
              upperValue: 40,
              label: 'Gen Y'
            },
            {
              lowerValue: 36,
              upperValue: 50,
              label: 'Gen X'
            },
            {
              lowerValue: 51,
              upperValue: 72,
              label: 'Baby Boomers'
            },
            {
              lowerValue: 73,
              upperValue: 90,
              label: 'Silent'
            }
          ]}
          range={100}
          selectedColor='#359BCF'
        />

          <Loader isLoading={true} isRelative={true} />

    );
  },

  _handleLineChartHover (data) {
    this.setState({
      lineChartHoverValue: data.value
    });
  },

  _handleSelectChange (option) {
    this.setState({
      icon: option
    });
  },

  _handleModalClick () {
    this.setState({
      showModal: true,
      showSmallModal: false
    });
  },

  _handleSmallModalClick () {
    this.setState({
      showModal: true,
      showSmallModal: true
    });
  },

  _handleModalClose () {
    this.setState({
      showModal: false,
      showSmallModal: false
    });
  }
});

ReactDOM.render(<Demo />, document.getElementById('demo'));<commit_msg>remove money symbol form tool tip<commit_after>const React = require('react');
const ReactDOM = require('react-dom');
const moment = require('moment');

const {
  DonutChart,
  Icon,
  Loader,
  Modal,
  RangeSelector,
  Select,
  TimeBasedLineChart,
  ToggleSwitch,
  TypeAhead
} = require('../src/Index');

const styles = {
  block: {
    boxSizing: 'border-box',
    float: 'left',
    width: '20%',
    fontFamily: 'Helvetica, Arial, sans-serif',
    fontSize: '13px',
    color: '#666666',
    textAlign: 'center',
    borderRight: '1px solid #e5e5e5',
    borderBottom: '1px solid #e5e5e5',
    borderLeft: '1px solid #e5e5e5',
    padding: '30px 0',
    marginRight: '-1px'
  },
  type: {
    backgroundColor: '#f5f5f5',
    border: '1px solid #e5e5e5',
    borderRadius: '2px',
    display: 'inline-block',
    margin: '5px 0',
    padding: '3px 5px'
  },
  button: {
    borderRadius: '3px',
    background: '#359BCF',
    padding: '10px 20px',
    display: 'inline-block',
    margin: '0 5px',
    color: '#fff',
    cursor: 'pointer',
    fontSize: '14px',
    WebkitFontSmoothing: 'antialiased'
  }
};

const icons = [
  {
    value: 'accounts',
    displayValue: 'Accounts'
  },
  {
    value: 'add',
    displayValue: 'Add'
  },
  {
    value: 'add-solid',
    displayValue: 'Add Solid'
  },
  {
    value: 'arrow-down',
    displayValue: 'Arrow Down'
  },
  {
    value: 'arrow-left',
    displayValue: 'Arrow Left'
  },
  {
    value: 'arrow-right',
    displayValue: 'Arrow Right'
  },
  {
    value: 'arrow-up',
    displayValue: 'Arrow Up'
  },
  {
    value: 'attention',
    displayValue: 'Attention'
  },
  {
    value: 'auto',
    displayValue: 'Auto'
  },
  {
    value: 'backspace',
    displayValue: 'Backspace'
  },
  {
    value: 'campaigns',
    displayValue: 'Campaigns'
  },
  {
    value: 'caret-down',
    displayValue: 'Caret Down'
  },
  {
    value: 'caret-left',
    displayValue: 'Caret Left'
  },
  {
    value: 'caret-right',
    displayValue: 'Caret Right'
  },
  {
    value: 'caret-up',
    displayValue: 'Caret Up'
  },
  {
    value: 'check',
    displayValue: 'Check'
  },
  {
    value: 'check-solid',
    displayValue: 'Check Solid'
  },
  {
    value: 'checking',
    displayValue: 'Checking'
  },
  {
    value: 'close',
    displayValue: 'Close'
  },
  {
    value: 'close-solid',
    displayValue: 'Close Solid'
  },
  {
    value: 'comparisons',
    displayValue: 'Comparisons'
  },
  {
    value: 'credit-card',
    displayValue: 'Credit Card'
  },
  {
    value: 'delete',
    displayValue: 'Delete'
  },
  {
    value: 'download',
    displayValue: 'Download'
  },
  {
    value: 'edit',
    displayValue: 'Edit'
  },
  {
    value: 'envelope',
    displayValue: 'Envelope'
  },
  {
    value: 'export',
    displayValue: 'Export'
  },
  {
    value: 'folder',
    displayValue: 'Folder'
  },
  {
    value: 'gallery',
    displayValue: 'Gallery'
  },
  {
    value: 'gear',
    displayValue: 'Gear'
  },
  {
    value: 'hamburger',
    displayValue: 'Hamburger'
  },
  {
    value: 'help',
    displayValue: 'Help'
  },
  {
    value: 'home',
    displayValue: 'Home'
  },
  {
    value: 'info',
    displayValue: 'Info'
  },
  {
    value: 'list-view',
    displayValue: 'List View'
  },
  {
    value: 'loans',
    displayValue: 'Loans'
  },
  {
    value: 'md-cash',
    displayValue: 'Cash (MD)'
  },
  {
    value: 'md-check-mark',
    displayValue: 'Check Mark (MD)'
  },
  {
    value: 'md-credit',
    displayValue: 'Creidt (MD)'
  },
  {
    value: 'md-debts',
    displayValue: 'Debts (MD)'
  },
  {
    value: 'md-savings',
    displayValue: 'Savings (MD)'
  },
  {
    value: 'mobile-phone',
    displayValue: 'Mobile Phone'
  },
  {
    value: 'mx',
    displayValue: 'MX'
  },
  {
    value: 'phone',
    displayValue: 'Phone'
  },
  {
    value: 'play',
    displayValue: 'Play'
  },
  {
    value: 'play-solid',
    displayValue: 'Play Solid'
  },
  {
    value: 'savings',
    displayValue: 'Savings'
  },
  {
    value: 'search',
    displayValue: 'Search'
  },
  {
    value: 'segments',
    displayValue: 'Segments'
  },
  {
    value: 'sync',
    displayValue: 'Sync'
  },
  {
    value: 'transactions',
    displayValue: 'Transactions'
  },
  {
    value: 'user',
    displayValue: 'User'
  },
  {
    value: 'view',
    displayValue: 'View'
  },
  {
    value: 'visit',
    displayValue: 'Visit'
  },
  {
    value: 'x-axis',
    displayValue: 'X Axis'
  },
  {
    value: 'y-axis',
    displayValue: 'Y Axis'
  }
];

const Demo = React.createClass({
  getInitialState () {
    return {
      icon: {
        value: 'accounts',
        displayValue: 'Accounts'
      },
      showModal: false,
      showSmallModal: false,
      windowWidth: document.documentElement.clientWidth || document.body.clientWidth
    }
  },

  componentDidMount () {
    window.addEventListener('resize', this._handleWindowResize);
  },

  componentWillUnmount () {
    window.removeEventListener('resize', this._handleWindowResize);
  },

  _handleSelectChange (option) {
    this.setState({
      icon: option
    });
  },

  _handleWindowResize () {
    this.setState({
      windowWidth: document.documentElement.clientWidth || document.body.clientWidth
    });
  },

  render () {
    return (

          Show Default Modal
          Show Small Modal

        <Modal
          isOpen={this.state.showModal}
          isSmall={this.state.showSmallModal}
          onRequestClose={this._handleModalClose}
        >

I am a modal!

        </Modal>

        <DonutChart
          animateOnHover={true}
          chartTotal={300}
          data={[
            {
              name: 'Data Point 1',
              value: 50
            },
            {
              name: 'Data Point 2',
              value: 80
            }
          ]}
          dataPoints={[
            {
              name: 'Data Dot 1',
              value: 200
            }
          ]}
          defaultLabelText='Total Users'
          defaultLabelValue='300'
          style={{ margin: '0 auto' }}
        />

        <TimeBasedLineChart
          breakPointDate={moment().startOf('day').unix()}
          breakPointLabel='Today'
          data={[
            {
              timeStamp: moment().subtract(15, 'days').unix(),
              value: 2000
            },
            {
              timeStamp: moment().subtract(14, 'days').unix(),
              value: 1900
            },
            {
              timeStamp: moment().subtract(13, 'days').unix(),
              value: 1850
            },
            {
              timeStamp: moment().subtract(12, 'days').unix(),
              value: 1550
            },
            {
              timeStamp: moment().subtract(11, 'days').unix(),
              value: 1500
            },
            {
              timeStamp: moment().subtract(10, 'days').unix(),
              value: 1000
            },
            {
              timeStamp: moment().subtract(9, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(8, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(7, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().subtract(6, 'days').unix(),
              value: 800
            },
            {
              timeStamp: moment().subtract(5, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(4, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(3, 'days').unix(),
              value: 600
            },
            {
              timeStamp: moment().subtract(2, 'days').unix(),
              value: 1600
            },
            {
              timeStamp: moment().subtract(1, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().unix(),
              value: 1400
            },
            {
              timeStamp: moment().add(1, 'days').unix(),
              value: 1200
            },
            {
              timeStamp: moment().add(2, 'days').unix(),
              value: 1200
            },
            {
              timeStamp: moment().add(3, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(4, 'days').unix(),
              value: 1100
            },
            {
              timeStamp: moment().add(5, 'days').unix(),
              value: 1000
            },
            {
              timeStamp: moment().add(6, 'days').unix(),
              value: 900
            },
            {
              timeStamp: moment().add(7, 'days').unix(),
              value: 500
            },
            {
              timeStamp: moment().add(8, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(9, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(10, 'days').unix(),
              value: 300
            },
            {
              timeStamp: moment().add(11, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(12, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(13, 'days').unix(),
              value: 1700
            },
            {
              timeStamp: moment().add(14, 'days').unix(),
              value: 1300
            },
            {
              timeStamp: moment().add(15, 'days').unix(),
              value: 900
            },
          ]}
          height={400}
          hoverCallBack={this._handleLineChartHover}
          margin={{ top: 30, right: 50, bottom: 20, left: 50 }}
          shadeAreaBelowZero={true}
          width={700}
        >

            {this.state.lineChartHoverValue}

        </TimeBasedLineChart>

        <ToggleSwitch />

        <TypeAhead
          items={[
            'JPMorgan Chase',
            'Bank of America',
            'Citigroup',
            'Wells Fargo',
            'The Bank of New York Mellon',
            'U.S. Bancorp',
            'HSBC Bank USA',
            'Capital One',
            'PNC Financial Services',
            'State Street Corporation'
          ]}
          placeholderText='Select a Bank'
        />

        <Select
          isMobile={false}
          onChange={this._handleSelectChange}
          options={icons}
          optionStyle={{
            color: '#333'
          }}
          optionHoverStyle={{
            backgroundColor: '#359BCF',
            color: '#fff'
          }}
          placeholderText='Pick One'
          selected={this.state.icon}
          valid={true}
        />

          <Icon
            type={this.state.icon.value}
            size={150}
            style={{
              color: '#359BCF'
            }}
          />

        <RangeSelector
          defaultLowerValue={18}
          defaultUpperValue={30}
          interval={1}
          presets={[
            {
              lowerValue: 0,
              upperValue: 13,
              label: 'Gen Z'
            },
            {
              lowerValue: 14,
              upperValue: 34,
              label: 'Millenials'
            },
            {
              lowerValue: 10,
              upperValue: 40,
              label: 'Gen Y'
            },
            {
              lowerValue: 36,
              upperValue: 50,
              label: 'Gen X'
            },
            {
              lowerValue: 51,
              upperValue: 72,
              label: 'Baby Boomers'
            },
            {
              lowerValue: 73,
              upperValue: 90,
              label: 'Silent'
            }
          ]}
          range={100}
          selectedColor='#359BCF'
        />

          <Loader isLoading={true} isRelative={true} />

    );
  },

  _handleLineChartHover (data) {
    this.setState({
      lineChartHoverValue: data.value
    });
  },

  _handleSelectChange (option) {
    this.setState({
      icon: option
    });
  },

  _handleModalClick () {
    this.setState({
      showModal: true,
      showSmallModal: false
    });
  },

  _handleSmallModalClick () {
    this.setState({
      showModal: true,
      showSmallModal: true
    });
  },

  _handleModalClose () {
    this.setState({
      showModal: false,
      showSmallModal: false
    });
  }
});

ReactDOM.render(<Demo />, document.getElementById('demo'));<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

app.configure(function(){
  app.set('host', '192.168.33.20');
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);
app.get('/users', user.list);
app.post('/create', routes.create);
app.get('/admin/:host', routes.admin);
app.get('/register/:host', routes.register);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<commit_msg>fixed http verb<commit_after>
/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

app.configure(function(){
  app.set('host', '192.168.33.20');
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);
app.get('/users', user.list);
app.post('/create', routes.create);
app.get('/admin/:host', routes.admin);
app.post('/register/:host', routes.register);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
<|endoftext|>


<commit_before>import { ListItem } from 'react-native-elements';
import RadioButton from 'react-native-radio-button';
import React from 'react';
import PropTypes from 'prop-types';

import { grey, primaryColor } from '../../../globals/colors';
import styles from './styles';

const ListItemRadioButton = ({ key, title, onSwitch, switched }) => (
  <ListItem
    key={key}
    title={title}
    rightIcon={
      <RadioButton
        animation={switched && 'bounceIn'}
        isSelected={switched}
        onPress={onSwitch}
        innerColor={switched ? primaryColor : grey}
        outerColor={switched ? primaryColor : grey}
      />
    }
    containerStyle={styles.container}
    onPress={onSwitch}
  />
);

ListItemRadioButton.propTypes = {
  key: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  onSwitch: PropTypes.func.isRequired,
  switched: PropTypes.bool.isRequired,
};

export default ListItemRadioButton;
<commit_msg>remove unnecessary key prop<commit_after>import { ListItem } from 'react-native-elements';
import RadioButton from 'react-native-radio-button';
import React from 'react';
import PropTypes from 'prop-types';

import { grey, primaryColor } from '../../../globals/colors';
import styles from './styles';

const ListItemRadioButton = ({ title, onSwitch, switched }) => (
  <ListItem
    title={title}
    rightIcon={
      <RadioButton
        animation={switched && 'bounceIn'}
        isSelected={switched}
        onPress={onSwitch}
        innerColor={switched ? primaryColor : grey}
        outerColor={switched ? primaryColor : grey}
      />
    }
    containerStyle={styles.container}
    onPress={onSwitch}
  />
);

ListItemRadioButton.propTypes = {
  title: PropTypes.string.isRequired,
  onSwitch: PropTypes.func.isRequired,
  switched: PropTypes.bool.isRequired,
};

export default ListItemRadioButton;
<|endoftext|>


<commit_before>var html = require('../html');
var atHtml = require('basisjs-tools-ast').html;
var atCss = require('basisjs-tools-ast').css;
var atTmpl = require('basisjs-tools-ast').tmpl;

(module.exports = function(flow){
  var fconsole = flow.console;
  var sortThemes = flow.tmpl.sortThemes;
  var idMap = {};
  var idMapRemovals = {};
  var classMap = {};
  var classMapRemovals = {};
  var bindingWarningCount = 0;
  var appThemes = Object.keys(flow.tmpl.themes);

  if (!appThemes.length)
    appThemes = ['all'];

  flow.css.idMap = idMap;
  flow.css.classMap = classMap;

  //
  // Collect names
  //

  function getMap(map, theme, key){
    if (!hasOwnProperty.call(map, theme))
      map[theme] = {};

    var themeMap = map[theme];

    if (!hasOwnProperty.call(themeMap, key))
    {
      var list = [];
      list.sources = {};
      list.nested = [];
      list.key = key;
      list.postfix = '';
      themeMap[key] = list;

      var baseKey = key.replace(/-anim$/, '');
      if (baseKey != key)
      {
        list.postfix = '-anim';
        getMap(map, theme, baseKey).nested.push(key);
      }
    }

    return themeMap[key];
  }

  function add(map, file, key, token, type, loc){
    var typePart = type.split('-');
    var themes = file.themes || appThemes;

    themes.forEach(function(theme){
      var list = getMap(map, theme, key);

      fconsole.log(typePart[1] + ': ' + key + ' (' + theme + ')');

      list.push({
        file: file,
        loc: loc,
        token: token,
        type: type
      });
      list.sources[typePart[0]] = true;
    });
  }

  function processTemplateAst(file, ast, idMap, classMap){
    atTmpl.walk(ast, flow.js.basis.template, {
      'attr': function(token, parentToken){
        switch (this.tokenName(token))
        {
          case 'id':
            if (token[1])
            {
              bindingWarningCount++;
              flow.warn({
                file: this.file.relpath,
                message: 'binding on id attribute: ' + JSON.stringify(token)
              });
            }
            else
            {
              token.context = this;
              add(idMap, this.file, this.tokenValue(token), token, 'tmpl-id');
            }
            break;

          case 'class':
            var value = this.tokenValue(token).trim();

            if (value)
            {
              token.context = this;
              value.split(/\s+/).forEach(function(name){
                var loc = token.valueLocMap ? token.valueLocMap[name] : token.loc;
                add(classMap, this.file, name, token, 'tmpl-class', loc);
              }, this);
            }

            if (token[1])
              token[1].forEach(function(binding){
                var bindingName = binding[1];
                var classes = this.getBindingClassNames(binding);
                var anim = false;

                if (!classes)
                  return fconsole.log('[!] unpredictable binding: ' + binding[0] + '{' + bindingName + '}');

                if (/^anim:/.test(bindingName))
                {
                  bindingName = bindingName.substr(5);
                  anim = true;
                }

                classes.forEach(function(className){
                  add(classMap, this.file, className, binding, 'tmpl-class-binding'); // binding[0] = '' && binding.push(alias)
                  if (anim)
                    add(classMap, this.file, className + '-anim', binding, 'tmpl-class-anim');
                }, this);
              }, this);

            break;
        }
      }
    }, { file: file });
  }

  for (var i = 0, file; file = flow.files.queue[i]; i++)
  {
    switch (file.type){
      case 'html':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (!file.ast)
          html.processFile(file, flow);

        atHtml.walk(file.ast, {
          'tag': function(node){
            var attrs = atHtml.getAttrs(node);
            var attrsInfo = node.info.attrs;

            if (attrs.id)
              add(idMap, this.file, attrs.id, attrs, 'html-id', this.file.location(attrsInfo.id && attrsInfo.id.start));

            if (attrs.class)
            {
              var loc = attrsInfo.class && attrsInfo.class.start;
              attrs.class.trim().split(/\s+/).forEach(function(name){
                add(classMap, this.file, name, attrs, 'html-class', loc && this.file.location({
                  line: loc.line,
                  column: loc.column + attrs.class.indexOf(name)
                }));
              }, this);
            }
          }
        }, { file: file });

        fconsole.endl();
        break;

      case 'style':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (file.classes)
          file.classes.forEach(function(entry){
            add(classMap, file, entry[2], entry, 'style-class');
          });

        if (file.ids)
          file.ids.forEach(function(entry){
            add(idMap, file, entry[2], entry, 'style-id');
          });

        fconsole.endl();
        break;

      case 'template':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (file.ast)
        {
          processTemplateAst(file, file.ast, idMap, classMap);

          if (file.removals)
          {
            var removals = file.removals.map(function(fragment){
              return fragment.token;
            });
            processTemplateAst(file, removals, idMapRemovals, classMapRemovals);
          }
        }

        fconsole.endl();
        break;
    }
  }

  if (bindingWarningCount)
    fconsole.log('[WARN] ' + bindingWarningCount + ' potential binding problem(s) detected, name optimizing may breakdown app\n');

  //
  // validate names
  //

  var warnNoStyle = {};
  var warnNoHtml = {};

  function arrayAddUnique(array, value){
    if (array.indexOf(value) == -1)
      array.push(value);
  }

  function addWarn(map, entry, theme, value){
    // just filter theme warnings for now
    // TODO: remove when files will be filtered by theme
    if (flow.options.theme && flow.options.theme.indexOf(theme) == -1)
      return;

    // Temporary solution to avoid warnings in some edge cases
    if (entry.file.ignoreWarnings)
      return;

    var loc = entry.loc || entry.token.loc;
    var warning = {
      theme: theme,
      loc: loc,
      value: value,
      filename: entry.file.originator || entry.file.hostFilename || entry.file.filename,
      isolate: entry.file.isolate
    };
    var filename = loc
      ? loc.replace(/\:\d+\:\d+$/, '')
      : entry.file.generatedFrom || entry.file.filename;

    if (!hasOwnProperty.call(map, filename))
    {
      map[filename] = [warning];
      map[filename].file = entry.file;
    }
    else
    {
      map[filename].push(warning);
    }
  }

  for (var theme in classMap)
    for (var name in classMap[theme])
    {
      var list = classMap[theme][name];
      var removalsList = classMapRemovals[theme] && classMapRemovals[theme][name];
      var inHtml = list.sources.html || list.sources.tmpl;
      var inCss = list.sources.style;
      var removedFromHtml = removalsList && (removalsList.sources.html || removalsList.sources.tmpl);

      if (inHtml && !inCss)
        list.forEach(function(entry){
          addWarn(warnNoStyle, entry, theme, '.' + name);
        });

      if (!inHtml && inCss)
      {
        list.forEach(function(entry){
          // ignore warnings for classes in removed parts but in isolated template only
          if (!removedFromHtml || !entry.file.isolate)
            addWarn(warnNoHtml, entry, theme, '.' + name);
        });

        // mark as unused
        list.unused = true;
      }
    }

  for (var theme in idMap)
    for (var name in idMap[theme])
    {
      var list = idMap[theme][name];
      var inHtml = list.sources.html || list.sources.tmpl;
      var inCss = list.sources.style;

      // don't warn in this case since id could be used for references only
      // if (inHtml && !inCss)
      //   list.forEach(function(entry){
      //     addWarn(warnNoStyle, entry, theme, '#' + name);
      //   });

      if (!inHtml && inCss)
      {
        list.forEach(function(entry){
          addWarn(warnNoHtml, entry, theme, '#' + name);
        });

        // mark as unused
        list.unused = true;
      }
    }

  function copyWarnsToFlow(warns, message){
    for (var fn in warns)
    {
      var fileWarns = warns[fn];

      // group by warn message and theme
      var map = fileWarns.reduce(function(res, warn){
        var warnId = [warn.value, warn.filename != fn ? warn.filename : '', warn.isolate || ''].join('\x00');

        if (!hasOwnProperty.call(res, warnId))
          res[warnId] = {};

        var warnMap = res[warnId];

        if (!hasOwnProperty.call(warnMap, warn.theme))
          warnMap[warn.theme] = [warn.loc];
        else
          arrayAddUnique(warnMap[warn.theme], warn.loc);

        return res;
      }, {});

      // merge by themes if loc lists are equal
      for (var warnId in map)
      {
        var warnMap = map[warnId];
        Object.keys(warnMap).forEach(function(theme){
          var locs = String(warnMap[theme]);
          var themes = [];

          // collect same loc list themes
          for (var theme in warnMap)
            if (String(warnMap[theme]) == locs)
              themes.push(theme);

          // merge
          if (themes.length > 1)
          {
            warnMap[sortThemes(themes).join(' ')] = warnMap[theme];
            themes.forEach(function(theme){
              delete warnMap[theme];
            });
          }
        });
      }

      for (var warnId in map)
        for (var theme in map[warnId])
        {
          var info = warnId.split('\x00');
          var warn = {
            file: fn,
            loc: map[warnId][theme],
            theme: theme,
            message: message + ': ' + (info[2] ? info[0].replace(new RegExp('^(.?)' + info[2]), '$1') : info[0])
          };

          if (info[1])
            warn.originator = info[1];
          if (info[2])
            warn.isolate = info[2];

          flow.warn(warn);
        }
    }
  }

  copyWarnsToFlow(warnNoStyle, 'No style rules for');
  copyWarnsToFlow(warnNoHtml, 'Never used in html or templates');

}).handlerName = '[css] Collect info';
<commit_msg>extract: collect css usage info<commit_after>var html = require('../html');
var atHtml = require('basisjs-tools-ast').html;
var atCss = require('basisjs-tools-ast').css;
var atTmpl = require('basisjs-tools-ast').tmpl;

(module.exports = function(flow){
  var fconsole = flow.console;
  var sortThemes = flow.tmpl.sortThemes;
  var idMap = {};
  var idMapRemovals = {};
  var classMap = {};
  var classMapRemovals = {};
  var bindingWarningCount = 0;
  var appThemes = Object.keys(flow.tmpl.themes);
  var usage = {
    classes: {},
    scopes: {}
  };

  if (!appThemes.length)
    appThemes = ['all'];

  flow.css.idMap = idMap;
  flow.css.classMap = classMap;
  flow.css.usage = usage;

  //
  // Collect names
  //

  function getMap(map, theme, key){
    if (!hasOwnProperty.call(map, theme))
      map[theme] = {};

    var themeMap = map[theme];

    if (!hasOwnProperty.call(themeMap, key))
    {
      var list = [];
      list.sources = {};
      list.nested = [];
      list.key = key;
      list.postfix = '';
      themeMap[key] = list;

      var baseKey = key.replace(/-anim$/, '');
      if (baseKey != key)
      {
        list.postfix = '-anim';
        getMap(map, theme, baseKey).nested.push(key);
      }
    }

    return themeMap[key];
  }

  function addToScope(namespaces, className){
    if (!namespaces.length)
      return;

    for (var i = 0; i < namespaces.length; i++)
    {
      var scopeId = namespaces[i];

      if (className.substr(0, scopeId.length) == scopeId)
      {
        if (!usage.scopes[scopeId])
          usage.scopes[scopeId] = {};

        usage.scopes[scopeId][className] = true;
        break;
      }
    }
  }

  function add(map, file, key, token, type, loc){
    var typePart = type.split('-');
    var themes = file.themes || appThemes;

    themes.forEach(function(theme){
      var list = getMap(map, theme, key);

      fconsole.log(typePart[1] + ': ' + key + ' (' + theme + ')');

      list.push({
        file: file,
        loc: loc,
        token: token,
        type: type
      });
      list.sources[typePart[0]] = true;
    });
  }

  function processTemplateAst(file, ast, idMap, classMap){
    var namespaces = [];

    if (file.decl.isolate)
      namespaces.push(file.decl.isolate);

    if (file.styleNSPrefixes)
      for (var namespace in file.styleNSPrefixes)
        namespaces.push(file.styleNSPrefixes[namespace].prefix);

    atTmpl.walk(ast, flow.js.basis.template, {
      'attr': function(token, parentToken){
        switch (this.tokenName(token))
        {
          case 'id':
            if (token[1])
            {
              bindingWarningCount++;
              flow.warn({
                file: this.file.relpath,
                message: 'binding on id attribute: ' + JSON.stringify(token)
              });
            }
            else
            {
              token.context = this;
              add(idMap, this.file, this.tokenValue(token), token, 'tmpl-id');
            }
            break;

          case 'class':
            var value = this.tokenValue(token).trim();

            if (value)
            {
              token.context = this;
              value.split(/\s+/).forEach(function(className){
                var loc = token.valueLocMap ? token.valueLocMap[className] : token.loc;
                add(classMap, this.file, className, token, 'tmpl-class', loc);
                addToScope(namespaces, className);
              }, this);
            }

            if (token[1])
              token[1].forEach(function(binding){
                var bindingName = binding[1];
                var classes = this.getBindingClassNames(binding);
                var anim = false;

                if (!classes)
                  return fconsole.log('[!] unpredictable binding: ' + binding[0] + '{' + bindingName + '}');

                if (/^anim:/.test(bindingName))
                {
                  bindingName = bindingName.substr(5);
                  anim = true;
                }

                classes.forEach(function(className){
                  add(classMap, this.file, className, binding, 'tmpl-class-binding'); // binding[0] = '' && binding.push(alias)
                  addToScope(namespaces, className);

                  if (anim)
                  {
                    add(classMap, this.file, className + '-anim', binding, 'tmpl-class-anim');
                    addToScope(namespaces, className + '-anim');
                  }
                }, this);
              }, this);

            break;
        }
      }
    }, { file: file });
  }

  for (var i = 0, file; file = flow.files.queue[i]; i++)
  {
    switch (file.type){
      case 'html':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (!file.ast)
          html.processFile(file, flow);

        atHtml.walk(file.ast, {
          'tag': function(node){
            var attrs = atHtml.getAttrs(node);
            var attrsInfo = node.info.attrs;

            if (attrs.id)
              add(idMap, this.file, attrs.id, attrs, 'html-id', this.file.location(attrsInfo.id && attrsInfo.id.start));

            if (attrs.class)
            {
              var loc = attrsInfo.class && attrsInfo.class.start;
              attrs.class.trim().split(/\s+/).forEach(function(name){
                add(classMap, this.file, name, attrs, 'html-class', loc && this.file.location({
                  line: loc.line,
                  column: loc.column + attrs.class.indexOf(name)
                }));
              }, this);
            }
          }
        }, { file: file });

        fconsole.endl();
        break;

      case 'style':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (file.classes)
          file.classes.forEach(function(entry){
            add(classMap, file, entry[2], entry, 'style-class');
          });

        if (file.ids)
          file.ids.forEach(function(entry){
            add(idMap, file, entry[2], entry, 'style-id');
          });

        fconsole.endl();
        break;

      case 'template':
        fconsole.start('Scan (' + file.type + ') ' + file.relpath);

        if (file.ast)
        {
          processTemplateAst(file, file.ast, idMap, classMap);

          if (file.removals)
          {
            var removals = file.removals.map(function(fragment){
              return fragment.token;
            });
            processTemplateAst(file, removals, idMapRemovals, classMapRemovals);
          }
        }

        fconsole.endl();
        break;
    }
  }

  if (bindingWarningCount)
    fconsole.log('[WARN] ' + bindingWarningCount + ' potential binding problem(s) detected, name optimizing may breakdown app\n');

  //
  // validate names
  //

  var warnNoStyle = {};
  var warnNoHtml = {};

  function arrayAddUnique(array, value){
    if (array.indexOf(value) == -1)
      array.push(value);
  }

  function addWarn(map, entry, theme, value){
    // just filter theme warnings for now
    // TODO: remove when files will be filtered by theme
    if (flow.options.theme && flow.options.theme.indexOf(theme) == -1)
      return;

    // Temporary solution to avoid warnings in some edge cases
    if (entry.file.ignoreWarnings)
      return;

    var loc = entry.loc || entry.token.loc;
    var warning = {
      theme: theme,
      loc: loc,
      value: value,
      filename: entry.file.originator || entry.file.hostFilename || entry.file.filename,
      isolate: entry.file.isolate
    };
    var filename = loc
      ? loc.replace(/\:\d+\:\d+$/, '')
      : entry.file.generatedFrom || entry.file.filename;

    if (!hasOwnProperty.call(map, filename))
    {
      map[filename] = [warning];
      map[filename].file = entry.file;
    }
    else
    {
      map[filename].push(warning);
    }
  }

  for (var theme in classMap)
    for (var name in classMap[theme])
    {
      var list = classMap[theme][name];
      var removalsList = classMapRemovals[theme] && classMapRemovals[theme][name];
      var inHtml = list.sources.html || list.sources.tmpl;
      var inCss = list.sources.style;
      var removedFromHtml = removalsList && (removalsList.sources.html || removalsList.sources.tmpl);

      if (inHtml && !inCss)
        list.forEach(function(entry){
          addWarn(warnNoStyle, entry, theme, '.' + name);
        });

      if (!inHtml && inCss)
      {
        list.forEach(function(entry){
          // ignore warnings for classes in removed parts but in isolated template only
          if (!removedFromHtml || !entry.file.isolate)
            addWarn(warnNoHtml, entry, theme, '.' + name);
        });

        // mark as unused
        list.unused = true;
      }
      else
      {
        usage.classes[name] = true;
      }
    }

  for (var theme in idMap)
    for (var name in idMap[theme])
    {
      var list = idMap[theme][name];
      var inHtml = list.sources.html || list.sources.tmpl;
      var inCss = list.sources.style;

      // don't warn in this case since id could be used for references only
      // if (inHtml && !inCss)
      //   list.forEach(function(entry){
      //     addWarn(warnNoStyle, entry, theme, '#' + name);
      //   });

      if (!inHtml && inCss)
      {
        list.forEach(function(entry){
          addWarn(warnNoHtml, entry, theme, '#' + name);
        });

        // mark as unused
        list.unused = true;
      }
    }

  function copyWarnsToFlow(warns, message){
    for (var fn in warns)
    {
      var fileWarns = warns[fn];

      // group by warn message and theme
      var map = fileWarns.reduce(function(res, warn){
        var warnId = [warn.value, warn.filename != fn ? warn.filename : '', warn.isolate || ''].join('\x00');

        if (!hasOwnProperty.call(res, warnId))
          res[warnId] = {};

        var warnMap = res[warnId];

        if (!hasOwnProperty.call(warnMap, warn.theme))
          warnMap[warn.theme] = [warn.loc];
        else
          arrayAddUnique(warnMap[warn.theme], warn.loc);

        return res;
      }, {});

      // merge by themes if loc lists are equal
      for (var warnId in map)
      {
        var warnMap = map[warnId];
        Object.keys(warnMap).forEach(function(theme){
          var locs = String(warnMap[theme]);
          var themes = [];

          // collect same loc list themes
          for (var theme in warnMap)
            if (String(warnMap[theme]) == locs)
              themes.push(theme);

          // merge
          if (themes.length > 1)
          {
            warnMap[sortThemes(themes).join(' ')] = warnMap[theme];
            themes.forEach(function(theme){
              delete warnMap[theme];
            });
          }
        });
      }

      for (var warnId in map)
        for (var theme in map[warnId])
        {
          var info = warnId.split('\x00');
          var warn = {
            file: fn,
            loc: map[warnId][theme],
            theme: theme,
            message: message + ': ' + (info[2] ? info[0].replace(new RegExp('^(.?)' + info[2]), '$1') : info[0])
          };

          if (info[1])
            warn.originator = info[1];
          if (info[2])
            warn.isolate = info[2];

          flow.warn(warn);
        }
    }
  }

  copyWarnsToFlow(warnNoStyle, 'No style rules for');
  copyWarnsToFlow(warnNoHtml, 'Never used in html or templates');

  usage.classes = Object.keys(usage.classes);
  usage.scopes = Object.keys(usage.scopes).map(function(key){
    return Object.keys(usage.scopes[key]);
  });

}).handlerName = '[css] Collect info';
<|endoftext|>


<commit_before>'use strict';

var domify = require('min-dom/lib/domify');

// document wide unique overlay ids
var ids = new (require('diagram-js/lib/util/IdGenerator'))('row');

/**
 * Adds a control to the table to add more rows
 *
 * @param {EventBus} eventBus
 */
function AddRow(eventBus, sheet, elementRegistry, modeling) {

  this.row = null;

  var self = this;
  // add the row control row
  eventBus.on('utilityColumn.added', function(event) {
    var column = event.column;
    self.row = sheet.addRow({
      id: 'tjs-controls',
      isFoot: true
    });

    var node = domify('');

    node.addEventListener('mouseup', function() {
      modeling.createRow({ id: ids.next() });
    });

    sheet.setCellContent({
      row: self.row,
      column: column,
      content: node
    });

  });
}

AddRow.$inject = [ 'eventBus', 'sheet', 'elementRegistry', 'modeling' ];

module.exports = AddRow;

AddRow.prototype.getRow = function() {
  return this.row;
};
<commit_msg>feat(add-row): add basic plus sign<commit_after>'use strict';

var domify = require('min-dom/lib/domify');

// document wide unique overlay ids
var ids = new (require('diagram-js/lib/util/IdGenerator'))('row');

/**
 * Adds a control to the table to add more rows
 *
 * @param {EventBus} eventBus
 */
function AddRow(eventBus, sheet, elementRegistry, modeling) {

  this.row = null;

  var self = this;
  // add the row control row
  eventBus.on('utilityColumn.added', function(event) {
    var column = event.column;
    self.row = sheet.addRow({
      id: 'tjs-controls',
      isFoot: true
    });

    var node = domify('+');

    node.addEventListener('mouseup', function() {
      modeling.createRow({ id: ids.next() });
    });

    sheet.setCellContent({
      row: self.row,
      column: column,
      content: node
    });

  });
}

AddRow.$inject = [ 'eventBus', 'sheet', 'elementRegistry', 'modeling' ];

module.exports = AddRow;

AddRow.prototype.getRow = function() {
  return this.row;
};
<|endoftext|>


<commit_before>'use strict';
(function () {

    var net    = require('net'),
        crypto = require('crypto'),
        url    = require('url');

    /**
     * Constructor
     * @param <object> httpAdapter Http Adapter
     * @param <string> clientId    Google client id
     * @param <string> apiKey      Google Api Key
     */
    var GoogleGeocoder = function(httpAdapter, clientId, apiKey) {

        if (!httpAdapter || httpAdapter == 'undefinded') {

            throw new Error('Google Geocoder need an httpAdapter');
        }

        if (!apiKey || apiKey == 'undefinded') {

            apiKey = null;
        }

        this.apiKey = apiKey;

        if (!clientId || clientId == 'undefinded') {

            clientId = null;
        }

        if (clientId && !apiKey) {

            throw new Error('You must specify a apiKey (privateKey)');
        }

        this.clientId = clientId;

        this.httpAdapter = httpAdapter;
    };

    // Google geocoding API endpoint
    GoogleGeocoder.prototype._endpoint = 'https://maps.googleapis.com/maps/api/geocode/json';

    /**
    * Geocode
    * @param <string>   value    Value to geocode (Adress)
    * @param <function> callback Callback method
    */
    GoogleGeocoder.prototype.geocode = function(value, callback) {

        if (net.isIP(value)) {
            throw new Error('Google Geocoder no suport geocoding ip');
        }
        var _this = this;

        var params = this._prepareQueryString();
        params.address = value;
        this._signedRequest(this._endpoint, params);
        this.httpAdapter.get(this._endpoint, params, function(err, result) {
            if (err) {
                throw err;
            } else {
                // status can be "OK", "ZERO_RESULTS", "OVER_QUERY_LIMIT", "REQUEST_DENIED", "INVALID_REQUEST", or "UNKNOWN_ERROR"
                // error_message may or may not be present
                if (result.status !== 'OK') {
                    return callback(new Error('Status is ' + result.status + '.' + (result.error_message ? ' ' + result.error_message : '')));
                }

                var results = [];

                for(var i = 0; i < result.results.length; i++) {
                    results.push(_this._formatResult(result.results[i]));
                }

                callback(false, results);
            }

        });

    };

    GoogleGeocoder.prototype._prepareQueryString = function() {
        var params = {
            'sensor' : false
        };

        if (this.clientId) {
            params.client = this.clientId;
        }

        return params;
    };

    GoogleGeocoder.prototype._signedRequest = function(endpoint, params) {
        if (this.clientId) {
            var request = url.parse(endpoint);
            request.query = params;
            request = url.parse(request.format());
            request.path = '/maps/api/geocode/json?address=blah&sensor=false&client=foo';
            var decodedKey = new Buffer(this.apiKey.replace('-', '+').replace('_', '/'), 'base64').toString('binary');
            var hmac = crypto.createHmac('sha1', decodedKey);
            hmac.update(request.path);
            var signature = hmac.digest('base64');

            signature = signature.replace('+', '-').replace('/', '_');

            params.signature = signature;
        }

        return params;
    };

    GoogleGeocoder.prototype._formatResult = function(result) {

        var country = null;
        var countryCode = null;
        var city = null;
        var state = null;
        var stateCode = null;
        var zipcode = null;
        var streetName = null;
        var streetNumber = null;

        for (var i = 0; i < result.address_components.length; i++) {
            // Country
            if (result.address_components[i].types.indexOf('country') >= 0) {
                country = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('country') >= 0) {
                countryCode = result.address_components[i].short_name;
            }
            // State
            if (result.address_components[i].types.indexOf('administrative_area_level_1') >= 0) {
                state = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('administrative_area_level_1') >= 0) {
                stateCode = result.address_components[i].short_name;
            }
            // City
            if (result.address_components[i].types.indexOf('locality') >= 0) {
                city = result.address_components[i].long_name;
            }
            // Adress
            if (result.address_components[i].types.indexOf('postal_code') >= 0) {
                zipcode = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('route') >= 0) {
                streetName = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('street_number') >= 0) {
                streetNumber = result.address_components[i].long_name;
            }
        }

        return {
            'latitude' : result.geometry.location.lat,
            'longitude' : result.geometry.location.lng,
            'country' : country,
            'city' : city,
            'state' : state,
            'stateCode' : stateCode,
            'zipcode' : zipcode,
            'streetName': streetName,
            'streetNumber' : streetNumber,
            'countryCode' : countryCode

        };
    };

    /**
    * Reverse geocoding
    * @param <integer>  lat      Latittude
    * @param <integer>  lng      Longitude
    * @param <function> callback Callback method
    */
    GoogleGeocoder.prototype.reverse = function(lat, lng, callback) {

        var _this = this;
        var params = this._prepareQueryString();
        params.latlng = lat + ',' + lng;
        this._signedRequest(this._endpoint, params);
        this.httpAdapter.get(this._endpoint , params, function(err, result) {
            if (err) {
                throw err;
            } else {
                // status can be "OK", "ZERO_RESULTS", "OVER_QUERY_LIMIT", "REQUEST_DENIED", "INVALID_REQUEST", or "UNKNOWN_ERROR"
                // error_message may or may not be present
                if (result.status !== 'OK') {
                    return callback(new Error('Status is ' + result.status + '.' + (result.error_message ? ' ' + result.error_message : '')));
                }

                var results = [];

                if(result.results.length > 0) {
                    results.push(_this._formatResult(result.results[0]));
                }

                callback(false, results);
            }
        });
    };

    module.exports = GoogleGeocoder;

})();
<commit_msg>fix node 0.8 compatibility<commit_after>'use strict';
(function () {

    var net    = require('net'),
        crypto = require('crypto'),
        url    = require('url');

    /**
     * Constructor
     * @param <object> httpAdapter Http Adapter
     * @param <string> clientId    Google client id
     * @param <string> apiKey      Google Api Key
     */
    var GoogleGeocoder = function(httpAdapter, clientId, apiKey) {

        if (!httpAdapter || httpAdapter == 'undefinded') {

            throw new Error('Google Geocoder need an httpAdapter');
        }

        if (!apiKey || apiKey == 'undefinded') {

            apiKey = null;
        }

        this.apiKey = apiKey;

        if (!clientId || clientId == 'undefinded') {

            clientId = null;
        }

        if (clientId && !apiKey) {

            throw new Error('You must specify a apiKey (privateKey)');
        }

        this.clientId = clientId;

        this.httpAdapter = httpAdapter;
    };

    // Google geocoding API endpoint
    GoogleGeocoder.prototype._endpoint = 'https://maps.googleapis.com/maps/api/geocode/json';

    /**
    * Geocode
    * @param <string>   value    Value to geocode (Adress)
    * @param <function> callback Callback method
    */
    GoogleGeocoder.prototype.geocode = function(value, callback) {

        if (net.isIP(value)) {
            throw new Error('Google Geocoder no suport geocoding ip');
        }
        var _this = this;

        var params = this._prepareQueryString();
        params.address = value;
        this._signedRequest(this._endpoint, params);
        this.httpAdapter.get(this._endpoint, params, function(err, result) {
            if (err) {
                throw err;
            } else {
                // status can be "OK", "ZERO_RESULTS", "OVER_QUERY_LIMIT", "REQUEST_DENIED", "INVALID_REQUEST", or "UNKNOWN_ERROR"
                // error_message may or may not be present
                if (result.status !== 'OK') {
                    return callback(new Error('Status is ' + result.status + '.' + (result.error_message ? ' ' + result.error_message : '')));
                }

                var results = [];

                for(var i = 0; i < result.results.length; i++) {
                    results.push(_this._formatResult(result.results[i]));
                }

                callback(false, results);
            }

        });

    };

    GoogleGeocoder.prototype._prepareQueryString = function() {
        var params = {
            'sensor' : false
        };

        if (this.clientId) {
            params.client = this.clientId;
        }

        return params;
    };

    GoogleGeocoder.prototype._signedRequest = function(endpoint, params) {
        if (this.clientId) {
            var request = url.parse(endpoint);
            request.query = params;
            request = url.parse(url.format(request));
            request.path = '/maps/api/geocode/json?address=blah&sensor=false&client=foo';
            var decodedKey = new Buffer(this.apiKey.replace('-', '+').replace('_', '/'), 'base64').toString('binary');
            var hmac = crypto.createHmac('sha1', decodedKey);
            hmac.update(request.path);
            var signature = hmac.digest('base64');

            signature = signature.replace('+', '-').replace('/', '_');

            params.signature = signature;
        }

        return params;
    };

    GoogleGeocoder.prototype._formatResult = function(result) {

        var country = null;
        var countryCode = null;
        var city = null;
        var state = null;
        var stateCode = null;
        var zipcode = null;
        var streetName = null;
        var streetNumber = null;

        for (var i = 0; i < result.address_components.length; i++) {
            // Country
            if (result.address_components[i].types.indexOf('country') >= 0) {
                country = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('country') >= 0) {
                countryCode = result.address_components[i].short_name;
            }
            // State
            if (result.address_components[i].types.indexOf('administrative_area_level_1') >= 0) {
                state = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('administrative_area_level_1') >= 0) {
                stateCode = result.address_components[i].short_name;
            }
            // City
            if (result.address_components[i].types.indexOf('locality') >= 0) {
                city = result.address_components[i].long_name;
            }
            // Adress
            if (result.address_components[i].types.indexOf('postal_code') >= 0) {
                zipcode = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('route') >= 0) {
                streetName = result.address_components[i].long_name;
            }
            if (result.address_components[i].types.indexOf('street_number') >= 0) {
                streetNumber = result.address_components[i].long_name;
            }
        }

        return {
            'latitude' : result.geometry.location.lat,
            'longitude' : result.geometry.location.lng,
            'country' : country,
            'city' : city,
            'state' : state,
            'stateCode' : stateCode,
            'zipcode' : zipcode,
            'streetName': streetName,
            'streetNumber' : streetNumber,
            'countryCode' : countryCode

        };
    };

    /**
    * Reverse geocoding
    * @param <integer>  lat      Latittude
    * @param <integer>  lng      Longitude
    * @param <function> callback Callback method
    */
    GoogleGeocoder.prototype.reverse = function(lat, lng, callback) {

        var _this = this;
        var params = this._prepareQueryString();
        params.latlng = lat + ',' + lng;
        this._signedRequest(this._endpoint, params);
        this.httpAdapter.get(this._endpoint , params, function(err, result) {
            if (err) {
                throw err;
            } else {
                // status can be "OK", "ZERO_RESULTS", "OVER_QUERY_LIMIT", "REQUEST_DENIED", "INVALID_REQUEST", or "UNKNOWN_ERROR"
                // error_message may or may not be present
                if (result.status !== 'OK') {
                    return callback(new Error('Status is ' + result.status + '.' + (result.error_message ? ' ' + result.error_message : '')));
                }

                var results = [];

                if(result.results.length > 0) {
                    results.push(_this._formatResult(result.results[0]));
                }

                callback(false, results);
            }
        });
    };

    module.exports = GoogleGeocoder;

})();
<|endoftext|>


<commit_before>/*
 * @license
 * Copyright 2016 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.
 */

/**
 * Top-Level of foam package
 * @exports foam
 */
foam = {
  isServer: typeof process === 'object',
  core:     {},
  Array:    Array.prototype,
  Function: Function.prototype,
  Number:   Number.prototype,
  Object:   Object.prototype,
  String:   String.prototype,
  Date:     Date.prototype,
};

/** Setup nodejs-like 'global' on web */
if ( ! foam.isServer ) global = this;

/**
 * A LIB is a collection of static constants, properties and functions.
 */
foam.LIB = function LIB(model) {
  var proto;

  function defineProperty(proto, key, map) {
    if ( ! map.value || proto === Object.prototype || proto === Array.prototype )
      Object.defineProperty.apply(this, arguments);
    else
      proto[key] = map.value;
  }

  proto = model.name ? foam[model.name] || ( foam[model.name] = {} ) : foam;

  if ( model.properties ) for ( var i = 0 ; i < model.properties.length ; i++ ) {
    var p = model.properties[i];
    defineProperty(
      proto,
      p.name,
      { get: p.getter, enumerable: false });
  }

  for ( key in model.constants )
    defineProperty(
      proto,
      key,
      { value: model.constants[key], writable: true, enumerable: false });

  if ( model.methods ) for ( var i = 0 ; i < model.methods.length ; i++ ) {
    var m = model.methods[i];
    defineProperty(
      proto,
      m.name,
      { value: m.code || m, writable: true, enumerable: false });
  }
};

/*
 * Add Unique Identifiers (UIDs) to all Objects.
 * UID's are created when first accessed.
 */
foam.LIB({
  name: 'Object',

  properties: [
    {
      name: '$UID',
      getter: (function() {
        var id = 1;
        return function() {
          if ( Object.hasOwnProperty.call(this, '$UID__') ) return this.$UID__;
          Object.defineProperty(this, '$UID__', {value: id, enumerable: false});
          id++;
          return this.$UID__;
        };
      })()
    }
  ]
});

foam.LIB({
  name: 'Number',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },
  ]
});

foam.LIB({
  name: 'String',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },

    /** Adds hashCode functionality to all strings. */
    function hashCode() {
      var hash = 0;
      if ( this.length == 0 ) return hash;

      for (i = 0; i < this.length; i++) {
        var code = this.charCodeAt(i);
        hash = ((hash << 5) - hash) + code;
        hash &= hash;
      }

      return hash;
    }
  ]
});

foam.LIB({
  name: 'Array',
  methods: [
    function diff(other) {
      /** Finds elements added (found in other, not in this) and removed
          (found in this, not in other). Repeated values are treated
          as separate elements, but ordering changes are ignored. */
      var added = other.slice(0);
      var removed = [];
      for ( var i = 0 ; i < this.length ; i++ ) {
        for ( var j = 0 ; j < added.length ; j++ ) {
          if ( this[i].compareTo(added[j]) == 0 ) {
            added.splice(j, 1);
            j--;
            break;
          }
        }
        if ( j == added.length ) removed.push(this[i]);
      }
      return { added: added, removed: removed };
    },
    function clone() {
      /** Returns a deep copy of this array and its contents. */
      var ret = new Array(this.length);
      for ( var i = 0; i < this.length; i++ ) {
        ret[i] = ( this[i].clone ) ? this[i].clone() : this[i];
      }
      return ret;
    },
    function shallowClone() {
      /** Returns a new array containing the same elements as this. */
      return this.slice();
    }
  ]
});

foam.LIB({
  name: 'Date',
  methods: [
    function toRelativeDateString(){
      // TODO i18n: make this translatable
      var seconds = Math.floor((Date.now() - this.getTime())/1000);

      if ( seconds < 60 ) return 'moments ago';

      var minutes = Math.floor((seconds)/60);

      if ( minutes == 1 ) return '1 minute ago';

      if ( minutes < 60 ) return minutes + ' minutes ago';

      var hours = Math.floor(minutes/60);
      if ( hours == 1 ) return '1 hour ago';

      if ( hours < 24 ) return hours + ' hours ago';

      var days = Math.floor(hours / 24);
      if ( days == 1 ) return '1 day ago';

      if ( days < 7 ) return days + ' days ago';

      if ( days < 365 ) {
        var year = 1900+this.getYear();
        var noyear = this.toDateString().replace(' ' + year, '');
        return noyear.substring(4);
      }

      return this.toDateString().substring(4);
    },

    function equals(o) {
      if ( ! o ) return false;
      if ( ! o.getTime ) return false;
      return this.getTime() === o.getTime();
    },

    function compareTo(o){
      if ( o === this ) return 0;
      if ( ! o ) return 1;
      var d = this.getTime() - o.getTime();
      return d == 0 ? 0 : d > 0 ? 1 : -1;
    }
  ]
});

foam.LIB({
  name: 'array',

  methods: [
    function argsToArray(args) {
      /** convenience method to turn 'arguments' into a real array */
      return foam.fn.appendArguments([], args, 0);
    }
  ]
});

foam.LIB({
  name: 'events',

  methods: [
    function oneTime(listener) {
      /** Create a "one-time" listener which unsubscribes itself after its first invocation. **/
      return function(subscription) {
        listener.apply(this, foam.array.argsToArray(arguments));
        subscription.destroy();
      };
    },

    function consoleLog(listener) {
      /** Log all listener invocations to console. **/
      return function() {
        var args = foam.array.argsToArray(arguments);
        console.log(args);
        listener && listener.apply(this, args);
      };
    }
  ]
});

foam.LIB({
  name: 'util',
  methods: [
    function equals(a, b) {
      if ( a === b ) return true;
      if ( ! a || ! b ) return false;
      if ( a.equals ) return a.equals(b);
      return a == b;
    }
  ]
});

foam.LIB({
  name: 'fn',

  methods: [
    /** Faster version of memoize() when only dealing with one argument. */
    function memoize1(f) {
      var cache = {};
      var g = function(arg) {
        console.assert(arguments.length == 1, "Memoize1'ed functions must take exactly one argument.");
        var key = arg ? arg.toString() : '';
        if ( ! cache.hasOwnProperty(key) ) cache[key] = f.call(this, arg);
        return cache[key];
      };
      foam.fn.setName(g, 'memoize1(' + f.name + ')');
      return g;
    },

    function setName(f, name) {
      /** Set a function's name for improved debugging and profiling **/
      Object.defineProperty(f, 'name', {value: name, configurable: true});
    },

    function appendArguments(a, args, start) {
      /** Convenience method to append 'arguments' onto a real array **/
      for ( var i = start ; i < args.length ; i++ ) a.push(args[i]);
      return a;
    },

    function argsStr(f) {
      /** Finds the function(...) declaration arguments part. Strips newlines. */
      return f.toString().replace(/(\r\n|\n|\r)/gm,"").match(/^function(\s+[_$\w]+|\s*)\((.*?)\)/)[2] || '';
    },

    function argsArray(f) {
      /**
       * Return a function's arguments as an array.
       * Ex. args(function(a,b) {...}) == ['a', 'b']
       **/
      var args = foam.fn.argsStr(f);
      if ( ! args ) return [];
      args += ',';

      var ret = [];
      // [ ws /* anything */ ] ws arg_name ws [ /* anything */ ],
      var argMatcher = /(\s*\/\*.*?\*\/)?\s*([\w_$]+)\s*(\/\*.*?\*\/)?\s*\,+/g;
      var typeMatch;
      while ((typeMatch = argMatcher.exec(args)) !== null) {
        ret.push(typeMatch[2]);
      }
      return ret;
    },

    // ???: Is this needed?
    /*
    function passProperties(args, f) {
      return function passProperties() {
        var self = this;
        return f.apply(this, args.map(function(arg) { return self[arg]; }));
      };
    }
    */
  ]
});

(function() {
  // Disable setName if not supported on this platform.
  try {
    foam.fn.setName(function() {}, '');
  } catch (x) {
    /**
      @class fn
      @ignore */
    foam.LIB({
      name: 'fn',
      methods: [ function setName() { /* NOP */ } ]
    });
  }
})();

foam.LIB({
  name: 'string',

  methods: [
    {
      name: 'constantize',
      code: foam.fn.memoize1(function(str) {
        // switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
        return str.replace(/[a-z][^0-9a-z_]/g, function(a) {
          return a.substring(0,1) + '_' + a.substring(1,2);
        }).toUpperCase();
      })
    },

    {
      name: 'labelize',
      code: foam.fn.memoize1(function(str) {
        if ( ! str || str === '' ) return str;
        return this.capitalize(str.replace(/[a-z][A-Z]/g, function (a) { return a.charAt(0) + ' ' + a.charAt(1); }));
      })
    },

    {
      name: 'capitalize',
      code: foam.fn.memoize1(function(str) {
        // switchFromProperyName to //SwitchFromPropertyName
        return str[0].toUpperCase() + str.substring(1);
      })
    },

    function pad(str, size) {
      // Right pads to size if size > 0, Left pads to -size if size < 0
      return size < 0 ?
        (new Array(-size).join(' ') + str).slice(size)       :
        (str + new Array(size).join(' ')).substring(0, size) ;
    },

    function multiline(f) {
      // Function for returning multi-line strings from commented functions.
      // Ex. var str = multiline(function() { /* multi-line string here */ });
      if ( typeof f === 'string' ) return f;
      var s = f.toString();
      var start = s.indexOf('/*');
      var end   = s.lastIndexOf('*/');
      return s.substring(start+2, end);
    }
  ]
});

(function() {

  function set(X, key, value) {
    /* Update a Context binding. */
    X[key] = value;

    // TODO:
    // if ( GLOBAL.SimpleReadOnlyValue && key !== '$' && key !== '$$' )
    // X[key + '$'] = SimpleReadOnlyValue.create({value: value});
  }

  function setDynamic(X, key, dValue) {
    Object.defineProperty(
      X,
      key,
      {
        get: function() { return dValue.get(); },
        configurable: true
      }
    );

    if ( key !== '$' && key !== '$$' ) X[key + '$'] = dValue;
  }

  var ROOT = global;

  var lookup_ = function lookup_(id) {
    var a = foam.core[id];
    if ( a ) return a;
    var path = id.split('.');
    var root = ROOT;
    for ( var i = 0 ; root && i < path.length ; i++ )
      root = root[path[i]];
    return root;
  };

  var cache = {};

  var X = {
    lookup: function(id) {
      return id && ( cache[id] || ( cache[id] = lookup_(id) ) );
    },

    register: function(cls) {
      cache = {};
      var path = cls.id.split('.');
      var root = ROOT;
      for ( var i = 0 ; i < path.length-1 ; i++ ) {
        root = root[path[i]] || ( root[path[i]] = {} );
      }
      root[path[path.length-1]] = cls;
    },

    sub: function sub(opt_args, opt_name) {
      var sub = Object.create(this);

      if ( opt_args ) for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var asDyn = key !== '$' && key != '$$' && key.charAt(key.length-1) == '$';
          if ( asDyn ) {
            setDynamic(sub, key.substring(0, key.length-1), opt_args[key]);
          } else {
            set(sub, key, opt_args[key]);
          }
        }
      }

      if ( opt_name )
        Object.defineProperty(sub, 'NAME', {value: opt_name, enumerable: false});

      return sub;
    }
  };

  foam.X = X;

  for ( var key in X ) foam[key] = X[key].bind(X);
})();
<commit_msg>Smarter cache invalidation.<commit_after>/*
 * @license
 * Copyright 2016 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.
 */

/**
 * Top-Level of foam package
 * @exports foam
 */
foam = {
  isServer: typeof process === 'object',
  core:     {},
  Array:    Array.prototype,
  Function: Function.prototype,
  Number:   Number.prototype,
  Object:   Object.prototype,
  String:   String.prototype,
  Date:     Date.prototype,
};

/** Setup nodejs-like 'global' on web */
if ( ! foam.isServer ) global = this;

/**
 * A LIB is a collection of static constants, properties and functions.
 */
foam.LIB = function LIB(model) {
  var proto;

  function defineProperty(proto, key, map) {
    if ( ! map.value || proto === Object.prototype || proto === Array.prototype )
      Object.defineProperty.apply(this, arguments);
    else
      proto[key] = map.value;
  }

  proto = model.name ? foam[model.name] || ( foam[model.name] = {} ) : foam;

  if ( model.properties ) for ( var i = 0 ; i < model.properties.length ; i++ ) {
    var p = model.properties[i];
    defineProperty(
      proto,
      p.name,
      { get: p.getter, enumerable: false });
  }

  for ( key in model.constants )
    defineProperty(
      proto,
      key,
      { value: model.constants[key], writable: true, enumerable: false });

  if ( model.methods ) for ( var i = 0 ; i < model.methods.length ; i++ ) {
    var m = model.methods[i];
    defineProperty(
      proto,
      m.name,
      { value: m.code || m, writable: true, enumerable: false });
  }
};

/*
 * Add Unique Identifiers (UIDs) to all Objects.
 * UID's are created when first accessed.
 */
foam.LIB({
  name: 'Object',

  properties: [
    {
      name: '$UID',
      getter: (function() {
        var id = 1;
        return function() {
          if ( Object.hasOwnProperty.call(this, '$UID__') ) return this.$UID__;
          Object.defineProperty(this, '$UID__', {value: id, enumerable: false});
          id++;
          return this.$UID__;
        };
      })()
    }
  ]
});

foam.LIB({
  name: 'Number',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },
  ]
});

foam.LIB({
  name: 'String',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },

    /** Adds hashCode functionality to all strings. */
    function hashCode() {
      var hash = 0;
      if ( this.length == 0 ) return hash;

      for (i = 0; i < this.length; i++) {
        var code = this.charCodeAt(i);
        hash = ((hash << 5) - hash) + code;
        hash &= hash;
      }

      return hash;
    }
  ]
});

foam.LIB({
  name: 'Array',
  methods: [
    function diff(other) {
      /** Finds elements added (found in other, not in this) and removed
          (found in this, not in other). Repeated values are treated
          as separate elements, but ordering changes are ignored. */
      var added = other.slice(0);
      var removed = [];
      for ( var i = 0 ; i < this.length ; i++ ) {
        for ( var j = 0 ; j < added.length ; j++ ) {
          if ( this[i].compareTo(added[j]) == 0 ) {
            added.splice(j, 1);
            j--;
            break;
          }
        }
        if ( j == added.length ) removed.push(this[i]);
      }
      return { added: added, removed: removed };
    },
    function clone() {
      /** Returns a deep copy of this array and its contents. */
      var ret = new Array(this.length);
      for ( var i = 0; i < this.length; i++ ) {
        ret[i] = ( this[i].clone ) ? this[i].clone() : this[i];
      }
      return ret;
    },
    function shallowClone() {
      /** Returns a new array containing the same elements as this. */
      return this.slice();
    }
  ]
});

foam.LIB({
  name: 'Date',
  methods: [
    function toRelativeDateString(){
      // TODO i18n: make this translatable
      var seconds = Math.floor((Date.now() - this.getTime())/1000);

      if ( seconds < 60 ) return 'moments ago';

      var minutes = Math.floor((seconds)/60);

      if ( minutes == 1 ) return '1 minute ago';

      if ( minutes < 60 ) return minutes + ' minutes ago';

      var hours = Math.floor(minutes/60);
      if ( hours == 1 ) return '1 hour ago';

      if ( hours < 24 ) return hours + ' hours ago';

      var days = Math.floor(hours / 24);
      if ( days == 1 ) return '1 day ago';

      if ( days < 7 ) return days + ' days ago';

      if ( days < 365 ) {
        var year = 1900+this.getYear();
        var noyear = this.toDateString().replace(' ' + year, '');
        return noyear.substring(4);
      }

      return this.toDateString().substring(4);
    },

    function equals(o) {
      if ( ! o ) return false;
      if ( ! o.getTime ) return false;
      return this.getTime() === o.getTime();
    },

    function compareTo(o){
      if ( o === this ) return 0;
      if ( ! o ) return 1;
      var d = this.getTime() - o.getTime();
      return d == 0 ? 0 : d > 0 ? 1 : -1;
    }
  ]
});

foam.LIB({
  name: 'array',

  methods: [
    function argsToArray(args) {
      /** convenience method to turn 'arguments' into a real array */
      return foam.fn.appendArguments([], args, 0);
    }
  ]
});

foam.LIB({
  name: 'events',

  methods: [
    function oneTime(listener) {
      /** Create a "one-time" listener which unsubscribes itself after its first invocation. **/
      return function(subscription) {
        listener.apply(this, foam.array.argsToArray(arguments));
        subscription.destroy();
      };
    },

    function consoleLog(listener) {
      /** Log all listener invocations to console. **/
      return function() {
        var args = foam.array.argsToArray(arguments);
        console.log(args);
        listener && listener.apply(this, args);
      };
    }
  ]
});

foam.LIB({
  name: 'util',
  methods: [
    function equals(a, b) {
      if ( a === b ) return true;
      if ( ! a || ! b ) return false;
      if ( a.equals ) return a.equals(b);
      return a == b;
    }
  ]
});

foam.LIB({
  name: 'fn',

  methods: [
    /** Faster version of memoize() when only dealing with one argument. */
    function memoize1(f) {
      var cache = {};
      var g = function(arg) {
        console.assert(arguments.length == 1, "Memoize1'ed functions must take exactly one argument.");
        var key = arg ? arg.toString() : '';
        if ( ! cache.hasOwnProperty(key) ) cache[key] = f.call(this, arg);
        return cache[key];
      };
      foam.fn.setName(g, 'memoize1(' + f.name + ')');
      return g;
    },

    function setName(f, name) {
      /** Set a function's name for improved debugging and profiling **/
      Object.defineProperty(f, 'name', {value: name, configurable: true});
    },

    function appendArguments(a, args, start) {
      /** Convenience method to append 'arguments' onto a real array **/
      for ( var i = start ; i < args.length ; i++ ) a.push(args[i]);
      return a;
    },

    function argsStr(f) {
      /** Finds the function(...) declaration arguments part. Strips newlines. */
      return f.toString().replace(/(\r\n|\n|\r)/gm,"").match(/^function(\s+[_$\w]+|\s*)\((.*?)\)/)[2] || '';
    },

    function argsArray(f) {
      /**
       * Return a function's arguments as an array.
       * Ex. args(function(a,b) {...}) == ['a', 'b']
       **/
      var args = foam.fn.argsStr(f);
      if ( ! args ) return [];
      args += ',';

      var ret = [];
      // [ ws /* anything */ ] ws arg_name ws [ /* anything */ ],
      var argMatcher = /(\s*\/\*.*?\*\/)?\s*([\w_$]+)\s*(\/\*.*?\*\/)?\s*\,+/g;
      var typeMatch;
      while ((typeMatch = argMatcher.exec(args)) !== null) {
        ret.push(typeMatch[2]);
      }
      return ret;
    },

    // ???: Is this needed?
    /*
    function passProperties(args, f) {
      return function passProperties() {
        var self = this;
        return f.apply(this, args.map(function(arg) { return self[arg]; }));
      };
    }
    */
  ]
});

(function() {
  // Disable setName if not supported on this platform.
  try {
    foam.fn.setName(function() {}, '');
  } catch (x) {
    /**
      @class fn
      @ignore */
    foam.LIB({
      name: 'fn',
      methods: [ function setName() { /* NOP */ } ]
    });
  }
})();

foam.LIB({
  name: 'string',

  methods: [
    {
      name: 'constantize',
      code: foam.fn.memoize1(function(str) {
        // switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
        return str.replace(/[a-z][^0-9a-z_]/g, function(a) {
          return a.substring(0,1) + '_' + a.substring(1,2);
        }).toUpperCase();
      })
    },

    {
      name: 'labelize',
      code: foam.fn.memoize1(function(str) {
        if ( ! str || str === '' ) return str;
        return this.capitalize(str.replace(/[a-z][A-Z]/g, function (a) { return a.charAt(0) + ' ' + a.charAt(1); }));
      })
    },

    {
      name: 'capitalize',
      code: foam.fn.memoize1(function(str) {
        // switchFromProperyName to //SwitchFromPropertyName
        return str[0].toUpperCase() + str.substring(1);
      })
    },

    function pad(str, size) {
      // Right pads to size if size > 0, Left pads to -size if size < 0
      return size < 0 ?
        (new Array(-size).join(' ') + str).slice(size)       :
        (str + new Array(size).join(' ')).substring(0, size) ;
    },

    function multiline(f) {
      // Function for returning multi-line strings from commented functions.
      // Ex. var str = multiline(function() { /* multi-line string here */ });
      if ( typeof f === 'string' ) return f;
      var s = f.toString();
      var start = s.indexOf('/*');
      var end   = s.lastIndexOf('*/');
      return s.substring(start+2, end);
    }
  ]
});

(function() {

  function set(X, key, value) {
    /* Update a Context binding. */
    X[key] = value;

    // TODO:
    // if ( GLOBAL.SimpleReadOnlyValue && key !== '$' && key !== '$$' )
    // X[key + '$'] = SimpleReadOnlyValue.create({value: value});
  }

  function setDynamic(X, key, dValue) {
    Object.defineProperty(
      X,
      key,
      {
        get: function() { return dValue.get(); },
        configurable: true
      }
    );

    if ( key !== '$' && key !== '$$' ) X[key + '$'] = dValue;
  }

  var ROOT = global;

  var lookup_ = function lookup_(id) {
    var a = foam.core[id];
    if ( a ) return a;
    var path = id.split('.');
    var root = ROOT;
    for ( var i = 0 ; root && i < path.length ; i++ )
      root = root[path[i]];
    return root;
  };

  var cache = {};

  var X = {
    lookup: function(id) {
      return id && ( cache[id] || ( cache[id] = lookup_(id) ) );
    },

    register: function(cls) {
      cache[cls.id] = cls;
      if ( cls.package === 'foam.core' )
        cache[cls.name] = cls;
      var path = cls.id.split('.');
      var root = ROOT;
      for ( var i = 0 ; i < path.length-1 ; i++ ) {
        root = root[path[i]] || ( root[path[i]] = {} );
      }
      root[path[path.length-1]] = cls;
    },

    sub: function sub(opt_args, opt_name) {
      var sub = Object.create(this);

      if ( opt_args ) for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var asDyn = key !== '$' && key != '$$' && key.charAt(key.length-1) == '$';
          if ( asDyn ) {
            setDynamic(sub, key.substring(0, key.length-1), opt_args[key]);
          } else {
            set(sub, key, opt_args[key]);
          }
        }
      }

      if ( opt_name )
        Object.defineProperty(sub, 'NAME', {value: opt_name, enumerable: false});

      return sub;
    }
  };

  foam.X = X;

  for ( var key in X ) foam[key] = X[key].bind(X);
})();
<|endoftext|>