<commit_before>/* ------------
 * Fill select element with birdnames + draw charts for first bird
 * ------------
*/

$(document).ready(
    function() {
	bird_results = getAllBirdInfo("");
	bird_results.done(function(data) {
	    var birds = data.rows;
	    var len = birds.length;
	    globalData.bird_data = birds;
	    len = birds.length;
	    for (var i=0; i<len; i++) {
		bird = birds[i];
		$("#birdselector").append("<option value=\"" + i + "\">" + bird.bird_name + "</option>");
	    }
	    drawCharts("colony_dist", birds[0]);
	});
    }
);

/* ------------
 * Inititate global stuff
 * ------------
*/

var globalData = {}

/* ------------
 * set some globals
 * These calendars need to be initialized before running the create functions.
 * That's because the create functions are also used for updating the calendars
 * so they start with cal.destroy(), but therefore, cal should already be
 * a calendar.
 * ------------
*/

var hourcal = new CalHeatMap();
hourcal.init({itemSelector: "#hour-month-heatmap"});
//drawCharts("colony_dist", {"bird_name": "Eric", "colony_longitude": 3.182875, "colony_latitude": 51.340768, "device_info_serial": 703});

/* ------------
 * Charting functions
 * ------------
*/

function drawCharts (data_type, bird_data) {
    insertBirdData(bird_data);
    if (data_type === "colony_dist") {
	var hour_month_cartodbdata = fetchTrackingData_byDayHour(bird_data.device_info_serial, "point("+ bird_data.colony_longitude + "%20" + bird_data.colony_latitude + ")", "");
    } else if (data_type === "dist_trav") {
	var hour_month_cartodbdata = fetchTravelledDist_byHour(bird_data.device_info_serial, "");
    }
    hour_month_cartodbdata.done(function (data) {
	globalData.hour_month_heatdata = toCalHeatmap(data);
	globalData.hour_month_linedata = toNvd3Linedata(data);
	var values = globalData.hour_month_linedata[0].values;
	var min_timestamp = values[0].x;
	var max_timestamp = values[values.length - 1].x;
	var startdate = new Date(min_timestamp);
	drawHourCalHeatmap("#hour-month-heatmap", startdate, globalData.hour_month_heatdata, bird_data);
	drawHourLineChart(globalData.hour_month_linedata, min_timestamp, max_timestamp);
    });

    if (data_type === "colony_dist") {
	var day_month_cartodbdata = fetchTrackingData_byDay(bird_data.device_info_serial, "point("+ bird_data.colony_longitude + "%20" + bird_data.colony_latitude + ")", "");
    } else if (data_type === "dist_trav") {
	var day_month_cartodbdata = fetchTravelledDist_byDay(bird_data.device_info_serial, "");
    }
    setBirdsLayer(window.map, bird_data.device_info_serial, "", "");

}

function drawHourCalHeatmap(element, startdate, data, bird_data) {
    hourcal = hourcal.destroy(function () {
	hourcal = new CalHeatMap();
	hourcal.init({
	    onComplete: addEvents,
	    domain: "month",
	    subDomain: "x_hour",
	    start: startdate,
	    cellSize: 6.5,
	    rowLimit: 24,
	    verticalOrientation: false,
	    itemSelector: element,
	    domainMargin: 10,
	    itemName: ['kilometer', 'kilometers'],
	    displayLegend: true,
	    legend: [0.05, 1, 5, 10, 50, 100],
	    legendColors: {
		range: ["#C2F2C3", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#005a32", "#000000"],
		empty: "#CFCFCF"
	    },
	    legendCellSize: 20,
	    legendCellPadding: 4,
	    data: data,
	    onClick: function(date, distance) {
		start_of_that_day = new Date(date.getFullYear(), date.getMonth(), date.getDate());
		clicked_date_timestamp = start_of_that_day.getTime();
		next_date_timestamp = clicked_date_timestamp + (24 * 60 * 60 * 1000);
		next_date = new Date(next_date_timestamp);
		drawHourLineChart(globalData.hour_month_linedata, clicked_date_timestamp, next_date_timestamp);
		setBirdsLayer(window.map, bird_data.device_info_serial, start_of_that_day, next_date);
	    }
	});
    });
}

function drawHourLineChart(data, focus_min, focus_max) {
    nv.addGraph(function() {
	chart = nv.models.lineWithFocusChart();

	chart.xAxis
	    .axisLabel('Time')
	    .tickFormat(function(d) {return d3.time.format('%d/%m %Hh')(new Date(d)); });

	chart.x2Axis
	    .axisLabel('Time')
	    .ticks(20)
	    .tickFormat(function(d) {   return d3.time.format('%d/%m')(new Date(d)); });

        chart.yAxis
	    .axisLabel('Distance from nest (km)')
	    .tickFormat(d3.format('.02f'))

        chart.y2Axis
	    .axisLabel('Distance from nest (km)')
	    .tickFormat(d3.format('.02f'))

	chart.showLegend(false);
	chart.brushExtent([focus_min, focus_max]);

	d3.select('#linechart svg')
	    .datum(data)
	    .transition().duration(500)
	    .call(chart);

        nv.utils.windowResize(function() { d3.select('#linechart svg').call(chart) });

	return chart;
    });
}

// ----- End of Charting functions ----- //

/* ------------
 * Add events to buttons
 * ------------
*/

// Go button
$("#gobutton").on("click", function(event) {
    globalData.datatype = "total_dist";
    var bird_index = $("#birdselector").val();
    var bird = globalData.bird_data[bird_index];
    var data_type = $("#dataselector").val();
    drawCharts(data_type, bird);
});

// Calendar navigation
$("#cal-next").on("click", function(event) {
    hourcal.next();
});

$("#cal-previous").on("click", function(event) {
    hourcal.previous();
});

// Calendar tabs
$("#show-dist-col").on("click", function(event) {
    $(this).attr("class", "tab active");
    $("#show-dist-trav").attr("class", "tab inactive");
});

$("#show-dist-trav").on("click", function(event) {
    $(this).attr("class", "tab active");
    $("#show-dist-col").attr("class", "tab inactive");
});

/* ------------
 * Add events to cal-heatmap graph-label
 * This function is called as call-back function
 * after the calendar data is loaded.
 * ------------
*/
function addEvents() {
    var bird_index = $("#birdselector").val();
    var bird = globalData.bird_data[bird_index];
    $(".graph-label").on("click", function(event) {
	// get class of parent DOM object. This should be "graph-domain m_A y_B"
	// Where A and B are month and year respectively.
	var pclasses = $(this).parent().attr("class").split(" ");
	var month_nr = parseInt(pclasses[1].split("_")[1]);
	var year_nr = parseInt(pclasses[2].split("_")[1]);
	var month_index = month_nr - 1;
	if (month_nr == 12) {
	    var next_month_index = 0;
	    var next_year = year_nr + 1;
	}
        else {
	    var next_month_index = month_index + 1;
	    var next_year = year_nr;
	}
	var startdate = new Date(year_nr, month_index, 1);
	var enddate = new Date(next_year, next_month_index, 1);
	drawHourLineChart(globalData.hour_month_linedata, startdate.getTime(), enddate.getTime());
	setBirdsLayer(window.map, bird.device_info_serial, startdate, enddate);
    });
}

/* ------------
 * Insert bird data in web page
 * ------------
*/
function insertBirdData(bird_data) {
    $("#name-text").text(" " + bird_data.bird_name);
    $("#species-text").text(" " + bird_data.scientific_name);
    $("#sex-text").text(" " + bird_data.sex);
    $("#max-speed-text").text("");
    $("#max-dist-col").text("");
    var speed_result = fetchMaximumSpeed(bird_data.device_info_serial)
    speed_result.done(function (data) {
	$("#max-speed-text").text(" " + data.rows[0].round + " km/h");
    });
    var dist_result = getMaxDistance(bird_data.device_info_serial, bird_data.colony_longitude, bird_data.colony_latitude);
    dist_result.done(function (data) {
	$("#max-dist-col").text(" " + Math.round(data.rows[0].max / 10) / 100 + " km");
    });
}
<commit_msg>Remove commented drawCharts line<commit_after>/* ------------
 * Fill select element with birdnames + draw charts for first bird
 * ------------
*/

$(document).ready(
    function() {
	bird_results = getAllBirdInfo("");
	bird_results.done(function(data) {
	    var birds = data.rows;
	    var len = birds.length;
	    globalData.bird_data = birds;
	    len = birds.length;
	    for (var i=0; i<len; i++) {
		bird = birds[i];
		$("#birdselector").append("<option value=\"" + i + "\">" + bird.bird_name + "</option>");
	    }
	    drawCharts("colony_dist", birds[0]);
	});
    }
);

/* ------------
 * Inititate global stuff
 * ------------
*/

var globalData = {}

/* ------------
 * set some globals
 * These calendars need to be initialized before running the create functions.
 * That's because the create functions are also used for updating the calendars
 * so they start with cal.destroy(), but therefore, cal should already be
 * a calendar.
 * ------------
*/

var hourcal = new CalHeatMap();
hourcal.init({itemSelector: "#hour-month-heatmap"});

/* ------------
 * Charting functions
 * ------------
*/

function drawCharts (data_type, bird_data) {
    insertBirdData(bird_data);
    if (data_type === "colony_dist") {
	var hour_month_cartodbdata = fetchTrackingData_byDayHour(bird_data.device_info_serial, "point("+ bird_data.colony_longitude + "%20" + bird_data.colony_latitude + ")", "");
    } else if (data_type === "dist_trav") {
	var hour_month_cartodbdata = fetchTravelledDist_byHour(bird_data.device_info_serial, "");
    }
    hour_month_cartodbdata.done(function (data) {
	globalData.hour_month_heatdata = toCalHeatmap(data);
	globalData.hour_month_linedata = toNvd3Linedata(data);
	var values = globalData.hour_month_linedata[0].values;
	var min_timestamp = values[0].x;
	var max_timestamp = values[values.length - 1].x;
	var startdate = new Date(min_timestamp);
	drawHourCalHeatmap("#hour-month-heatmap", startdate, globalData.hour_month_heatdata, bird_data);
	drawHourLineChart(globalData.hour_month_linedata, min_timestamp, max_timestamp);
    });

    if (data_type === "colony_dist") {
	var day_month_cartodbdata = fetchTrackingData_byDay(bird_data.device_info_serial, "point("+ bird_data.colony_longitude + "%20" + bird_data.colony_latitude + ")", "");
    } else if (data_type === "dist_trav") {
	var day_month_cartodbdata = fetchTravelledDist_byDay(bird_data.device_info_serial, "");
    }
    setBirdsLayer(window.map, bird_data.device_info_serial, "", "");

}

function drawHourCalHeatmap(element, startdate, data, bird_data) {
    hourcal = hourcal.destroy(function () {
	hourcal = new CalHeatMap();
	hourcal.init({
	    onComplete: addEvents,
	    domain: "month",
	    subDomain: "x_hour",
	    start: startdate,
	    cellSize: 6.5,
	    rowLimit: 24,
	    verticalOrientation: false,
	    itemSelector: element,
	    domainMargin: 10,
	    itemName: ['kilometer', 'kilometers'],
	    displayLegend: true,
	    legend: [0.05, 1, 5, 10, 50, 100],
	    legendColors: {
		range: ["#C2F2C3", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#005a32", "#000000"],
		empty: "#CFCFCF"
	    },
	    legendCellSize: 20,
	    legendCellPadding: 4,
	    data: data,
	    onClick: function(date, distance) {
		start_of_that_day = new Date(date.getFullYear(), date.getMonth(), date.getDate());
		clicked_date_timestamp = start_of_that_day.getTime();
		next_date_timestamp = clicked_date_timestamp + (24 * 60 * 60 * 1000);
		next_date = new Date(next_date_timestamp);
		drawHourLineChart(globalData.hour_month_linedata, clicked_date_timestamp, next_date_timestamp);
		setBirdsLayer(window.map, bird_data.device_info_serial, start_of_that_day, next_date);
	    }
	});
    });
}

function drawHourLineChart(data, focus_min, focus_max) {
    nv.addGraph(function() {
	chart = nv.models.lineWithFocusChart();

	chart.xAxis
	    .axisLabel('Time')
	    .tickFormat(function(d) {return d3.time.format('%d/%m %Hh')(new Date(d)); });

	chart.x2Axis
	    .axisLabel('Time')
	    .ticks(20)
	    .tickFormat(function(d) {   return d3.time.format('%d/%m')(new Date(d)); });

        chart.yAxis
	    .axisLabel('Distance from nest (km)')
	    .tickFormat(d3.format('.02f'))

        chart.y2Axis
	    .axisLabel('Distance from nest (km)')
	    .tickFormat(d3.format('.02f'))

	chart.showLegend(false);
	chart.brushExtent([focus_min, focus_max]);

	d3.select('#linechart svg')
	    .datum(data)
	    .transition().duration(500)
	    .call(chart);

        nv.utils.windowResize(function() { d3.select('#linechart svg').call(chart) });

	return chart;
    });
}

// ----- End of Charting functions ----- //

/* ------------
 * Add events to buttons
 * ------------
*/

// Go button
$("#gobutton").on("click", function(event) {
    globalData.datatype = "total_dist";
    var bird_index = $("#birdselector").val();
    var bird = globalData.bird_data[bird_index];
    var data_type = $("#dataselector").val();
    drawCharts(data_type, bird);
});

// Calendar navigation
$("#cal-next").on("click", function(event) {
    hourcal.next();
});

$("#cal-previous").on("click", function(event) {
    hourcal.previous();
});

// Calendar tabs
$("#show-dist-col").on("click", function(event) {
    $(this).attr("class", "tab active");
    $("#show-dist-trav").attr("class", "tab inactive");
});

$("#show-dist-trav").on("click", function(event) {
    $(this).attr("class", "tab active");
    $("#show-dist-col").attr("class", "tab inactive");
});

/* ------------
 * Add events to cal-heatmap graph-label
 * This function is called as call-back function
 * after the calendar data is loaded.
 * ------------
*/
function addEvents() {
    var bird_index = $("#birdselector").val();
    var bird = globalData.bird_data[bird_index];
    $(".graph-label").on("click", function(event) {
	// get class of parent DOM object. This should be "graph-domain m_A y_B"
	// Where A and B are month and year respectively.
	var pclasses = $(this).parent().attr("class").split(" ");
	var month_nr = parseInt(pclasses[1].split("_")[1]);
	var year_nr = parseInt(pclasses[2].split("_")[1]);
	var month_index = month_nr - 1;
	if (month_nr == 12) {
	    var next_month_index = 0;
	    var next_year = year_nr + 1;
	}
        else {
	    var next_month_index = month_index + 1;
	    var next_year = year_nr;
	}
	var startdate = new Date(year_nr, month_index, 1);
	var enddate = new Date(next_year, next_month_index, 1);
	drawHourLineChart(globalData.hour_month_linedata, startdate.getTime(), enddate.getTime());
	setBirdsLayer(window.map, bird.device_info_serial, startdate, enddate);
    });
}

/* ------------
 * Insert bird data in web page
 * ------------
*/
function insertBirdData(bird_data) {
    $("#name-text").text(" " + bird_data.bird_name);
    $("#species-text").text(" " + bird_data.scientific_name);
    $("#sex-text").text(" " + bird_data.sex);
    $("#max-speed-text").text("");
    $("#max-dist-col").text("");
    var speed_result = fetchMaximumSpeed(bird_data.device_info_serial)
    speed_result.done(function (data) {
	$("#max-speed-text").text(" " + data.rows[0].round + " km/h");
    });
    var dist_result = getMaxDistance(bird_data.device_info_serial, bird_data.colony_longitude, bird_data.colony_latitude);
    dist_result.done(function (data) {
	$("#max-dist-col").text(" " + Math.round(data.rows[0].max / 10) / 100 + " km");
    });
}
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose');

// Compile Schema into Model here
var honors = mongoose.model('honors');

var modelClass = require('../modelClass');
var renderModel = new modelClass.RenderModel( honors, 'honors/honors.tex', 'honors/na.tex');

var is = require('is-js');

/*
will explicitly populate the report with
the data you provide
*/
renderModel.setDebugPopulate( false, {
	info: 'I received the following honors...'
});

/*
will explicitly print the N/A latex
to the screen for debugging purposes
*/
renderModel.isDebugNull = false;

/*
render function that finds the obj in the database
and converts it into latex.
*/
module.exports.render = function(req, callback) {
	renderModel.render(req, callback);
};

module.exports.submit = function(req, callback) {

	if (is.empty(req.body.honors)) return callback(null, null);

	var honors = new honors({
		info: req.body.honors.info,
		user: req.user
	});

	honors.save(function(err) {
		callback(err, honors);
	});
};
<commit_msg>Update renderHonors.js<commit_after>'use strict';

var mongoose = require('mongoose');

// Compile Schema into Model here
var honors = mongoose.model('honors');

var modelClass = require('../modelClass');
var renderModel = new modelClass.RenderModel( honors, 'honors/honors.tex', 'honors/na.tex');

var is = require('is-js');

/*
will explicitly populate the report with
the data you provide
*/
renderModel.setDebugPopulate( false, {
	info: 'I received the following honors...'
});

/*
will explicitly print the N/A latex
to the screen for debugging purposes
*/
renderModel.isDebugNull = false;

/*
render function that finds the obj in the database
and converts it into latex.
*/
module.exports.render = function(req, callback) {
	renderModel.render(req, callback);
};

module.exports.submit = function(req, callback) {

	if (is.empty(req.body.honors)) return callback(null, null);

	var honor = new honors({
		info: req.body.honors.info,
		user: req.user
	});

	honor.save(function(err) {
		callback(err, honor);
	});
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  ScrollView,
  Text,
  StyleSheet,
  TouchableOpacity
} from 'react-native';

class DashboardView extends Component {
  static navigationOptions = {
    title: 'Exams',
    header: {
      style: {
        backgroundColor: '#15396a'
      },
      titleStyle: {
        color: 'white'
      }
    }
  };

  showExam(exam) {
    this.props.navigation.navigate('Exam', { exam: exam });
  }

  render() {
    return (
      <ScrollView style={styles.wrapper} contentInset={{top: 0, bottom: 100}}>
        <TouchableOpacity onPress={this.showExam.bind(this, "trauma")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Patient Assessment/Management - Trauma</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "medical")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Patient Assessment/Management - Medical</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "bvm")} style={styles.borderBottom}>
          <Text style={styles.examLink}>BVM Ventilation Of An Apneic Adult Patient</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "oxygen")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Oxygen Administration By Non-Rebreather Mask</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "seatedSpine")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Spinal Immobilization (Seated Patient)</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "supineSpine")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Spinal Immobilization (Supine Patient)</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "bleeding")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Bleeding Control/Shock Management</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "cardiac")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Cardiac Arrest Management/AED</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "joint")} style={styles.borderBottom}>
          <Text style={styles.examLink}>Joint Immobilization</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={this.showExam.bind(this, "longBone")}>
          <Text style={styles.examLink}>Long Bone Immobilization</Text>
        </TouchableOpacity>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: 'white',
    height: '100%',
    paddingTop: 8,
    paddingLeft: 6,
    paddingRight: 6
  },
  borderBottom: {
    borderBottomWidth: 1,
    borderColor: 'lightgray'
  },
  examLink: {
    fontSize: 20,
    marginTop: 10,
    marginBottom: 10
  }
});

export default DashboardView;
<commit_msg>map exams to links<commit_after>import React, { Component } from 'react';
import {
  ScrollView,
  Text,
  StyleSheet,
  TouchableOpacity
} from 'react-native';

import exams from '../../data/exams';

class DashboardView extends Component {
  static navigationOptions = {
    title: 'Exams',
    header: {
      style: {
        backgroundColor: '#15396a'
      },
      titleStyle: {
        color: 'white'
      }
    }
  };

  _showExam(exam) {
    this.props.navigation.navigate('Exam', { exam: exam });
  }

  render() {
    return (
      <ScrollView style={styles.wrapper} contentInset={{top: 0, bottom: 100}}>
        {exams.map((exam, idx) => {
          return (
            <TouchableOpacity key={idx} onPress={this._showExam.bind(this, exam.examID)} style={styles.borderBottom}>
              <Text style={styles.examLink}>{exam.title}</Text>
            </TouchableOpacity>
          );
        })}
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: 'white',
    height: '100%',
    paddingTop: 8,
    paddingLeft: 6,
    paddingRight: 6
  },
  borderBottom: {
    borderBottomWidth: 1,
    borderColor: 'lightgray'
  },
  examLink: {
    fontSize: 20,
    marginTop: 10,
    marginBottom: 10
  }
});

export default DashboardView;
<|endoftext|>


<commit_before>//  React and its typechecking
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import _ from 'lodash'
//  Redux utils
import { compose } from 'redux'
import { connect } from 'react-redux'
import { connectRequest } from 'redux-query'
//  Our API services
import api from '../../../services'

import { Link } from 'react-router'
import {
  Spin,
  Table,
  Progress,
  Badge,
  Input,
  Button,
  Icon
} from 'antd'

import SubTable from './SubTable/SubTable'

//  Status indicator mapping for badge components
const indicators = {
  'In Review': 'default',
  'Fully Funded': 'success',
  'Partially Funded': 'success',
  'Revisions Requested': 'warning',
  Denied: 'error'
}
const currency = number =>
  number.toLocaleString('en-US', {
    style: 'currency',
    currency: 'USD'
  })

const expandedRowRender = (record, i) => <SubTable
  contacts={record.proposal && record.proposal.contacts}
  manifest={record.manifest}
  report={record.manifest && record.manifest.report}
/>

//  Import modular CSS. Needs to run through JS because styles are hashed.
import styles from './Dashboard.css'
//  This is a decorator, a function that wraps another class (which in JS is essentially a func)
@compose(
  connect((state, props) => ({
    awards: state.db.decisions,
    enums: state.db.config && state.db.config.enums,
    screen: state.screen,
    user: state.user
  })),
  connectRequest(
    () => api.get('decisions', {
      where: { approved: true },
      join: ['manifest.report', 'proposal.contacts']
    })
  )
)
class Dashboard extends React.Component {
  static propTypes = {
    awards: PropTypes.array,
    screen: PropTypes.object,
    user: PropTypes.object
  }
  constructor (props) {
    super(props)
    const { awards } = this.props
    this.state = {
      awards,
      filterDropdownVisible: false,
      searchText: '',
      filtered: false
    }
  }
  componentWillReceiveProps (nextProps) {
    const { awards } = nextProps
    if (awards) this.setState({ awards })
  }

  onInputChange = searchText => this.setState({ searchText })
  onSearch = () => {
    const { searchText } = this.state
    const { awards } = this.props
    const reg = new RegExp(searchText, 'gi')
    this.setState({
      filterDropdownVisible: false,
      filtered: !!searchText,
      awards: awards
        .map(record => {
          const match = record.proposal.title.match(reg)
          if (!match) return null
          return {
            ...record,
            title: (

                {record.proposal.title
                  .split(reg).map((text, i) => i > 0
                      ? [({match[0]}), text]
                      : text
                  )}

            )
          }
        })
        .filter(record => !!record)
    })
  }
  //  Shorthand assignment of variables when defining render
  render (
    { enums, screen } = this.props,
    //  Proposals go through state since we filter
    { awards } = this.state
  ) {
    //  Create an array of years for select boxes
    const years = _.range(
      2000,
      new Date().getFullYear() + 1
    )
    const columns = [
      {
        title: 'ID',
        dataIndex: 'proposal.number',
        key: 'proposal.number',
        render: (text, record) => (
          {`${record.proposal.year}-${record.proposal.number}`}
        ),
        sorter: (a, b) =>
          a.proposal.year * a.proposal.number - b.proposal.year * b.proposal.number,
        filters: years.map((year, i) => {
          return { text: year, value: year }
        }),
        onFilter: (value, record) =>
          record.proposal.year.toString().includes(value),
        width: 90
      }, {
        title: 'Q',
        dataIndex: 'proposal.quarter',
        key: 'quarter',
        render: text => {text.substr(0, 2) || ''},
        filters: [
          { text: 'Autumn', value: 'Autumn' },
          { text: 'Fall', value: 'Fall' },
          { text: 'Spring', value: 'Spring' },
          { text: 'Summer', value: 'Summer' }
        ],
        onFilter: (value, record) => record.proposal.quarter.includes(value),
        width: 50
      }, {
        title: 'Type',
        dataIndex: 'manifest.type',
        key: 'manifest.type',
        render: text => {_.capitalize(text)},
        filters: [
          { text: 'Original Proposal', value: 'Original' },
          { text: 'Supplemental Award', value: 'Supplemental' },
          { text: 'Partial Funding', value: 'Partial' }
        ],
        onFilter: (value, record) => record.manifest.type.includes(value),
        width: 120
      }, {
        title: 'Title',
        dataIndex: 'proposal.title',
        key: 'proposal.title',
        render: (text, record) => (

            <Link to={`/proposals/${record.proposal.year}/${record.proposal.number}`}>
              {record.proposal.title}
            </Link>

            {record.proposal.category}

        ),
        filterDropdown: (
          <Input
            ref={ele => this.searchInput = ele}
            placeholder='Search title'
            value={this.state.searchText}
            onChange={(e) => this.onInputChange(e.target.value)}
            onPressEnter={this.onSearch}
          />
        ),
        filterIcon: <Icon type='search' style={{ color: this.state.filtered ? '#108ee9' : '#aaa' }} />,
        filterDropdownVisible: this.state.filterDropdownVisible,
        onFilterDropdownVisibleChange: visible => {
          this.setState(
            { filterDropdownVisible: visible },
            () => this.searchInput.focus()
          )
        }
      },
      {
        title: 'Organization',
        dataIndex: 'proposal.organization',
        key: 'proposal.organization',
        render: (text, record) => (

            {text}

            {record.proposal.budget}

        ),
        filters: enums
          ? Object.keys(enums.organizations).map(org => {
            return { text: org, value: org }
          })
          : [],
        onFilter: (value, record) => record.proposal.organization === value
      },
      {
        title: 'Category',
        dataIndex: 'proposal.category',
        key: 'proposal.category',
        filters: enums
          ? enums.categories.map(category => {
            return { text: category, value: category }
          })
          : [],
        onFilter: (value, record) => record.proposal.category === value,
        width: 150
      }, {
        title: 'Awarded',
        dataIndex: 'proposal.received',
        key: 'proposal.received',
        //  FIXME: Use manifest.total instead, using decision to qualify if it's N/A or not.
        render: (text, record) => (

            {text ? currency(text) : '$0'}

            <Badge status={indicators[record.proposal.status] || 'default'} text={record.proposal.status} />

        ),
        sorter: (a, b) => a.proposal.received - b.proposal.received
      }, {
        title: 'Spent',
        dataIndex: 'manifest.report.total',
        key: 'manifest.report.total',
        render: (text, record) => {
          let percentage = record.manifest.report.total > 0
            ? Number.parseInt(record.manifest.report.total / record.proposal.received * 100)
            : 0
          // let percentage = Number.parseInt(record.proposal.received / record.manifest.report.total)
          if (Number.isNaN(percentage)) percentage = 0
          else if (percentage > 100) percentage = 100
          return (

              {text ? currency(text) : 'N/A'}

                <Progress
                  percent={percentage}
                  strokeWidth={5} />

          )
        },
        sorter: (a, b) => a.manifest.report.total - b.manifest.report.total
      }, {
        title: 'Budget #',
        dataIndex: 'manifest.report.budget',
        key: 'manifest.report.budget',
        width: 100
      }, {
        title: 'Report Due',
        dataIndex: 'manifest.report.due',
        key: 'manifest.report.due',
        render: (text, record) => (

            {text
              ? new Date(text)
                .toLocaleDateString('en-US', { timeZone: 'UTC' })
              : 'N/A'
            }

        ),
        sorter: (a, b) => Date.parse(a.manifest.report.due) - Date.parse(b.manifest.report.due),
        width: 130
      }
    ]
    return (

Budgeting Dashboard

        <Helmet title='Dashboard' />
        {!awards
            ? <Spin size='large' tip='Loading...' />
            :
 record._id}
              expandedRowRender={expandedRowRender}
            />
            }

    )
  }
}
export default Dashboard
<commit_msg>Bugfixes to dashboard.<commit_after>//  React and its typechecking
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import _ from 'lodash'
//  Redux utils
import { compose } from 'redux'
import { connect } from 'react-redux'
import { connectRequest } from 'redux-query'
//  Our API services
import api from '../../../services'

import { Link } from 'react-router'
import {
  Spin,
  Table,
  Progress,
  Badge,
  Input,
  Button,
  Icon
} from 'antd'

import SubTable from './SubTable/SubTable'

//  Status indicator mapping for badge components
const indicators = {
  'In Review': 'default',
  'Fully Funded': 'success',
  'Partially Funded': 'success',
  'Revisions Requested': 'warning',
  Denied: 'error'
}
const currency = number =>
  number.toLocaleString('en-US', {
    style: 'currency',
    currency: 'USD'
  })

const expandedRowRender = (record, i) => <SubTable
  contacts={record.proposal && record.proposal.contacts}
  manifest={record.manifest}
  report={record.manifest && record.manifest.report}
/>

//  Import modular CSS. Needs to run through JS because styles are hashed.
import styles from './Dashboard.css'
//  This is a decorator, a function that wraps another class (which in JS is essentially a func)
@compose(
  connect((state, props) => ({
    awards: state.db.decisions,
    enums: state.db.config && state.db.config.enums,
    screen: state.screen,
    user: state.user
  })),
  connectRequest(
    () => api.get('decisions', {
      where: { approved: true },
      join: ['manifest.report', 'proposal.contacts']
    })
  )
)
class Dashboard extends React.Component {
  static propTypes = {
    awards: PropTypes.array,
    screen: PropTypes.object,
    user: PropTypes.object
  }
  constructor (props) {
    super(props)
    const { awards } = this.props
    this.state = {
      awards,
      filterDropdownVisible: false,
      searchText: '',
      filtered: false
    }
  }
  componentWillReceiveProps (nextProps) {
    const { awards } = nextProps
    if (awards) this.setState({ awards })
  }

  onInputChange = searchText => this.setState({ searchText })
  onSearch = () => {
    const { searchText } = this.state
    const { awards } = this.props
    const reg = new RegExp(searchText, 'gi')
    this.setState({
      filterDropdownVisible: false,
      filtered: !!searchText,
      awards: awards
        .map(record => {
          const match = record.proposal.title.match(reg)
          if (!match) return null
          return {
            ...record,
            title: (

                {record.proposal.title
                  .split(reg).map((text, i) => i > 0
                      ? [({match[0]}), text]
                      : text
                  )}

            )
          }
        })
        .filter(record => !!record)
    })
  }
  //  Shorthand assignment of variables when defining render
  render (
    { enums, screen } = this.props,
    //  Proposals go through state since we filter
    { awards } = this.state
  ) {
    //  Create an array of years for select boxes
    const years = _.range(
      2000,
      new Date().getFullYear() + 1
    )
    const columns = [
      {
        title: 'ID',
        dataIndex: 'proposal.number',
        key: 'proposal.number',
        render: (text, record) => (
          {`${record.proposal.year}-${record.proposal.number}`}
        ),
        sorter: (a, b) =>
          a.proposal.year * a.proposal.number - b.proposal.year * b.proposal.number,
        filters: years.map((year, i) => {
          return { text: year, value: year }
        }),
        onFilter: (value, record) =>
          record.proposal.year.toString().includes(value),
        width: 90
      }, {
        title: 'Q',
        dataIndex: 'proposal.quarter',
        key: 'quarter',
        render: text => {text.substr(0, 2) || ''},
        filters: [
          { text: 'Autumn', value: 'Autumn' },
          { text: 'Fall', value: 'Fall' },
          { text: 'Spring', value: 'Spring' },
          { text: 'Summer', value: 'Summer' }
        ],
        onFilter: (value, record) => record.proposal.quarter.includes(value),
        width: 50
      }, {
        title: 'Type',
        dataIndex: 'manifest.type',
        key: 'manifest.type',
        render: text => {_.capitalize(text)},
        filters: [
          { text: 'Original Proposal', value: 'Original' },
          { text: 'Supplemental Award', value: 'Supplemental' },
          { text: 'Partial Funding', value: 'Partial' }
        ],
        onFilter: (value, record) => record.manifest.type.includes(value),
        width: 120
      }, {
        title: 'Title',
        dataIndex: 'proposal.title',
        key: 'proposal.title',
        render: (text, record) => (

            <Link to={`/proposals/${record.proposal.year}/${record.proposal.number}`}>
              {record.proposal.title}
            </Link>

        ),
        filterDropdown: (
          <Input
            ref={ele => this.searchInput = ele}
            placeholder='Search title'
            value={this.state.searchText}
            onChange={(e) => this.onInputChange(e.target.value)}
            onPressEnter={this.onSearch}
          />
        ),
        filterIcon: <Icon type='search' style={{ color: this.state.filtered ? '#108ee9' : '#aaa' }} />,
        filterDropdownVisible: this.state.filterDropdownVisible,
        onFilterDropdownVisibleChange: visible => {
          this.setState(
            { filterDropdownVisible: visible },
            () => this.searchInput.focus()
          )
        }
      },
      {
        title: 'Organization',
        dataIndex: 'proposal.organization',
        key: 'proposal.organization',
        render: (text, record) => (

            {text}

            {record.proposal.budget}

        ),
        filters: enums
          ? Object.keys(enums.organizations).map(org => {
            return { text: org, value: org }
          })
          : [],
        onFilter: (value, record) => record.proposal.organization === value
      },
      {
        title: 'Category',
        dataIndex: 'proposal.category',
        key: 'proposal.category',
        filters: enums
          ? enums.categories.map(category => {
            return { text: category, value: category }
          })
          : [],
        onFilter: (value, record) => record.proposal.category === value,
        width: 150
      }, {
        title: 'Awarded',
        dataIndex: 'manifest.total',
        key: 'manifest.total',
        render: (text, record) => (

            {text ? currency(text) : '$0'}

            <Badge status={indicators[record.proposal.status] || 'default'} text={record.proposal.status} />

        ),
        width: 120,
        sorter: (a, b) => a.manifest.total - b.manifest.total
      }, {
        title: 'Spent',
        dataIndex: 'manifest.report.total',
        key: 'manifest.report.total',
        render: (text, record) => {
          // let percentage = record.manifest.report.total > 0
          //   ? Number.parseInt(record.manifest.report.total / record.proposal.received * 100)
          //   : 0
          // let percentage = Number.parseInt(text / record.manifest.total) * 100
          let percentage = Number.parseInt(text / record.manifest.total * 100)
          // console.warn(record.manifest.report.total, record.proposal.received, percentage)
          if (Number.isNaN(percentage)) percentage = 0
          // else if (percentage > 100) percentage = 100
          return (

              {text ? currency(text) : 'N/A'}

                <Progress
                  percent={percentage <= 100 ? percentage : 100}
                  status={percentage <= 100 ? 'success' : 'exception'}
                  strokeWidth={5} />

          )
        },
        width: 80,
        sorter: (a, b) => a.manifest.report.total - b.manifest.report.total,
        filters: [
          { text: 'No Reporting', value: 'No Reporting' },
          { text: 'In Budget', value: 'In Budget' },
          { text: 'Over Budget', value: 'Over Budget' }
        ],
        onFilter: (value, record) => {
          let percentage = Number.parseInt(record.manifest.report.total / record.manifest.total * 100)
          switch (value) {
            case 'No Reporting':
              return Number.isNaN(percentage)
            case 'In Budget':
              return percentage <= 100
            case 'Over Budget':
              return percentage > 100
            default:
              return true
          }
        }
      }, {
        title: 'Budget',
        dataIndex: 'manifest.report.budget',
        key: 'manifest.report.budget',
        width: 80
      }, {
        title: 'Due',
        dataIndex: 'manifest.report.due',
        key: 'manifest.report.due',
        render: (text, record) => (

            {text
              ? new Date(text)
                .toLocaleDateString('en-US', { timeZone: 'UTC' })
              : 'N/A'
            }

        ),
        sorter: (a, b) => Date.parse(a.manifest.report.due) - Date.parse(b.manifest.report.due),
        width: 100
      }
    ]
    return (

Budgeting Dashboard

        <Helmet title='Dashboard' />
        {!awards
            ? <Spin size='large' tip='Loading...' />
            :
 record._id}
              expandedRowRender={expandedRowRender}
            />
            }

    )
  }
}
export default Dashboard
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict'

const log = require("../../net2/logger")('diag');

const express = require('express');
const https = require('https');
const qs = require('querystring');
const path = require('path');

const port = 8835

const Promise = require('bluebird')

const async = require('asyncawait/async');
const await = require('asyncawait/await');

const exec = require('child-process-promise').exec
const fs = require('fs')
Promise.promisifyAll(fs)

const VIEW_PATH = 'view';
const STATIC_PATH = 'static';

const errorCodes = {
  "firekick": 101,
  "firemain": 102,
  "fireapi": 103,
  "firemon": 104,
  "memory": 201,
  "database": 301,
  "gid": 401,
  "ip": 501
}

class App {
  constructor() {
    this.app = express();

    this.app.engine('mustache', require('mustache-express')());
    this.app.set('view engine', 'mustache');

    this.app.set('views', path.join(__dirname, VIEW_PATH));
    //this.app.disable('view cache'); //for debug only

    this.routes();
  }

  getSystemTime() {
    return new Date() / 1000
  }

  getSystemServices() {
    const fireKickCmd = "systemctl is-active firekick"
    const fireMainCmd = "systemctl is-active firemain"
    const fireApiCmd = "systemctl is-active fireapi"
    const fireMonCmd = "systemctl is-active firemon"

    return async(() => {
      try {
        await (exec(fireKickCmd))
      } catch(err) {
        log.error("firekick is not alive", err, {})
        return errorCodes.firekick
      }

      try {
        await (exec(fireMainCmd))
      } catch(err) {
        log.error("firemain is not alive", err, {})
        return errorCodes.firemain
      }

      try {
        await (exec(fireApiCmd))
      } catch(err) {
        log.error("fireapi is not alive", err, {})
        return errorCodes.fireapi
      }

      try {
        await (exec(fireMonCmd))
      } catch(err) {
        log.error("firemon is not alive", err, {})
        return errorCodes.firemon
      }

      return 0
    })()
  }

  getCloudConnectivity() {
    return this.connected
  }

  getSystemMemory() {
    return async(() => {
      const result = await (exec("free -m"))
      const stdout = result.stdout
      const lines = stdout.split(/\n/g)

      for(var i = 0; i < lines.length; i++) {
        lines[i] = lines[i].split(/\s+/)
      }

      const allMem = parseInt(lines[1][1])

      if(allMem > 490) {
        return 0
      } else {
        return errorCodes.memory
      }
    })()
  }

  getNodeVersion() {
    return process.version
  }

  getUptime() {
    return require('os').uptime()
  }

  getDatabase() {
    return async(() => {
      try {
        await (exec("systemctl is-active redis-server"))
      } catch(err) {
        log.error("Failed to check database", err, {})
        return errorCodes.database
      }

      return 0
    })()
  }

  getGID() {
    return async(() => {
      try {
        const gid = await (exec("redis-cli hget sys:ept gid"))
        return gid && gid.stdout && gid.stdout.substring(0,8)
      } catch(err) {
        log.error("Failed to get gid", err, {})
        return null
      }
    })()
  }

  getFullGID() {
    return async(() => {
      try {
        const gid = await (exec("redis-cli hget sys:ept gid"))
        return gid && gid.stdout
      } catch(err) {
        log.error("Failed to get gid", err, {})
        return null
      }
    })()
  }

  getPrimaryIP() {
    return async(() => {
      const eth0s = require('os').networkInterfaces()["eth0"]

      if(eth0s) {
        for (let index = 0; index < eth0s.length; index++) {
          const eth0 = eth0s[index]
          if(eth0.family == "IPv4" && eth0.address != "192.168.218.1") {
            return eth0.address
          }
        }
      }

      return ''
    })()
  }

  routes() {
    this.router = express.Router();

    this.app.use('/' + VIEW_PATH, this.router);
    this.app.use('/' + STATIC_PATH, express.static(path.join(__dirname, STATIC_PATH)));

    this.app.use('/log', (req, res) => {
      const filename = "/home/pi/logs/FireKick.log"
      async(() => {
        const gid = await (this.getFullGID())
        await (fs.accessAsync(filename, fs.constants.F_OK))
        //tail -n 1000 /home/pi/logs/FireKick.log | sed -r   "s/0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"
        const result = await (exec(`tail -n 1000 ${filename}`)).stdout
        let lines = result.split("\n")
        lines = lines.map((originLine) => {
          let line = originLine
          line = line.replace(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]/, '')
          line = line.replace(new RegExp(gid, "g"), "<****gid****>")
          line = line.replace(/type in this key:.*$/g, "type in this key: <****key****>")
          line = line.replace(/Inviting .{10,40} to group/g, "Inviting <****rid****> to group")
          line = line.replace(/Set SYS:EPT null OK.*/, "Set SYS:EPT null OK <****token****>")
          return line
        })
        res.send(lines.join("\n"))
      })().catch((err) => {
        log.error("Failed to fetch log", err, {})
        res.status(404).send('')
      })
    })

    this.app.use('*', (req, res) => {
      log.info("Got a request in *")

      return async(() => {
        const time = this.getSystemTime()
        const ip = await (this.getPrimaryIP())
        const gid = await (this.getGID())
        const database = await(this.getDatabase())
        const uptime = this.getUptime()
        const nodeVersion = this.getNodeVersion()
        const memory = await(this.getSystemMemory())
        const connected = this.getCloudConnectivity()
        const systemServices = await(this.getSystemServices())
        const expireDate = this.expireDate

        let success = true
        let values = {
          now: new Date() / 1000
        }

        if(!this.broadcastInfo) {
          values.err_binding = true
          success = false
        }

        if(ip == "") {
          values.err_ip = true
          success = false
        } else {
          values.ip = ip
        }

        if(gid == null) {
          values.err_config = true
          success = false
        }

        if(database != 0) {
          values.err_database = true
          success = false
        }

        if(memory != 0) {
          values.err_memory = true
          success = false
        }

        if(connected != true) {
          values.err_cloud = true
          success = false
        }

        if(systemServices != 0) {
          values.err_service = true
          success = false
        }

        values.success = success

        res.render('welcome', values)

      })().catch((err) => {
        log.error("Failed to process request", err, {})
        res.status(500).send({})
      })
    })
  }

  start() {
    this.app.listen(port, () => log.info(`Httpd listening on port ${port}!`));
  }
}

module.exports = App
<commit_msg>bug fix<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict'

const log = require("../../net2/logger")('diag');

const express = require('express');
const https = require('https');
const qs = require('querystring');
const path = require('path');

const port = 8835

const Promise = require('bluebird')

const async = require('asyncawait/async');
const await = require('asyncawait/await');

const exec = require('child-process-promise').exec
const fs = require('fs')
Promise.promisifyAll(fs)

const VIEW_PATH = 'view';
const STATIC_PATH = 'static';

const errorCodes = {
  "firekick": 101,
  "firemain": 102,
  "fireapi": 103,
  "firemon": 104,
  "memory": 201,
  "database": 301,
  "gid": 401,
  "ip": 501
}

class App {
  constructor() {
    this.app = express();

    this.app.engine('mustache', require('mustache-express')());
    this.app.set('view engine', 'mustache');

    this.app.set('views', path.join(__dirname, VIEW_PATH));
    //this.app.disable('view cache'); //for debug only

    this.routes();
  }

  getSystemTime() {
    return new Date() / 1000
  }

  getSystemServices() {
    const fireKickCmd = "systemctl is-active firekick"
    const fireMainCmd = "systemctl is-active firemain"
    const fireApiCmd = "systemctl is-active fireapi"
    const fireMonCmd = "systemctl is-active firemon"

    return async(() => {
      try {
        await (exec(fireKickCmd))
      } catch(err) {
        log.error("firekick is not alive", err, {})
        return errorCodes.firekick
      }

      try {
        await (exec(fireMainCmd))
      } catch(err) {
        log.error("firemain is not alive", err, {})
        return errorCodes.firemain
      }

      try {
        await (exec(fireApiCmd))
      } catch(err) {
        log.error("fireapi is not alive", err, {})
        return errorCodes.fireapi
      }

      try {
        await (exec(fireMonCmd))
      } catch(err) {
        log.error("firemon is not alive", err, {})
        return errorCodes.firemon
      }

      return 0
    })()
  }

  getCloudConnectivity() {
    return this.connected
  }

  getSystemMemory() {
    return async(() => {
      const result = await (exec("free -m"))
      const stdout = result.stdout
      const lines = stdout.split(/\n/g)

      for(var i = 0; i < lines.length; i++) {
        lines[i] = lines[i].split(/\s+/)
      }

      const allMem = parseInt(lines[1][1])

      if(allMem > 490) {
        return 0
      } else {
        return errorCodes.memory
      }
    })()
  }

  getNodeVersion() {
    return process.version
  }

  getUptime() {
    return require('os').uptime()
  }

  getDatabase() {
    return async(() => {
      try {
        await (exec("systemctl is-active redis-server"))
      } catch(err) {
        log.error("Failed to check database", err, {})
        return errorCodes.database
      }

      return 0
    })()
  }

  getGID() {
    return async(() => {
      try {
        const gid = await (exec("redis-cli hget sys:ept gid"))
        return gid && gid.stdout && gid.stdout.substring(0,8)
      } catch(err) {
        log.error("Failed to get gid", err, {})
        return null
      }
    })()
  }

  getFullGID() {
    return async(() => {
      try {
        const gid = await (exec("redis-cli hget sys:ept gid"))
        return gid && gid.stdout && gid.stdout.replace("\n", "")
      } catch(err) {
        log.error("Failed to get gid", err, {})
        return null
      }
    })()
  }

  getPrimaryIP() {
    return async(() => {
      const eth0s = require('os').networkInterfaces()["eth0"]

      if(eth0s) {
        for (let index = 0; index < eth0s.length; index++) {
          const eth0 = eth0s[index]
          if(eth0.family == "IPv4" && eth0.address != "192.168.218.1") {
            return eth0.address
          }
        }
      }

      return ''
    })()
  }

  routes() {
    this.router = express.Router();

    this.app.use('/' + VIEW_PATH, this.router);
    this.app.use('/' + STATIC_PATH, express.static(path.join(__dirname, STATIC_PATH)));

    this.app.use('/log', (req, res) => {
      const filename = "/home/pi/logs/FireKick.log"
      async(() => {
        const gid = await (this.getFullGID())
        await (fs.accessAsync(filename, fs.constants.F_OK))
        //tail -n 1000 /home/pi/logs/FireKick.log | sed -r   "s/0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"
        const result = await (exec(`tail -n 1000 ${filename}`)).stdout
        let lines = result.split("\n")
        lines = lines.map((originLine) => {
          let line = originLine
          line = line.replace(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]/, '')
          line = line.replace(new RegExp(gid, "g"), "<****gid****>")
          line = line.replace(/type in this key:.*$/g, "type in this key: <****key****>")
          line = line.replace(/Inviting .{10,40} to group/g, "Inviting <****rid****> to group")
          line = line.replace(/Set SYS:EPT.*/, "Set SYS:EPT<****token****>")
          return line
        })
        res.send(lines.join("\n"))
      })().catch((err) => {
        log.error("Failed to fetch log", err, {})
        res.status(404).send('')
      })
    })

    this.app.use('*', (req, res) => {
      log.info("Got a request in *")

      return async(() => {
        const time = this.getSystemTime()
        const ip = await (this.getPrimaryIP())
        const gid = await (this.getGID())
        const database = await(this.getDatabase())
        const uptime = this.getUptime()
        const nodeVersion = this.getNodeVersion()
        const memory = await(this.getSystemMemory())
        const connected = this.getCloudConnectivity()
        const systemServices = await(this.getSystemServices())
        const expireDate = this.expireDate

        let success = true
        let values = {
          now: new Date() / 1000
        }

        if(!this.broadcastInfo) {
          values.err_binding = true
          success = false
        }

        if(ip == "") {
          values.err_ip = true
          success = false
        } else {
          values.ip = ip
        }

        if(gid == null) {
          values.err_config = true
          success = false
        }

        if(database != 0) {
          values.err_database = true
          success = false
        }

        if(memory != 0) {
          values.err_memory = true
          success = false
        }

        if(connected != true) {
          values.err_cloud = true
          success = false
        }

        if(systemServices != 0) {
          values.err_service = true
          success = false
        }

        values.success = success

        res.render('welcome', values)

      })().catch((err) => {
        log.error("Failed to process request", err, {})
        res.status(500).send({})
      })
    })
  }

  start() {
    this.app.listen(port, () => log.info(`Httpd listening on port ${port}!`));
  }
}

module.exports = App
<|endoftext|>


<commit_before>/*
 * Copyright 2008 Google Inc.
 *
 * 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.
 */

/**
 * @fileoverview Definitions for all the extensions over W3C's DOM
 *  specification by WebKit. This file depends on w3c_dom2.js.
 *  All the provided definitions has been type annotated
 *
 * @externs
 */

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.cpp
 */
function MemoryInfo() {};

/** @type {number} */
MemoryInfo.prototype.totalJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.usedJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.jsHeapSizeLimit;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfileNode.idl
 */
function ScriptProfileNode() {};

/** @type {string} */
ScriptProfileNode.prototype.functionName;

/** @type {string} */
ScriptProfileNode.prototype.url;

/** @type {number} */
ScriptProfileNode.prototype.lineNumber;

/** @type {number} */
ScriptProfileNode.prototype.totalTime;

/** @type {number} */
ScriptProfileNode.prototype.selfTime;

/** @type {number} */
ScriptProfileNode.prototype.numberOfCalls;

/** @type {Array.<ScriptProfileNode>} */
ScriptProfileNode.prototype.children;

/** @type {boolean} */
ScriptProfileNode.prototype.visible;

/** @type {number} */
ScriptProfileNode.prototype.callUID;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfile.idl
 */
function ScriptProfile() {};

/** @type {string} */
ScriptProfile.prototype.title;

/** @type {number} */
ScriptProfile.prototype.uid;

/** @type {ScriptProfileNode} */
ScriptProfile.prototype.head;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.cpp
 */
function Console() {};

/**
 * @param {*} condition
 * @param {...*} var_args
 */
Console.prototype.assert = function(condition, var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.error = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.info = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.log = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.warn = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.debug = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.dir = function(value) {};

/**
 * @param {...*} var_args
 */
Console.prototype.dirxml = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.trace = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.count = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.markTimeline = function(value) {};

/**
 * @param {string=} opt_title
 */
Console.prototype.profile = function(opt_title) {};

/** @type {Array.<ScriptProfile>} */
Console.prototype.profiles;

Console.prototype.profileEnd = function() {};

/**
 * @param {string} name
 */
Console.prototype.time = function(name) {};

/**
 * @param {string} name
 */
Console.prototype.timeEnd = function(name) {};

/**
 * @param {*} value
 */
Console.prototype.timeStamp = function(value) {};

Console.prototype.group = function() {};

Console.prototype.groupEnd = function() {};

/** @type {MemoryInfo} */
Console.prototype.memory;

/** @type {Console} */
Window.prototype.console;

/**
 * @type {number}
 * @see http://developer.android.com/reference/android/webkit/WebView.html
 */
Window.prototype.devicePixelRatio;

/** @type {Node} */
Selection.prototype.baseNode;

/** @type {number} */
Selection.prototype.baseOffset;

/** @type {Node} */
Selection.prototype.extentNode;

/** @type {number} */
Selection.prototype.extentOffset;

/** @type {string} */
Selection.prototype.type;

/**
 * @return {undefined}
 */
Selection.prototype.empty = function() {};

/**
 * @param {Node} baseNode
 * @param {number} baseOffset
 * @param {Node} extentNode
 * @param {number} extentOffset
 * @return {undefined}
 */
Selection.prototype.setBaseAndExtent =
 function(baseNode, baseOffset, extentNode, extentOffset) {};

/**
 * @param {string} alter
 * @param {string} direction
 * @param {string} granularity
 * @return {undefined}
 */
Selection.prototype.modify = function(alter, direction, granularity) {};

/**
 * @param {Element} element
 * @param {string} pseudoElement
 * @param {boolean=} opt_authorOnly
 * @return {CSSRuleList}
 * @nosideeffects
 */
ViewCSS.prototype.getMatchedCSSRules =
    function(element, pseudoElement, opt_authorOnly) {};

/**
 * @param {string} contextId
 * @param {string} name
 * @param {number} width
 * @param {number} height
 * @nosideeffects
 */
Document.prototype.getCSSCanvasContext =
    function(contextId, name, width, height) {};

/**
 * @type {string}
 * @see http://code.google.com/chrome/whitepapers/pagevisibility.html
 */
Document.prototype.webkitVisibilityState;
<commit_msg><commit_after>/*
 * Copyright 2008 Google Inc.
 *
 * 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.
 */

/**
 * @fileoverview Definitions for all the extensions over W3C's DOM
 *  specification by WebKit. This file depends on w3c_dom2.js.
 *  All the provided definitions has been type annotated
 *
 * @externs
 */

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.cpp
 */
function MemoryInfo() {};

/** @type {number} */
MemoryInfo.prototype.totalJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.usedJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.jsHeapSizeLimit;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfileNode.idl
 */
function ScriptProfileNode() {};

/** @type {string} */
ScriptProfileNode.prototype.functionName;

/** @type {string} */
ScriptProfileNode.prototype.url;

/** @type {number} */
ScriptProfileNode.prototype.lineNumber;

/** @type {number} */
ScriptProfileNode.prototype.totalTime;

/** @type {number} */
ScriptProfileNode.prototype.selfTime;

/** @type {number} */
ScriptProfileNode.prototype.numberOfCalls;

/** @type {Array.<ScriptProfileNode>} */
ScriptProfileNode.prototype.children;

/** @type {boolean} */
ScriptProfileNode.prototype.visible;

/** @type {number} */
ScriptProfileNode.prototype.callUID;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfile.idl
 */
function ScriptProfile() {};

/** @type {string} */
ScriptProfile.prototype.title;

/** @type {number} */
ScriptProfile.prototype.uid;

/** @type {ScriptProfileNode} */
ScriptProfile.prototype.head;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.cpp
 */
function Console() {};

/**
 * @param {*} condition
 * @param {...*} var_args
 */
Console.prototype.assert = function(condition, var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.error = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.info = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.log = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.warn = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.debug = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.dir = function(value) {};

/**
 * @param {...*} var_args
 */
Console.prototype.dirxml = function(var_args) {};

/**
 * @return {undefined}
 */
Console.prototype.trace = function() {};

/**
 * @param {*} value
 */
Console.prototype.count = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.markTimeline = function(value) {};

/**
 * @param {string=} opt_title
 */
Console.prototype.profile = function(opt_title) {};

/** @type {Array.<ScriptProfile>} */
Console.prototype.profiles;

Console.prototype.profileEnd = function() {};

/**
 * @param {string} name
 */
Console.prototype.time = function(name) {};

/**
 * @param {string} name
 */
Console.prototype.timeEnd = function(name) {};

/**
 * @param {*} value
 */
Console.prototype.timeStamp = function(value) {};

Console.prototype.group = function() {};

Console.prototype.groupEnd = function() {};

/** @type {MemoryInfo} */
Console.prototype.memory;

/** @type {Console} */
Window.prototype.console;

/**
 * @type {number}
 * @see http://developer.android.com/reference/android/webkit/WebView.html
 */
Window.prototype.devicePixelRatio;

/** @type {Node} */
Selection.prototype.baseNode;

/** @type {number} */
Selection.prototype.baseOffset;

/** @type {Node} */
Selection.prototype.extentNode;

/** @type {number} */
Selection.prototype.extentOffset;

/** @type {string} */
Selection.prototype.type;

/**
 * @return {undefined}
 */
Selection.prototype.empty = function() {};

/**
 * @param {Node} baseNode
 * @param {number} baseOffset
 * @param {Node} extentNode
 * @param {number} extentOffset
 * @return {undefined}
 */
Selection.prototype.setBaseAndExtent =
 function(baseNode, baseOffset, extentNode, extentOffset) {};

/**
 * @param {string} alter
 * @param {string} direction
 * @param {string} granularity
 * @return {undefined}
 */
Selection.prototype.modify = function(alter, direction, granularity) {};

/**
 * @param {Element} element
 * @param {string} pseudoElement
 * @param {boolean=} opt_authorOnly
 * @return {CSSRuleList}
 * @nosideeffects
 */
ViewCSS.prototype.getMatchedCSSRules =
    function(element, pseudoElement, opt_authorOnly) {};

/**
 * @param {string} contextId
 * @param {string} name
 * @param {number} width
 * @param {number} height
 * @nosideeffects
 */
Document.prototype.getCSSCanvasContext =
    function(contextId, name, width, height) {};

/**
 * @type {string}
 * @see http://code.google.com/chrome/whitepapers/pagevisibility.html
 */
Document.prototype.webkitVisibilityState;
<|endoftext|>


<commit_before>angular.module('igTypeahead', []).directive('typeahead', function(){
  return{
    restrict: 'E',
    replace: true,
    scope: {
      choice: '=',
      list: '='
    },
    template: '<input type="text" ng-model="choice" />',
    link: function(scope, element, attrs){
      scope.typeaheadElement = element;
      $(element).typeahead({
        source: scope.list,
        updater: function(item){
          scope.$apply(function(){
            scope.choice = item;
          });
          return item;
        }
      });
    }
  };
});
<commit_msg>Added support to update the source list of typeahead plugin<commit_after>angular.module('igTypeahead', []).directive('typeahead', function(){
  return{
    restrict: 'E',
    replace: true,
    scope: {
      choice: '=',
      list: '='
    },
    template: '<input type="text" ng-model="choice" />',
    link: function(scope, element, attrs){
      scope.typeaheadElement = element;
      $(element).typeahead({
        source: scope.list,
        updater: function(item){
          scope.$apply(function(){
            scope.choice = item;
          });
          return item;
        }
      });
      scope.$watch('list',function(n,o){
        $(element).data('typeahead').source = n;
      },true);
    }
  };
});
<|endoftext|>


<commit_before>$.aaacplApp.registerPage.getLayout = function (){
	//This code will be dynamic - for now it is static
	var tmpl =  '
'+
        ''+
      '
'+
      '
'+
	   '
'+
		'
'+
		'	You have Registered successfully ! '+
		'
'+
		'
A verification link has been sent to your email address. Please check you mail.

 Please note: You will be able to login once admin verify the other details and activate your account. You will receive a notification for the same.
'+
		'
'+
		'
'+
        '
GET REGISTERED FOR THE MEMBERSHIP
'+
		'
'+
		'×'+
		'  Error ! '+
		'
'+
        '<form method="post" action="" id="submit">'+
        '
'+
		'	  <select id="select" class="form-control" required>'+
		'       <option value="">Select Account Type</option>'+
		'	  </select>'+
        '
'+
		 '
'+
          '  <input type="text" class="form-control" placeholder="Full name" required>'+
           ' '+
          '
'+
          '
'+
           ' <input type="email" class="form-control" placeholder="Email" required>'+
           ' '+
          '
'+
          '
'+
          '  <input type="password" class="form-control" placeholder="Password" required>'+
          '  '+
          '
'+
		  '
'+
          '  <input type="text" class="form-control" placeholder="Company name (Optional)">'+
          '
'+
		  '
'+
		'
'+
		'		<input type="text" class="form-control" placeholder="PAN no." required>'+
		'
'+
		'
'+
		'		<input type="text" class="form-control" placeholder="VAT no." required>'+
		'
'+
		 '
'+
          '
'+
           ' <textarea class="form-control" placeholder="Material Description"></textarea>'+
          '
'+
		  '
'+
          '  <textarea class="form-control" placeholder="Address" required></textarea>'+
          '
'+
		  '
'+
			'
'+
			'	<input type="text" class="form-control" placeholder="City" required>'+
			 '
'+
			  '
'+
				'<input type="text" class="form-control" placeholder="Pin Code" required>'+
			  '
'+
		  '
'+
		  '
'+
			'
'+
			'	<input type="text" class="form-control" placeholder="Country" required>'+
			 '
'+
			  '
'+
				'<input type="text" class="form-control" placeholder="State" required>'+
			  '
'+
		  '
'+
		 '
'+
         '   <input type="text" class="form-control" placeholder="Phone" required>'+
         '
'+
		 '
'+
         '   <input type="text" class="form-control" placeholder="Mobile no. (Optional)">'+
         '
'+
         '
'+
         '
'+
         '
'+
         '       '+
         '         <input type="checkbox" required> I agree to the terms'+
         '       '+
         '
'+
         '
'+
         '
'+
         '     <button type="submit" class="btn btn-primary btn-block bg-orange btn-flat">Register</button>'+
         '
'+
         '
'+
        '</form>'+
       ' Already a memeber with us?'+
      '
'+
	 '
';
	return tmpl;
};

$.aaacplApp.registerPage.executeScript = function(){

    // ajax call on page load which will return the user types which will be shown in the drop down list.
         $(function(){
             $.ajax({
               type: "GET",
               data: {
                     format: 'json'
                  },
               dataType: "jsonp",
               url: $.aaacplApp.apiSrvPath + 'user/userTypes',
               success: function(data){
               // appending option to select element
                $.each(data, function (key, item) {
                    $('#select').append($('<option>', {
                        value: item.type,
                        text : item.label
                    }));
                });
               },
                error: function() {
                $('#register-failure').show();
                $('#register-failure .message-text').html('Something went wrong. Kindly try later');
               }
            });
         });

	// be default hiding the success and error alert messages
		$('#register-success').hide();
		$('#register-failure').hide();
		var registerForm = $('#submit');
		registerForm[0].reset();

        $('input').iCheck({
          checkboxClass: 'icheckbox_square-orange',
          radioClass: 'iradio_square-orange',
          increaseArea: '20%' // optional
        });

		// ajax call only when client side validation is completed
		function registerFormAjaxCall(registerForm){
		var formData = JSON.stringify(registerForm.serializeArray()); // JSON data of values entered in form
			 $.ajax({
			 type: "POST",
			 url: $.aaacplApp.apiSrvPath + 'user/register', //REST API call
			 data: formData,
			 dataType: "jsonp",
			 success: function(response) {
				$('#register-success').show();
				$('#register-form').hide();
			 },
			 error: function() {
				$('#register-failure').show();
				$('#register-failure .message-text').html('Unable to register. Kindly provide correct details');
			 }
		});
		}

		// on submit function of form is called to perform client side validation

		registerForm.submit(function(event){
			event.preventDefault(); // Prevent the form from submitting via the browser
			registerFormAjaxCall(registerForm);
		});
};<commit_msg>register usertypes response<commit_after>$.aaacplApp.registerPage.getLayout = function (){
	//This code will be dynamic - for now it is static
	var tmpl =  '
'+
        ''+
      '
'+
      '
'+
	   '
'+
		'
'+
		'	You have Registered successfully ! '+
		'
'+
		'
A verification link has been sent to your email address. Please check you mail.

 Please note: You will be able to login once admin verify the other details and activate your account. You will receive a notification for the same.
'+
		'
'+
		'
'+
        '
GET REGISTERED FOR THE MEMBERSHIP
'+
		'
'+
		'×'+
		'  Error ! '+
		'
'+
        '<form method="post" action="" id="submit">'+
        '
'+
		'	  <select id="select" class="form-control" required>'+
		'       <option value="">Select Account Type</option>'+
		'	  </select>'+
        '
'+
		 '
'+
          '  <input type="text" class="form-control" placeholder="Full name" required>'+
           ' '+
          '
'+
          '
'+
           ' <input type="email" class="form-control" placeholder="Email" required>'+
           ' '+
          '
'+
          '
'+
          '  <input type="password" class="form-control" placeholder="Password" required>'+
          '  '+
          '
'+
		  '
'+
          '  <input type="text" class="form-control" placeholder="Company name (Optional)">'+
          '
'+
		  '
'+
		'
'+
		'		<input type="text" class="form-control" placeholder="PAN no." required>'+
		'
'+
		'
'+
		'		<input type="text" class="form-control" placeholder="VAT no." required>'+
		'
'+
		 '
'+
          '
'+
           ' <textarea class="form-control" placeholder="Material Description"></textarea>'+
          '
'+
		  '
'+
          '  <textarea class="form-control" placeholder="Address" required></textarea>'+
          '
'+
		  '
'+
			'
'+
			'	<input type="text" class="form-control" placeholder="City" required>'+
			 '
'+
			  '
'+
				'<input type="text" class="form-control" placeholder="Pin Code" required>'+
			  '
'+
		  '
'+
		  '
'+
			'
'+
			'	<input type="text" class="form-control" placeholder="Country" required>'+
			 '
'+
			  '
'+
				'<input type="text" class="form-control" placeholder="State" required>'+
			  '
'+
		  '
'+
		 '
'+
         '   <input type="text" class="form-control" placeholder="Phone" required>'+
         '
'+
		 '
'+
         '   <input type="text" class="form-control" placeholder="Mobile no. (Optional)">'+
         '
'+
         '
'+
         '
'+
         '
'+
         '       '+
         '         <input type="checkbox" required> I agree to the terms'+
         '       '+
         '
'+
         '
'+
         '
'+
         '     <button type="submit" class="btn btn-primary btn-block bg-orange btn-flat">Register</button>'+
         '
'+
         '
'+
        '</form>'+
       ' Already a memeber with us?'+
      '
'+
	 '
';
	return tmpl;
};

$.aaacplApp.registerPage.executeScript = function(){

    // ajax call on page load which will return the user types which will be shown in the drop down list.
         $(function(){
             $.ajax({
               type: "GET",
               dataType: "json",
			   crossDomain : true,
               url: $.aaacplApp.apiSrvPath + 'user/userTypes',
               success: function(data){
               // appending option to select element
			   data = data.getTypesResponseList;
                $.each(data, function (key, item) {
                    $('#select').append($('<option>', {
                        value: item.type,
                        text : item.label
                    }));
                });
               },
                error: function() {
                $('#register-failure').show();
                $('#register-failure .message-text').html('Something went wrong. Kindly try later');
               }
            });
         });

	// be default hiding the success and error alert messages
		$('#register-success').hide();
		$('#register-failure').hide();
		var registerForm = $('#submit');
		registerForm[0].reset();

        $('input').iCheck({
          checkboxClass: 'icheckbox_square-orange',
          radioClass: 'iradio_square-orange',
          increaseArea: '20%' // optional
        });

		// ajax call only when client side validation is completed
		function registerFormAjaxCall(registerForm){
		var formData = JSON.stringify(registerForm.serializeArray()); // JSON data of values entered in form
			 $.ajax({
			 type: "POST",
			 url: $.aaacplApp.apiSrvPath + 'user/register', //REST API call
			 data: formData,
			 dataType: "jsonp",
			 success: function(response) {
				$('#register-success').show();
				$('#register-form').hide();
			 },
			 error: function() {
				$('#register-failure').show();
				$('#register-failure .message-text').html('Unable to register. Kindly provide correct details');
			 }
		});
		}

		// on submit function of form is called to perform client side validation

		registerForm.submit(function(event){
			event.preventDefault(); // Prevent the form from submitting via the browser
			registerFormAjaxCall(registerForm);
		});
};<|endoftext|>


<commit_before>/**
 * Special concat/build task to handle various jQuery build requirements
 * Concats AMD modules, removes their definitions, and includes/excludes specified modules
 */

module.exports = function( grunt ) {

	"use strict";

	var fs = require( "fs" ),
		requirejs = require( "requirejs" ),
		srcFolder = __dirname + "/../../src/",
		rdefineEnd = /\}\);[^}\w]*$/,
		config = {
			baseUrl: "src",
			name: "jquery",
			out: "dist/jquery.js",
			// We have multiple minify steps
			optimize: "none",
			// Include dependencies loaded with require
			findNestedDependencies: true,
			// Avoid breaking semicolons inserted by r.js
			skipSemiColonInsertion: true,
			wrap: {
				startFile: "src/intro.js",
				endFile: "src/outro.js"
			},
			paths: {
				sizzle: "../bower_components/sizzle/dist/sizzle"
			},
			rawText: {},
			onBuildWrite: convert
		};

	/**
	 * Strip all definitions generated by requirejs
	 * Convert "var" modules to var declarations
	 * "var module" means the module only contains a return statement that should be converted to a var declaration
	 * This is indicated by including the file in any "var" folder
	 * @param {String} name
	 * @param {String} path
	 * @param {String} contents The contents to be written (including their AMD wrappers)
	 */
	function convert( name, path, contents ) {
		// Convert var modules
		if ( /.\/var\//.test( path ) ) {
			contents = contents
				.replace( /define\([\w\W]*?return/, "var " + (/var\/([\w-]+)/.exec(name)[1]) + " =" )
				.replace( rdefineEnd, "" );

		// Sizzle treatment
		} else if ( /^sizzle$/.test( name ) ) {
			contents = "var Sizzle =\n" + contents
				// Remove EXPOSE lines from Sizzle
				.replace( /\/\/\s*EXPOSE[\w\W]*\/\/\s*EXPOSE/, "return Sizzle;" );

		} else {

			// Ignore jQuery's exports (the only necessary one)
			if ( name !== "jquery" ) {
				contents = contents
					.replace( /\s*return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" )
					// Multiple exports
					.replace( /\s*exports\.\w+\s*=\s*\w+;/g, "" );
			}

			// Remove define wrappers, closure ends, and empty declarations
			contents = contents
				.replace( /define\([^{]*?{/, "" )
				.replace( rdefineEnd, "" );

			// Remove anything wrapped with
			// /* ExcludeStart */ /* ExcludeEnd */
			// or a single line directly after a // BuildExclude comment
			contents = contents
				.replace( /\/\*\s*ExcludeStart\s*\*\/[\w\W]*?\/\*\s*ExcludeEnd\s*\*\//ig, "" )
				.replace( /\/\/\s*BuildExclude\n\r?[\w\W]*?\n\r?/ig, "" );

			// Remove empty definitions
			contents = contents
				.replace( /define\(\[[^\]]+\]\)[\W\n]+$/, "" );
		}
		return contents;
	}

	grunt.registerMultiTask(
		"build",
		"Concatenate source, remove sub AMD definitions, (include/exclude modules with +/- flags), embed date/version",
	function() {
		var flag, index,
			done = this.async(),
			flags = this.flags,
			optIn = flags[ "*" ],
			name = this.data.dest,
			minimum = this.data.minimum,
			removeWith = this.data.removeWith,
			excluded = [],
			included = [],
			version = grunt.config( "pkg.version" ),
			/**
			 * Recursively calls the excluder to remove on all modules in the list
			 * @param {Array} list
			 * @param {String} [prepend] Prepend this to the module name. Indicates we're walking a directory
			 */
			excludeList = function( list, prepend ) {
				if ( list ) {
					prepend = prepend ? prepend + "/" : "";
					list.forEach(function( module ) {
						// Exclude var modules as well
						if ( module === "var" ) {
							excludeList( fs.readdirSync( srcFolder + prepend + module ), prepend + module );
							return;
						}
						if ( prepend ) {
							// Skip if this is not a js file and we're walking files in a dir
							if ( !(module = /([\w-\/]+)\.js$/.exec( module )) ) {
								return;
							}
							// Prepend folder name if passed
							// Remove .js extension
							module = prepend + module[1];
						}

						// Avoid infinite recursion
						if ( excluded.indexOf( module ) === -1 ) {
							excluder( "-" + module );
						}
					});
				}
			},
			/**
			 * Adds the specified module to the excluded or included list, depending on the flag
			 * @param {String} flag A module path relative to the src directory starting with + or - to indicate whether it should included or excluded
			 */
			excluder = function( flag ) {
				var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
					exclude = m[ 1 ] === "-",
					module = m[ 2 ];

				if ( exclude ) {
					// Can't exclude certain modules
					if ( minimum.indexOf( module ) === -1 ) {
						// Add to excluded
						if ( excluded.indexOf( module ) === -1 ) {
							grunt.log.writeln( flag );
							excluded.push( module );
							// Exclude all files in the folder of the same name
							// These are the removable dependencies
							// It's fine if the directory is not there
							try {
								excludeList( fs.readdirSync( srcFolder + module ), module );
							} catch( e ) {
								grunt.verbose.writeln( e );
							}
						}
						// Check removeWith list
						excludeList( removeWith[ module ] );
					} else {
						grunt.log.error( "Module \"" + module + "\" is a mimimum requirement.");
						if ( module === "selector" ) {
							grunt.log.error( "If you meant to replace Sizzle, use -sizzle instead." );
						}
					}
				} else {
					grunt.log.writeln( flag );
					included.push( module );
				}
			};

		// append commit id to version
		if ( process.env.COMMIT ) {
			version += " " + process.env.COMMIT;
		}

		// figure out which files to exclude based on these rules in this order:
		//  dependency explicit exclude
		//  > explicit exclude
		//  > explicit include
		//  > dependency implicit exclude
		//  > implicit exclude
		// examples:
		//  *                  none (implicit exclude)
		//  *:*                all (implicit include)
		//  *:*:-css           all except css and dependents (explicit > implicit)
		//  *:*:-css:+effects  same (excludes effects because explicit include is trumped by explicit exclude of dependency)
		//  *:+effects         none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
		delete flags[ "*" ];
		for ( flag in flags ) {
			excluder( flag );
		}

		// Handle Sizzle exclusion
		// Replace with selector-native
		if ( (index = excluded.indexOf( "sizzle" )) > -1 ) {
			config.rawText.selector = "define(['./selector-native']);";
			excluded.splice( index, 1 );
		}

		grunt.verbose.writeflags( excluded, "Excluded" );
		grunt.verbose.writeflags( included, "Included" );

		// append excluded modules to version
		if ( excluded.length ) {
			version += " -" + excluded.join( ",-" );
			// set pkg.version to version with excludes, so minified file picks it up
			grunt.config.set( "pkg.version", version );
			grunt.verbose.writeln( "Version changed to " + version );
			// Have to use shallow or core will get excluded since it is a dependency
			config.excludeShallow = excluded;
		}
		config.include = included;

		/**
		 * Handle Final output from the optimizer
		 * @param {String} compiled
		 */
		config.out = function( compiled ) {
			compiled = compiled
				// Embed Version
				.replace( /@VERSION/g, version )
				// Embed Date
				// yyyy-mm-ddThh:mmZ
				.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );

			// Write concatenated source to file
			grunt.file.write( name, compiled );
		};

		// Turn off opt-in if necessary
		if ( !optIn ) {
			// Overwrite the default inclusions with the explicit ones provided
			config.rawText.jquery = "define([" + (included.length ? included.join(",") : "") + "]);";
		}

		// Trace dependencies and concatenate files
		requirejs.optimize( config, function( response ) {
			grunt.verbose.writeln( response );
			grunt.log.ok( "File '" + name + "' created." );
			done();
		}, function( err ) {
			done( err );
		});
	});

	// Special "alias" task to make custom build creation less grawlix-y
	// Translation example
	//
	//   grunt custom:+ajax,-dimensions,-effects,-offset
	//
	// Becomes:
	//
	//   grunt build:*:*:+ajax:-dimensions:-effects:-offset
	grunt.registerTask( "custom", function() {
		var args = [].slice.call( arguments ),
			modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";

		grunt.log.writeln( "Creating custom build...\n" );

		grunt.task.run([ "build:*:*:" + modules, "pre-uglify", "uglify", "dist" ]);
	});
};
<commit_msg>No ticket. Remove the pre-uglify task form build/tasks/build.js. Fix custom builds.<commit_after>/**
 * Special concat/build task to handle various jQuery build requirements
 * Concats AMD modules, removes their definitions, and includes/excludes specified modules
 */

module.exports = function( grunt ) {

	"use strict";

	var fs = require( "fs" ),
		requirejs = require( "requirejs" ),
		srcFolder = __dirname + "/../../src/",
		rdefineEnd = /\}\);[^}\w]*$/,
		config = {
			baseUrl: "src",
			name: "jquery",
			out: "dist/jquery.js",
			// We have multiple minify steps
			optimize: "none",
			// Include dependencies loaded with require
			findNestedDependencies: true,
			// Avoid breaking semicolons inserted by r.js
			skipSemiColonInsertion: true,
			wrap: {
				startFile: "src/intro.js",
				endFile: "src/outro.js"
			},
			paths: {
				sizzle: "../bower_components/sizzle/dist/sizzle"
			},
			rawText: {},
			onBuildWrite: convert
		};

	/**
	 * Strip all definitions generated by requirejs
	 * Convert "var" modules to var declarations
	 * "var module" means the module only contains a return statement that should be converted to a var declaration
	 * This is indicated by including the file in any "var" folder
	 * @param {String} name
	 * @param {String} path
	 * @param {String} contents The contents to be written (including their AMD wrappers)
	 */
	function convert( name, path, contents ) {
		// Convert var modules
		if ( /.\/var\//.test( path ) ) {
			contents = contents
				.replace( /define\([\w\W]*?return/, "var " + (/var\/([\w-]+)/.exec(name)[1]) + " =" )
				.replace( rdefineEnd, "" );

		// Sizzle treatment
		} else if ( /^sizzle$/.test( name ) ) {
			contents = "var Sizzle =\n" + contents
				// Remove EXPOSE lines from Sizzle
				.replace( /\/\/\s*EXPOSE[\w\W]*\/\/\s*EXPOSE/, "return Sizzle;" );

		} else {

			// Ignore jQuery's exports (the only necessary one)
			if ( name !== "jquery" ) {
				contents = contents
					.replace( /\s*return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" )
					// Multiple exports
					.replace( /\s*exports\.\w+\s*=\s*\w+;/g, "" );
			}

			// Remove define wrappers, closure ends, and empty declarations
			contents = contents
				.replace( /define\([^{]*?{/, "" )
				.replace( rdefineEnd, "" );

			// Remove anything wrapped with
			// /* ExcludeStart */ /* ExcludeEnd */
			// or a single line directly after a // BuildExclude comment
			contents = contents
				.replace( /\/\*\s*ExcludeStart\s*\*\/[\w\W]*?\/\*\s*ExcludeEnd\s*\*\//ig, "" )
				.replace( /\/\/\s*BuildExclude\n\r?[\w\W]*?\n\r?/ig, "" );

			// Remove empty definitions
			contents = contents
				.replace( /define\(\[[^\]]+\]\)[\W\n]+$/, "" );
		}
		return contents;
	}

	grunt.registerMultiTask(
		"build",
		"Concatenate source, remove sub AMD definitions, (include/exclude modules with +/- flags), embed date/version",
	function() {
		var flag, index,
			done = this.async(),
			flags = this.flags,
			optIn = flags[ "*" ],
			name = this.data.dest,
			minimum = this.data.minimum,
			removeWith = this.data.removeWith,
			excluded = [],
			included = [],
			version = grunt.config( "pkg.version" ),
			/**
			 * Recursively calls the excluder to remove on all modules in the list
			 * @param {Array} list
			 * @param {String} [prepend] Prepend this to the module name. Indicates we're walking a directory
			 */
			excludeList = function( list, prepend ) {
				if ( list ) {
					prepend = prepend ? prepend + "/" : "";
					list.forEach(function( module ) {
						// Exclude var modules as well
						if ( module === "var" ) {
							excludeList( fs.readdirSync( srcFolder + prepend + module ), prepend + module );
							return;
						}
						if ( prepend ) {
							// Skip if this is not a js file and we're walking files in a dir
							if ( !(module = /([\w-\/]+)\.js$/.exec( module )) ) {
								return;
							}
							// Prepend folder name if passed
							// Remove .js extension
							module = prepend + module[1];
						}

						// Avoid infinite recursion
						if ( excluded.indexOf( module ) === -1 ) {
							excluder( "-" + module );
						}
					});
				}
			},
			/**
			 * Adds the specified module to the excluded or included list, depending on the flag
			 * @param {String} flag A module path relative to the src directory starting with + or - to indicate whether it should included or excluded
			 */
			excluder = function( flag ) {
				var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
					exclude = m[ 1 ] === "-",
					module = m[ 2 ];

				if ( exclude ) {
					// Can't exclude certain modules
					if ( minimum.indexOf( module ) === -1 ) {
						// Add to excluded
						if ( excluded.indexOf( module ) === -1 ) {
							grunt.log.writeln( flag );
							excluded.push( module );
							// Exclude all files in the folder of the same name
							// These are the removable dependencies
							// It's fine if the directory is not there
							try {
								excludeList( fs.readdirSync( srcFolder + module ), module );
							} catch( e ) {
								grunt.verbose.writeln( e );
							}
						}
						// Check removeWith list
						excludeList( removeWith[ module ] );
					} else {
						grunt.log.error( "Module \"" + module + "\" is a mimimum requirement.");
						if ( module === "selector" ) {
							grunt.log.error( "If you meant to replace Sizzle, use -sizzle instead." );
						}
					}
				} else {
					grunt.log.writeln( flag );
					included.push( module );
				}
			};

		// append commit id to version
		if ( process.env.COMMIT ) {
			version += " " + process.env.COMMIT;
		}

		// figure out which files to exclude based on these rules in this order:
		//  dependency explicit exclude
		//  > explicit exclude
		//  > explicit include
		//  > dependency implicit exclude
		//  > implicit exclude
		// examples:
		//  *                  none (implicit exclude)
		//  *:*                all (implicit include)
		//  *:*:-css           all except css and dependents (explicit > implicit)
		//  *:*:-css:+effects  same (excludes effects because explicit include is trumped by explicit exclude of dependency)
		//  *:+effects         none except effects and its dependencies (explicit include trumps implicit exclude of dependency)
		delete flags[ "*" ];
		for ( flag in flags ) {
			excluder( flag );
		}

		// Handle Sizzle exclusion
		// Replace with selector-native
		if ( (index = excluded.indexOf( "sizzle" )) > -1 ) {
			config.rawText.selector = "define(['./selector-native']);";
			excluded.splice( index, 1 );
		}

		grunt.verbose.writeflags( excluded, "Excluded" );
		grunt.verbose.writeflags( included, "Included" );

		// append excluded modules to version
		if ( excluded.length ) {
			version += " -" + excluded.join( ",-" );
			// set pkg.version to version with excludes, so minified file picks it up
			grunt.config.set( "pkg.version", version );
			grunt.verbose.writeln( "Version changed to " + version );
			// Have to use shallow or core will get excluded since it is a dependency
			config.excludeShallow = excluded;
		}
		config.include = included;

		/**
		 * Handle Final output from the optimizer
		 * @param {String} compiled
		 */
		config.out = function( compiled ) {
			compiled = compiled
				// Embed Version
				.replace( /@VERSION/g, version )
				// Embed Date
				// yyyy-mm-ddThh:mmZ
				.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );

			// Write concatenated source to file
			grunt.file.write( name, compiled );
		};

		// Turn off opt-in if necessary
		if ( !optIn ) {
			// Overwrite the default inclusions with the explicit ones provided
			config.rawText.jquery = "define([" + (included.length ? included.join(",") : "") + "]);";
		}

		// Trace dependencies and concatenate files
		requirejs.optimize( config, function( response ) {
			grunt.verbose.writeln( response );
			grunt.log.ok( "File '" + name + "' created." );
			done();
		}, function( err ) {
			done( err );
		});
	});

	// Special "alias" task to make custom build creation less grawlix-y
	// Translation example
	//
	//   grunt custom:+ajax,-dimensions,-effects,-offset
	//
	// Becomes:
	//
	//   grunt build:*:*:+ajax:-dimensions:-effects:-offset
	grunt.registerTask( "custom", function() {
		var args = [].slice.call( arguments ),
			modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";

		grunt.log.writeln( "Creating custom build...\n" );

		grunt.task.run([ "build:*:*:" + modules, "uglify", "dist" ]);
	});
};
<|endoftext|>