<commit_before>$(document).ready(function() {
    _init('CA')
});

function _init(defaultState) {
    if (defaultState) { _generateDashboards(defaultState); }

    $('select').change(function(){
        var stateAbbrev = this.value;
        _generateDashboards(stateAbbrev);
    });
}

function _generateDashboards (state) {
    dashboardAreaChart(state);
    appendStateDescription(state);
    dashboardHomocideRate(state);
    dashboardRapeRate(state);
    dashboardRobberyRate(state);
    dashboardAssaultRate(state);
    dashboardPopAreaBarCharts(state);
}

function dashboardPopAreaBarCharts (state) {
    var rawCSV = 'data/prison-rearrest.csv';
    var stateData = [];
    $.get(rawCSV, function (csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateData.push(data[i]);
            }
        }
        _generateMetroBarChart(state, stateData[0]);
        _generateMicroBarChart(state, stateData[1]);
        _generateNonMetroBarChart(state, stateData[2]);
    });
}

function dashboardHomocideRate (state) {
    _generateLineChartData(state, 'Homocide', 'homocide');
}

function dashboardRapeRate (state) {
    _generateLineChartData (state, 'Rape', 'rape');
}

function dashboardRobberyRate (state)  {
    _generateLineChartData (state, 'Robbery', 'robbery');
}

function dashboardAssaultRate (state)  {
    _generateLineChartData (state, 'Aggravated Assault', 'assault');
}

function _appendPercentChange (id, percentChange) {
    $(id).text(percentChange);
}

// Area chart
function dashboardAreaChart (state) {
    var stateCSV = 'data/prison-rearrest.csv';
    var stateData, stateName, increaseOrDecline, percentChange;
    $.get(stateCSV, function(csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateName = data[i][0];
                percentChange = data[i][data[i].length - 1];
                increaseOrDecline = parseFloat(data[i][data[i].length - 1]) > 0 ? 'increased' : 'declined';
                stateData = _formatStateData(data[i]);
            }
        }
        _appendPercentChange('#crime-rate-chart-percent-change', percentChange);
        _appendPageTitles(stateName, increaseOrDecline);
        _createAreaChart(stateName, stateData);
    });
}

function _appendPageTitles (stateName, increaseOrDecline) {
    $('#title').text(stateName + '\'s violent crime rate ' + increaseOrDecline + ' overall between 2006 and 2016.');
    $('#category-title').text('Change in ' + stateName + '\'s Violent Crime Rate (Incidents per 100,000 Residents) by Category, 2006–2016')
    $('#bar-chart-title').text('Change in ' + stateName + '\'s Overall Violent Crime Rate (Incidents per 100,000 Residents) by Population Area, 2006–2016');
}

function appendStateDescription (state) {
    var content = $('#state-description');
    var lormIpsum = 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur';
    switch (state) {
      case 'AL':
        content.text(lormIpsum + state)
        break;
      case 'AK':
        content.text(lormIpsum + state)
        break;
      case 'AZ':
        content.text(lormIpsum + state)
        break;
      case 'AR':
        content.text(lormIpsum + state)
        break;
      case 'CA':
        content.text(lormIpsum + state)
        break;
      case 'CO':
        content.text(lormIpsum + state)
        break;
      case 'CT':
        content.text(lormIpsum + state)
        break;
      case 'DE':
        content.text(lormIpsum + state)
        break;
      case 'FL':
        content.text(lormIpsum + state)
        break;
      case 'GA':
        content.text(lormIpsum + state)
        break;
      case 'HI':
        content.text(lormIpsum + state)
        break;
      case 'ID':
        content.text(lormIpsum + state)
        break;
      case 'IL':
        content.text(lormIpsum + state)
        break;
      case 'IN':
        content.text(lormIpsum + state)
        break;
      case 'IA':
        content.text(lormIpsum + state)
        break;
      case 'KS':
        content.text(lormIpsum + state)
        break;
      case 'KY':
        content.text(lormIpsum + state)
        break;
      case 'LA':
        content.text(lormIpsum + state)
        break;
      case 'ME':
        content.text(lormIpsum + state)
        break;
      case 'MD':
        content.text(lormIpsum + state)
        break;
      case 'MA':
        content.text(lormIpsum + state)
        break;
      case 'MI':
        content.text(lormIpsum + state)
        break;
      case 'MN':
        content.text(lormIpsum + state)
        break;
      case 'MS':
        content.text(lormIpsum + state)
        break;
      case 'MO':
        content.text(lormIpsum + state)
        break;
      case 'MT':
        content.text(lormIpsum + state)
        break;
      case 'NE':
        content.text(lormIpsum + state)
        break;
      case 'NV':
        content.text(lormIpsum + state)
        break;
      case 'NH':
        content.text(lormIpsum + state)
        break;
      case 'NJ':
        content.text(lormIpsum + state)
        break;
      case 'NM':
        content.text(lormIpsum + state)
        break;
      case 'NY':
        content.text(lormIpsum + state)
        break;
      case 'NC':
        content.text(lormIpsum + state)
        break;
      case 'ND':
        content.text(lormIpsum + state)
        break;
      case 'OH':
        content.text(lormIpsum + state)
        break;
      case 'OK':
        content.text(lormIpsum + state)
        break;
      case 'OR':
        content.text(lormIpsum + state)
        break;
      case 'PA':
        content.text(lormIpsum + state)
        break;
      case 'RI':
        content.text(lormIpsum + state)
        break;
      case 'SC':
        content.text(lormIpsum + state)
        break;
      case 'SD':
        content.text(lormIpsum + state)
        break;
      case 'TN':
        content.text(lormIpsum + state)
        break;
      case 'TX':
        content.text(lormIpsum + state)
        break;
      case 'UT':
        content.text(lormIpsum + state)
        break;
      case 'VT':
        content.text(lormIpsum + state)
        break;
      case 'VA':
        content.text(lormIpsum + state)
        break;
      case 'WA':
        content.text(lormIpsum + state)
        break;
      case 'WV':
        content.text(lormIpsum + state)
        break;
      case 'WI':
        content.text(lormIpsum + state)
        break;
      case 'WY':
        content.text(lormIpsum + state)
        break;
    }
}
// end area chart

// Bar chart functions
function _generateMetroBarChart (state, data) {
    var id = 'metro';
    var name = 'Metropolitan Areas';
    var subtitle = '(population of 50,000+)'
    var percentChange = data[data.length - 1];
    _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _generateMicroBarChart (state, data) {
    var id = 'micro';
    var name = 'Micropolitan Areas';
    var subtitle = '(population of 10,000–49,999)';
    var percentChange = data[data.length - 1];
    _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _generateNonMetroBarChart (state, data) {
    var id = 'non-metro';
    var name = 'Non-Metropolitan Areas';
    var subtitle = '(population of fewer than 10,000)';
//    var percentChange = data[data.length - 1];
//    _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _cutBarChartData (data) {
    var cutData = [];
    cutData.push(Number(data.slice(4, 5)[0]));
    cutData.push(Number(data.slice(6, 7)[0]));
    return cutData;
}

function _createBarChart (data, id, name, subtitle) {
    var myChart = Highcharts.chart(id, {
        chart: {
            type: 'bar'
        },
        title: {
            text: name
        },
        subtitle: {
            text: subtitle
        },
        xAxis: {
            categories: ['', ''],
            labels: {
                enabled: false
            }
        },
        yAxis: {
            title: {
                text: ''
            },
            labels: {
                enabled: false
            }
        },
        legend: {
            enabled: false
        },
        colors: [
            '#E76946',
            '#FBB731'
        ],
        plotOptions: {
               series: {
                   pointPadding: 0,
                   groupPadding: 0,
                   colorByPoint: true
               }
           },
        series: [{
            data: data
        }]
    });
}
// end bar chart

// Line chart functions
function _createAreaChart (stateName, stateData) {
    var myChart = Highcharts.chart('crime-rate-chart', {
        chart: {
            type: 'area'
        },
        title: {
            text: 'Change in ' + stateName + '\'s Overall Violent Crime Rate (Incidents per 100,000 Residents), 2006–2016'
        },
        xAxis: {
            categories: ['2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016']
        },
        legend: {
            enabled: false
        },
        yAxis: {
            title: {
                text: ''
            }
        },
        series: [{
            name: stateName,
            data: stateData,
            color: '#66ccff',
            fillOpacity: 1
        }],
    });
}

function _generateLineChartData (state, title, type) {
   // var stateCSV = 'data/' + type + '-rate.csv';
   var stateCSV = 'data/prison-rearrest.csv';
    var stateData, stateName, percentChange;
    $.get(stateCSV, function (csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateName = data[i][0];
                percentChange = data[i][data[i].length - 1];
                stateData = _formatStateData(data[i]);
            }
        }
        var chartId = type + '-chart';
        _appendPercentChange('#' + type + '-percent-change', percentChange);
        _createLineChart(stateName, stateData, title, chartId);
    });
}

function _createLineChart (stateName, stateData, title, chartId) {
    var myChart = Highcharts.chart(chartId, {
        chart: {
            type: 'line'
        },
        title: {
            text: title
        },
        xAxis: {
            categories: ['2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016']
        },
        legend: {
            enabled: false
        },
        yAxis: {
            title: {
                text: ''
            }
        },
        series: [{
            name: stateName,
            data: stateData
        }]
    });
}

function _csvToArray (csv) {
    rows  = csv.split("\n");
    return rows.map(function (row) {
        return row.split(",");
    });
};

function _formatStateData (data) {
    data.splice(0, 2);
    data.splice(-1, 1);
    data = data.map(Number);
    return data;
}
// end line chart functions<commit_msg>Remove percent change<commit_after>$(document).ready(function() {
    _init('CA')
});

function _init(defaultState) {
    if (defaultState) { _generateDashboards(defaultState); }

    $('select').change(function(){
        var stateAbbrev = this.value;
        _generateDashboards(stateAbbrev);
    });
}

function _generateDashboards (state) {
    dashboardAreaChart(state);
    appendStateDescription(state);
    dashboardHomocideRate(state);
    dashboardRapeRate(state);
    dashboardRobberyRate(state);
    dashboardAssaultRate(state);
    dashboardPopAreaBarCharts(state);
}

function dashboardPopAreaBarCharts (state) {
    var rawCSV = 'data/prison-rearrest.csv';
    var stateData = [];
    $.get(rawCSV, function (csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateData.push(data[i]);
            }
        }
        _generateMetroBarChart(state, stateData[0]);
        _generateMicroBarChart(state, stateData[1]);
        _generateNonMetroBarChart(state, stateData[2]);
    });
}

function dashboardHomocideRate (state) {
    _generateLineChartData(state, 'Homocide', 'homocide');
}

function dashboardRapeRate (state) {
    _generateLineChartData (state, 'Rape', 'rape');
}

function dashboardRobberyRate (state)  {
    _generateLineChartData (state, 'Robbery', 'robbery');
}

function dashboardAssaultRate (state)  {
    _generateLineChartData (state, 'Aggravated Assault', 'assault');
}

//function _appendPercentChange (id, percentChange) {
 //   $(id).text(percentChange);
}

// Area chart
function dashboardAreaChart (state) {
    var stateCSV = 'data/prison-rearrest.csv';
    var stateData, stateName, increaseOrDecline;
    $.get(stateCSV, function(csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateName = data[i][0];
//                percentChange = data[i][data[i].length - 1];
                increaseOrDecline = parseFloat(data[i][data[i].length - 1]) > 0 ? 'increased' : 'declined';
                stateData = _formatStateData(data[i]);
            }
        }
//        _appendPercentChange('#crime-rate-chart-percent-change', percentChange);
        _appendPageTitles(stateName, increaseOrDecline);
        _createAreaChart(stateName, stateData);
    });
}

function _appendPageTitles (stateName, increaseOrDecline) {
    $('#title').text(stateName + '\'s violent crime rate ' + increaseOrDecline + ' overall between 2006 and 2016.');
    $('#category-title').text('Change in ' + stateName + '\'s Violent Crime Rate (Incidents per 100,000 Residents) by Category, 2006–2016')
    $('#bar-chart-title').text('Change in ' + stateName + '\'s Overall Violent Crime Rate (Incidents per 100,000 Residents) by Population Area, 2006–2016');
}

function appendStateDescription (state) {
    var content = $('#state-description');
    var lormIpsum = 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur';
    switch (state) {
      case 'AL':
        content.text(lormIpsum + state)
        break;
      case 'AK':
        content.text(lormIpsum + state)
        break;
      case 'AZ':
        content.text(lormIpsum + state)
        break;
      case 'AR':
        content.text(lormIpsum + state)
        break;
      case 'CA':
        content.text(lormIpsum + state)
        break;
      case 'CO':
        content.text(lormIpsum + state)
        break;
      case 'CT':
        content.text(lormIpsum + state)
        break;
      case 'DE':
        content.text(lormIpsum + state)
        break;
      case 'FL':
        content.text(lormIpsum + state)
        break;
      case 'GA':
        content.text(lormIpsum + state)
        break;
      case 'HI':
        content.text(lormIpsum + state)
        break;
      case 'ID':
        content.text(lormIpsum + state)
        break;
      case 'IL':
        content.text(lormIpsum + state)
        break;
      case 'IN':
        content.text(lormIpsum + state)
        break;
      case 'IA':
        content.text(lormIpsum + state)
        break;
      case 'KS':
        content.text(lormIpsum + state)
        break;
      case 'KY':
        content.text(lormIpsum + state)
        break;
      case 'LA':
        content.text(lormIpsum + state)
        break;
      case 'ME':
        content.text(lormIpsum + state)
        break;
      case 'MD':
        content.text(lormIpsum + state)
        break;
      case 'MA':
        content.text(lormIpsum + state)
        break;
      case 'MI':
        content.text(lormIpsum + state)
        break;
      case 'MN':
        content.text(lormIpsum + state)
        break;
      case 'MS':
        content.text(lormIpsum + state)
        break;
      case 'MO':
        content.text(lormIpsum + state)
        break;
      case 'MT':
        content.text(lormIpsum + state)
        break;
      case 'NE':
        content.text(lormIpsum + state)
        break;
      case 'NV':
        content.text(lormIpsum + state)
        break;
      case 'NH':
        content.text(lormIpsum + state)
        break;
      case 'NJ':
        content.text(lormIpsum + state)
        break;
      case 'NM':
        content.text(lormIpsum + state)
        break;
      case 'NY':
        content.text(lormIpsum + state)
        break;
      case 'NC':
        content.text(lormIpsum + state)
        break;
      case 'ND':
        content.text(lormIpsum + state)
        break;
      case 'OH':
        content.text(lormIpsum + state)
        break;
      case 'OK':
        content.text(lormIpsum + state)
        break;
      case 'OR':
        content.text(lormIpsum + state)
        break;
      case 'PA':
        content.text(lormIpsum + state)
        break;
      case 'RI':
        content.text(lormIpsum + state)
        break;
      case 'SC':
        content.text(lormIpsum + state)
        break;
      case 'SD':
        content.text(lormIpsum + state)
        break;
      case 'TN':
        content.text(lormIpsum + state)
        break;
      case 'TX':
        content.text(lormIpsum + state)
        break;
      case 'UT':
        content.text(lormIpsum + state)
        break;
      case 'VT':
        content.text(lormIpsum + state)
        break;
      case 'VA':
        content.text(lormIpsum + state)
        break;
      case 'WA':
        content.text(lormIpsum + state)
        break;
      case 'WV':
        content.text(lormIpsum + state)
        break;
      case 'WI':
        content.text(lormIpsum + state)
        break;
      case 'WY':
        content.text(lormIpsum + state)
        break;
    }
}
// end area chart

// Bar chart functions
function _generateMetroBarChart (state, data) {
    var id = 'metro';
    var name = 'Metropolitan Areas';
    var subtitle = '(population of 50,000+)'
//    var percentChange = data[data.length - 1];
//    _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _generateMicroBarChart (state, data) {
    var id = 'micro';
    var name = 'Micropolitan Areas';
    var subtitle = '(population of 10,000–49,999)';
//    var percentChange = data[data.length - 1];
 //   _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _generateNonMetroBarChart (state, data) {
    var id = 'non-metro';
    var name = 'Non-Metropolitan Areas';
    var subtitle = '(population of fewer than 10,000)';
//    var percentChange = data[data.length - 1];
//    _appendPercentChange('#' + id + '-percent-change', percentChange);
    var cutData = _cutBarChartData(data);
    _createBarChart(cutData, id, name, subtitle);
}

function _cutBarChartData (data) {
    var cutData = [];
    cutData.push(Number(data.slice(4, 5)[0]));
    cutData.push(Number(data.slice(6, 7)[0]));
    return cutData;
}

function _createBarChart (data, id, name, subtitle) {
    var myChart = Highcharts.chart(id, {
        chart: {
            type: 'bar'
        },
        title: {
            text: name
        },
        subtitle: {
            text: subtitle
        },
        xAxis: {
            categories: ['', ''],
            labels: {
                enabled: false
            }
        },
        yAxis: {
            title: {
                text: ''
            },
            labels: {
                enabled: false
            }
        },
        legend: {
            enabled: false
        },
        colors: [
            '#E76946',
            '#FBB731'
        ],
        plotOptions: {
               series: {
                   pointPadding: 0,
                   groupPadding: 0,
                   colorByPoint: true
               }
           },
        series: [{
            data: data
        }]
    });
}
// end bar chart

// Line chart functions
function _createAreaChart (stateName, stateData) {
    var myChart = Highcharts.chart('crime-rate-chart', {
        chart: {
            type: 'area'
        },
        title: {
            text: 'Change in ' + stateName + '\'s Overall Violent Crime Rate (Incidents per 100,000 Residents), 2006–2016'
        },
        xAxis: {
            categories: ['2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016']
        },
        legend: {
            enabled: false
        },
        yAxis: {
            title: {
                text: ''
            }
        },
        series: [{
            name: stateName,
            data: stateData,
            color: '#66ccff',
            fillOpacity: 1
        }],
    });
}

function _generateLineChartData (state, title, type) {
   // var stateCSV = 'data/' + type + '-rate.csv';
   var stateCSV = 'data/prison-rearrest.csv';
    var stateData, stateName;
    $.get(stateCSV, function (csv) {
        var data = _csvToArray(csv);
        for (var i = 0; i < data.length; i++) {
            if (data[i][1] == state) {
                stateName = data[i][0];
//                percentChange = data[i][data[i].length - 1];
                stateData = _formatStateData(data[i]);
            }
        }
        var chartId = type + '-chart';
//        _appendPercentChange('#' + type + '-percent-change', percentChange);
        _createLineChart(stateName, stateData, title, chartId);
    });
}

function _createLineChart (stateName, stateData, title, chartId) {
    var myChart = Highcharts.chart(chartId, {
        chart: {
            type: 'line'
        },
        title: {
            text: title
        },
        xAxis: {
            categories: ['2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016']
        },
        legend: {
            enabled: false
        },
        yAxis: {
            title: {
                text: ''
            }
        },
        series: [{
            name: stateName,
            data: stateData
        }]
    });
}

function _csvToArray (csv) {
    rows  = csv.split("\n");
    return rows.map(function (row) {
        return row.split(",");
    });
};

function _formatStateData (data) {
    data.splice(0, 2);
    data.splice(-1, 1);
    data = data.map(Number);
    return data;
}
// end line chart functions<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

var d3 = require("d3");

/*
 Provides some functions which can be applied to an HTML element.
 */
module.exports = function(el) {
    var openButtons,
	currentOpenButton,
	closeButton,
	manuallyPositioned = false,
	manuallySized = false,
	content = el.append("div")
	    .classed("content", true);

    var visibility = function(show, targetButton) {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);

	    if (show) {
		if (targetButton !== undefined) {
		    currentOpenButton = targetButton;

		} else if (currentOpenButton === undefined) {
		    currentOpenButton = d3.select(openButtons.node());
		}
		currentOpenButton.classed("element-visible", true);
	    }
	}
	el.style("visibility", show ? "visible" : "hidden");
    };

    var disable = function() {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);
	}

	el.style("visibility", "hidden");
    };

    var toggle = function(button) {
	// if it's not visible, open it with the button
	var wasVisible = (el.style("visibility") === "visible");

	visibility(
	    !(wasVisible && currentOpenButton && button.node() === currentOpenButton.node()),
	    button
	);
    };

    el
	.style("overflow", "hidden");

    var m = {
	drag: function() {
	    el
		.style("cursor", "move")
		.style("position", "absolute");

	    if(el.style("left") === "auto") {
		el.style("left", 0);
	    }
	    if(el.style("top") === "auto") {
		el.style("top", 0);
	    }

	    el.call(
		d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("left")),
			    "y" : parseInt(el.style("top"))
			};
		    })
		    .on("drag", function(d){
			d3.event.sourceEvent.preventDefault();
			el
			    .style("top", d3.event.y + "px")
			    .style("left", d3.event.x + "px");
			manuallyPositioned = true;
		    })
	    );

	    return m;
	},

	/*
	 Allows the dialogue to be shown and hidden by buttons, which are other elements.
	 */
	open: function(buttons) {
	    if (buttons.empty()) {
		buttons = undefined;
		currentOpenButton = undefined;
		m.hide();
		return m;
	    } else {
		// If the current open button isn't in the selection, clear it.
		if (currentOpenButton) {
		    var current = buttons.filter(function(d, i) {
			return this === currentOpenButton.node();
		    });

		    if (current.empty()) {
			currentOpenButton = undefined;
		    }
		}

		buttons
		    .classed("open-button", true)
		    .on("click", function(d, i) {
			d3.event.preventDefault();
			toggle(d3.select(this));
		    });

		openButtons = buttons;

		visibility(m.visible());

		return m;
	    }
	},

	/*
	 Adds a hide button 'X' to the dialogue.
	 */
	close: function() {
	    var closeButton = el
	    // This padding provides space for the button.
		    .style("padding-right", "1.5em")
		    .append("span")
		    .classed("close-button", true)
		    .style("font-size", "x-large")
		    .style("font-family", "monospace")
		    .style("position", "absolute")
		    .style("top", "0")
		    .style("right", "5px")
		    .style("cursor", "pointer")
		    .html("X");

	    closeButton.on("click", disable);

	    return m;
	},

	/*
	 Adds a resize handle to the dialogue.
	 */
	resize: function() {
	    var dragHandle = d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("width")),
			    "y" : parseInt(el.style("height"))
			};
		    })
		    .on("dragstart", function(d){
			d3.event.sourceEvent.stopPropagation();
		    })
		    .on("drag", function(d){
			el.style("height", d3.event.y + "px");
			el.style("width", d3.event.x + "px");
			manuallySized = true;
		    });

	    el
	    // This padding prevents us from make the box too small to resize.
		.style("padding-bottom", "3em")
	    // This padding provides space for the button.
		.style("padding-right", "1.5em")
		.append("span")
		.classed("resize-dialogue", true)
		.style("font-size", "xx-large")
		.style("font-family", "monospace")
		.style("position", "absolute")
		.style("bottom", "0")
		.style("right", "5px")
		.html("⇘")
		.call(dragHandle);

	    return m;
	},

	hide: function() {
	    visibility(false);
	    return m;
	},

	show: function() {
	    visibility(true);
	    return m;
	},

	visible: function() {
	    return el.style("visibility") === "visible";
	},

	content: function() {
	    return content;
	},

	currentOpenButton: function() {
	    return currentOpenButton;
	},

	el: function() {
	    return el;
	},

	manuallySized: function() {
	    return manuallySized;
	},

	manuallyPositioned: function() {
	    return manuallyPositioned;
	},

	/*
	 Gets or sets the current size of the dialogue in [width, height] pixels
	 */
	size: function(value) {
	    if (value) {
		el
		    .style("width", value[0])
		    .style("height", value[1]);
		manuallySized = true;
	    }

	    return [
		parseInt(el.style("width")),
		parseInt(el.style("height"))
	    ];
	},

	/*
	 Gets or sets the current position of the dialogue relative to the top-left corner in [x, y] pixels.
	 */
	position: function(value) {
	    if (value) {
		el
		    .style("left", value[0])
		    .style("top", value[1]);
		manuallyPositioned = true;
	    }

	    return [
		parseInt(el.style("left")),
		parseInt(el.style("top"))
	    ];
	}
    };

    return m;
};
<commit_msg>Size tables in px.<commit_after>"use strict";

/*global module, require*/

var d3 = require("d3");

/*
 Provides some functions which can be applied to an HTML element.
 */
module.exports = function(el) {
    var openButtons,
	currentOpenButton,
	closeButton,
	manuallyPositioned = false,
	manuallySized = false,
	content = el.append("div")
	    .classed("content", true);

    var visibility = function(show, targetButton) {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);

	    if (show) {
		if (targetButton !== undefined) {
		    currentOpenButton = targetButton;

		} else if (currentOpenButton === undefined) {
		    currentOpenButton = d3.select(openButtons.node());
		}
		currentOpenButton.classed("element-visible", true);
	    }
	}
	el.style("visibility", show ? "visible" : "hidden");
    };

    var disable = function() {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);
	}

	el.style("visibility", "hidden");
    };

    var toggle = function(button) {
	// if it's not visible, open it with the button
	var wasVisible = (el.style("visibility") === "visible");

	visibility(
	    !(wasVisible && currentOpenButton && button.node() === currentOpenButton.node()),
	    button
	);
    };

    el
	.style("overflow", "hidden");

    var m = {
	drag: function() {
	    el
		.style("cursor", "move")
		.style("position", "absolute");

	    if(el.style("left") === "auto") {
		el.style("left", 0);
	    }
	    if(el.style("top") === "auto") {
		el.style("top", 0);
	    }

	    el.call(
		d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("left")),
			    "y" : parseInt(el.style("top"))
			};
		    })
		    .on("drag", function(d){
			d3.event.sourceEvent.preventDefault();
			el
			    .style("top", d3.event.y + "px")
			    .style("left", d3.event.x + "px");
			manuallyPositioned = true;
		    })
	    );

	    return m;
	},

	/*
	 Allows the dialogue to be shown and hidden by buttons, which are other elements.
	 */
	open: function(buttons) {
	    if (buttons.empty()) {
		buttons = undefined;
		currentOpenButton = undefined;
		m.hide();
		return m;
	    } else {
		// If the current open button isn't in the selection, clear it.
		if (currentOpenButton) {
		    var current = buttons.filter(function(d, i) {
			return this === currentOpenButton.node();
		    });

		    if (current.empty()) {
			currentOpenButton = undefined;
		    }
		}

		buttons
		    .classed("open-button", true)
		    .on("click", function(d, i) {
			d3.event.preventDefault();
			toggle(d3.select(this));
		    });

		openButtons = buttons;

		visibility(m.visible());

		return m;
	    }
	},

	/*
	 Adds a hide button 'X' to the dialogue.
	 */
	close: function() {
	    var closeButton = el
	    // This padding provides space for the button.
		    .style("padding-right", "1.5em")
		    .append("span")
		    .classed("close-button", true)
		    .style("font-size", "x-large")
		    .style("font-family", "monospace")
		    .style("position", "absolute")
		    .style("top", "0")
		    .style("right", "5px")
		    .style("cursor", "pointer")
		    .html("X");

	    closeButton.on("click", disable);

	    return m;
	},

	/*
	 Adds a resize handle to the dialogue.
	 */
	resize: function() {
	    var dragHandle = d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("width")),
			    "y" : parseInt(el.style("height"))
			};
		    })
		    .on("dragstart", function(d){
			d3.event.sourceEvent.stopPropagation();
		    })
		    .on("drag", function(d){
			el.style("height", d3.event.y + "px");
			el.style("width", d3.event.x + "px");
			manuallySized = true;
		    });

	    el
	    // This padding prevents us from make the box too small to resize.
		.style("padding-bottom", "3em")
	    // This padding provides space for the button.
		.style("padding-right", "1.5em")
		.append("span")
		.classed("resize-dialogue", true)
		.style("font-size", "xx-large")
		.style("font-family", "monospace")
		.style("position", "absolute")
		.style("bottom", "0")
		.style("right", "5px")
		.html("⇘")
		.call(dragHandle);

	    return m;
	},

	hide: function() {
	    visibility(false);
	    return m;
	},

	show: function() {
	    visibility(true);
	    return m;
	},

	visible: function() {
	    return el.style("visibility") === "visible";
	},

	content: function() {
	    return content;
	},

	currentOpenButton: function() {
	    return currentOpenButton;
	},

	el: function() {
	    return el;
	},

	manuallySized: function() {
	    return manuallySized;
	},

	manuallyPositioned: function() {
	    return manuallyPositioned;
	},

	/*
	 Gets or sets the current size of the dialogue in [width, height] pixels
	 */
	size: function(value) {
	    if (value) {
		el
		    .style("width", value[0] + "px")
		    .style("height", value[1] + "px");
		manuallySized = true;
	    }

	    return [
		parseInt(el.style("width")),
		parseInt(el.style("height"))
	    ];
	},

	/*
	 Gets or sets the current position of the dialogue relative to the top-left corner in [x, y] pixels.
	 */
	position: function(value) {
	    if (value) {
		el
		    .style("left", value[0] + "px")
		    .style("top", value[1] + "px");
		manuallyPositioned = true;
	    }

	    return [
		parseInt(el.style("left")),
		parseInt(el.style("top"))
	    ];
	}
    };

    return m;
};
<|endoftext|>


<commit_before>/*!

Scaffold2D 1.0.%buildNumber%

The MIT License (MIT)

Copyright (c) 2014 Bradford Kelly
brad@bradfordkelly.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */
var RenderModes = {WEBGL:0, CANVAS:1};
var ScaleModes = {WEBGL:0, CANVAS:1}; //canvas is faster, but webgl looks better

	function Scaffold() {

	}

	self.Scaffold = Scaffold;

	//Static vars
	Scaffold.camera = null;
	Scaffold.gravity = 0;
	Scaffold.keysDown = [];
	Scaffold.state=null;
	Scaffold.lastTime =0;
	Scaffold.currentFPS=0;
	Scaffold.timers = [];
	Scaffold.data = {};
	Scaffold.paused = false;
	Scaffold.gamepads = [];
	Scaffold.renderMode = RenderModes.WEBGL;
	Scaffold.scale = 1;
	Scaffold.scaleMode = ScaleModes.CANVAS;
	Scaffold.timeScale = 1;
	Scaffold.maxTimeScale = 2.5;
	Scaffold.soundAvailable = false;
	Scaffold.canvasFallback = true;
	Scaffold.nexState = null;

	//lookup for gamepad.button indexes
	Scaffold.gamepadLookup = {
		up:12,
		down:13,
		left:14,
		right:15,
		select:8,
		start:9,
		a: 0,
		b: 2,
		c: 1,
		d:3,
		l1:4,
		l2:6,
		r1:5,
		r2:7,
		l3:10,
		r3:11
	}

	Scaffold.prototype = {

	}

	Scaffold.init = function(canvas) {

	  	if (Scaffold.scaleMode == ScaleModes.CANVAS && Scaffold.scale!=1) {
	  		//scale the canvas
	  		canvas.style.width = canvas.width + 'px';
	  		canvas.style.height = canvas.height + 'px';
	  		canvas.width = Math.round(canvas.width/2);
	  		canvas.height = Math.round(canvas.height/2);
	  		Scaffold.scale = 1; //don't use this value

	  	}

		if (Scaffold.renderMode==0) {
			Scaffold.renderer = new RendererGL(canvas);
			if (!Scaffold.renderer.gl && Scaffold.canvasFallback) {
				Scaffold.renderMode = 1;
			}
		}
		if (Scaffold.renderMode==1) {
			Scaffold.renderer = new RendererCanvas(canvas);

		}

	  	if(Sound.init()) {
	  		Scaffold.soundAvailable = true;
	  	}

		Scaffold.camera = new Camera(canvas.width, canvas.height);

		//gamepads only currently supported by chrome and firefox
		if (navigator.userAgent.indexOf("Firefox")!=-1) {
			window.addEventListener('MozGamepadConnected', Scaffold.gamepadConnected, false);
    		window.addEventListener('MozGamepadDisconnected', Scaffold.gamepadDisconnected, false);
		} else if (navigator.userAgent.indexOf("Chrome")!=-1 && navigator.userAgent.indexOf("Mobile")==-1) {
			Scaffold.gamepads = navigator.webkitGetGamepads();
		}

		if (!self.requestAnimationFrame) {
			if (self.msRequestAnimationFrame) {
				self.requestAnimationFrame = self.msRequestAnimationFrame;
			} else if (self.mozRequestAnimationFrame) {
				self.requestAnimationFrame = self.mozRequestAnimationFrame;
			} else if (self.webkitRequestAnimationFrame) {
				self.requestAnimationFrame = self.webkitRequestAnimationFrame;
			} else if (self.oRequestAnimationFrame) {
				self.requestAnimationFrame = self.oRequestAnimationFrame;
			} else {
				//console.log("RequestAnimationFrame not found.");
				self.requestAnimationFrame = function(callback) {
					setInterval(callback, 16);
				}
			}
		}

	}

	//changes state, but lets the current state complete the update/render cycle
	Scaffold.setState = function(state) {
		Scaffold.nextState = state;
	}

	Scaffold.run = function() {
		if (Scaffold.nextState!=null) {
			Scaffold.state = Scaffold.nextState;
		}

		var d =Date.now();
	    var elapsedTime = d-Scaffold.lastTime;
	    if (Scaffold.lastTime==0) elapsedTime = 16.67;

	    Scaffold.timeScale = elapsedTime/16.67; //percentage based on 60 fps
	    if (Scaffold.timeScale > Scaffold.maxTimeScale) {
	    	Scaffold.timeScale = Scaffold.maxTimeScale;
	    } else if (Scaffold.timeScale<1) {
	    	Scaffold.timeScale=1; //cap at 100%
	    }
	    Scaffold.lastTime = d;

	    Scaffold.currentFPS = (1000/elapsedTime + .5) | 0;

	    if (!Scaffold.paused) {
			var i = Scaffold.timers.length;
			while(i--) {
				Scaffold.timers[i].update(elapsedTime);
			}

		    if (Scaffold.state!=null) {
		    	Scaffold.state.update(elapsedTime);
		    	if (Scaffold.renderMode==1) {
		    		Scaffold.renderer.context.clearRect(0,0, Scaffold.camera.bounds.width, Scaffold.camera.bounds.height);
		    	} else {
		    		Scaffold.renderer.startRender();
		    	}
		    	Scaffold.state.render();
		    }
	    }

	    requestAnimationFrame(Scaffold.run);
	};

	Scaffold.playSound = function(src) {
		this.loader.assets[src].play();
	};

	Scaffold.keyDown = function(e) {
		//if (e.keyCode >=37 && e.keyCode <=40) {
			Scaffold.keysDown[e.keyCode] = 1;

			/*
			 * Default keys:
			 *  "+ -" Volume control
			 *  "p" pause
			 */
			if (e.keyCode==189) {
				//volume down
				if (Sound.volume>0) {
					Sound.setVolume(Sound.volume-.1);
				}
			} else if (e.keyCode==187) {
				//volume up
				if (Sound.volume<1) {
					Sound.setVolume(Sound.volume+.1);
				}
			} if (e.keyCode==80) {
				Scaffold.paused = !Scaffold.paused;
			}
		//}
	}

	Scaffold.keyUp = function(e) {
		delete Scaffold.keysDown[e.keyCode];
	}

	Scaffold.gamepadConnected = function(e) {
		Scaffold.gamepads.push(e.gamepad);
	}

	Scaffold.gamepadDisconnected = function(e) {

	}

	Scaffold.collideSprites = function(a,b) {

	}

	Scaffold.gamepadDown = function(key) {

	}

	Scaffold.getOverlap = function(boundsA, boundsB) {

		var xBottomRight = Math.min(boundsB.x+boundsB.width, boundsA.x+boundsA.width);
		var xTopLeft = Math.max(boundsB.x,boundsA.x);

		var xOverlap = Math.max(0, xBottomRight - xTopLeft);

		var yBottomRight = Math.min(boundsB.y+boundsB.height, boundsA.y+boundsA.height);
		var yTopLeft = Math.max(boundsB.y, boundsA.y);

		var yOverlap = Math.max(0, (yBottomRight - yTopLeft));

		return {total : xOverlap * yOverlap, y:yOverlap, x:xOverlap};
	}

	Scaffold.resolveX = function(spA, spB) {

		var diffA = spA.x - spA.prevPos.x;
		var diffB = spB.x - spB.prevPos.x;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*2;

		var diffA = spA.x - spA.prevPos.x;
		var diffB = spB.x - spB.prevPos.x;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*1;

		if (diffA > diffB) {
			overlap = spA.x + spA.spriteWidth - spB.x;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.x - spB.spriteWidth - spB.x;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}

		if (diffA > diffB) {
			overlap = spA.x + spA.spriteWidth - spB.x;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.x - spB.spriteWidth - spB.x;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}

		if (!spA.moveable || spA.locked.left) {
			spB.x += overlap;
			spB.velocity.x *= -spB.bounce;
		} else if (!spB.moveable || spB.locked.right) {
			spA.x -= overlap;
			spA.velocity.x *= -spA.bounce;
		} else {
			spA.prevPos.x = spA.x;
			spB.prevPos.x = spB.x;
			spA.x -= overlap*.5;
			spB.x += overlap*.5;

			var vA = spB.velocity.x;
			var vB = spA.velocity.x;
			var average = (vA + vB) /2;

			spA.velocity.x = average;
			spB.velocity.x = average;
		}

	}

	Scaffold.resolveY = function(spA, spB) {
		var diffA = spA.y - spA.prevPos.y;
		var diffB = spB.y - spB.prevPos.y;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*2;

		//console.log(diffA + " " + diffB);

		if (diffA > diffB) {
			overlap = spA.y + spA.spriteHeight - spB.y;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.y - spB.y - spB.spriteHeight;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}
		if (!spA.moveable || spA.locked.top) {
			spB.y += overlap;
			spB.y = spA.y+spA.spriteHeight;
			spB.velocity.y *=-spB.bounce;
		} else if (!spB.moveable || spB.locked.bottom) {
			spA.y -= overlap;
			spA.velocity.y *= -spA.bounce;

		} else {

			spA.y -= overlap*.5;
			spB.y += overlap*.5;

			var vA = spB.velocity.y * ((spB.velocity.y>0)? 1: -1);
			var vB = spA.velocity.y * ((spA.velocity.y>0)? 1: -1);
			var average = (vA + vB) /2;

			spA.velocity.y = average * ((spA.velocity.y>0)?1:-1);
			spB.velocity.y = average * ((spA.velocity.y>0)?1:-1);

		}
	}

	//Collide Two sprites
	Scaffold.collide = function(spA, spB) {

		var overlap = Scaffold.getOverlap(spA.getBounds(), spB.getBounds());
		spA.colliding = false; spB.colliding = false;

		if (overlap.total>0) {

			if (spA.solidCollide && spB.solidCollide) {
				Scaffold.resolveY(spA, spB);
				if (spA.prevPos.y != spA.y || spB.prevPos.y!=spB.prevPos.y) { //could be part of a series of objects
					Scaffold.resolveX(spA, spB);
				}

			}

			//Do A
			var e = {top:0, bottom:0, left:0, right:0, type:spB.type, obj:spB};
			spA.colliding = true; spB.colliding = true;
			if (spA.onCollide!=null) {
				e = Scaffold.setDirection(spB,spA,e);
				spA.onCollide(e);
			}

			//Do B
			if (spB.onCollide!=null) {
				e = {top:0, bottom:0, left:0, right:0, type:spA.type, obj:spA};
				e = Scaffold.setDirection(spA,spB,e);
				spB.onCollide(e);
			}

		}
	}

	Scaffold.min= function() {
		var i=arguments.length;
		while(i--) {
			if (arguments[0]>arguments[i]) {
				arguments[0] = arguments[i];
			}
		}
		return arguments[0];
	}

	Scaffold.max = function() {
		var i=arguments.length;
		while(i--) {
			if (arguments[0]<arguments[i]) {
				arguments[0] = arguments[i];
			}
		}
		return arguments[0];
	}

	Scaffold.setDirection=function(a,b,event) {
		if (a.prevPos.x+a.spriteWidth<=b.prevPos.x) {
			event.left = 1;
		} else if (a.prevPos.x>=b.prevPos.x+b.spriteWidth) {
			event.right = 1;
		}
		if (a.prevPos.y+a.spriteHeight<=b.prevPos.y) {
			event.top = 1;
		} else if (a.prevPos.y>=b.prevPos.y+b.spriteHeight) {
			event.bottom = 1;
		}
		return event;
	}

	//Collide a sprite with a group
	Scaffold.collideGroup=function(sp,grp) {
			var objects = grp.quadTree.retrieve(sp);
			var i = objects.length;

			while (i--) {
				var obj = objects[i];
				Scaffold.collide(sp, obj);
			}
	}

	//collide two groups
	Scaffold.collideGroups = function(grpA, grpB) {
		var i = grpA.members.length;
		while (i--) {
			Scaffold.collideGroup(grpA.members[i],grpB);
		}
	}

    window.addEventListener('keydown', Scaffold.keyDown, false);
    window.addEventListener('keyup', Scaffold.keyUp, false);

<commit_msg>updated state changing<commit_after>/*!

Scaffold2D 1.0.%buildNumber%

The MIT License (MIT)

Copyright (c) 2014 Bradford Kelly
brad@bradfordkelly.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */
var RenderModes = {WEBGL:0, CANVAS:1};
var ScaleModes = {WEBGL:0, CANVAS:1}; //canvas is faster, but webgl looks better

	function Scaffold() {

	}

	self.Scaffold = Scaffold;

	//Static vars
	Scaffold.camera = null;
	Scaffold.gravity = 0;
	Scaffold.keysDown = [];
	Scaffold.state=null;
	Scaffold.lastTime =0;
	Scaffold.currentFPS=0;
	Scaffold.timers = [];
	Scaffold.data = {};
	Scaffold.paused = false;
	Scaffold.gamepads = [];
	Scaffold.renderMode = RenderModes.WEBGL;
	Scaffold.scale = 1;
	Scaffold.scaleMode = ScaleModes.CANVAS;
	Scaffold.timeScale = 1;
	Scaffold.maxTimeScale = 2.5;
	Scaffold.soundAvailable = false;
	Scaffold.canvasFallback = true;
	Scaffold.nexState = null;

	//lookup for gamepad.button indexes
	Scaffold.gamepadLookup = {
		up:12,
		down:13,
		left:14,
		right:15,
		select:8,
		start:9,
		a: 0,
		b: 2,
		c: 1,
		d:3,
		l1:4,
		l2:6,
		r1:5,
		r2:7,
		l3:10,
		r3:11
	}

	Scaffold.prototype = {

	}

	Scaffold.init = function(canvas) {

	  	if (Scaffold.scaleMode == ScaleModes.CANVAS && Scaffold.scale!=1) {
	  		//scale the canvas
	  		canvas.style.width = canvas.width + 'px';
	  		canvas.style.height = canvas.height + 'px';
	  		canvas.width = Math.round(canvas.width/2);
	  		canvas.height = Math.round(canvas.height/2);
	  		Scaffold.scale = 1; //don't use this value

	  	}

		if (Scaffold.renderMode==0) {
			Scaffold.renderer = new RendererGL(canvas);
			if (!Scaffold.renderer.gl && Scaffold.canvasFallback) {
				Scaffold.renderMode = 1;
			}
		}
		if (Scaffold.renderMode==1) {
			Scaffold.renderer = new RendererCanvas(canvas);

		}

	  	if(Sound.init()) {
	  		Scaffold.soundAvailable = true;
	  	}

		Scaffold.camera = new Camera(canvas.width, canvas.height);

		//gamepads only currently supported by chrome and firefox
		if (navigator.userAgent.indexOf("Firefox")!=-1) {
			window.addEventListener('MozGamepadConnected', Scaffold.gamepadConnected, false);
    		window.addEventListener('MozGamepadDisconnected', Scaffold.gamepadDisconnected, false);
		} else if (navigator.userAgent.indexOf("Chrome")!=-1 && navigator.userAgent.indexOf("Mobile")==-1) {
			Scaffold.gamepads = navigator.webkitGetGamepads();
		}

		if (!self.requestAnimationFrame) {
			if (self.msRequestAnimationFrame) {
				self.requestAnimationFrame = self.msRequestAnimationFrame;
			} else if (self.mozRequestAnimationFrame) {
				self.requestAnimationFrame = self.mozRequestAnimationFrame;
			} else if (self.webkitRequestAnimationFrame) {
				self.requestAnimationFrame = self.webkitRequestAnimationFrame;
			} else if (self.oRequestAnimationFrame) {
				self.requestAnimationFrame = self.oRequestAnimationFrame;
			} else {
				//console.log("RequestAnimationFrame not found.");
				self.requestAnimationFrame = function(callback) {
					setInterval(callback, 16);
				}
			}
		}

	}

	//changes state, but lets the current state complete the update/render cycle
	Scaffold.setState = function(state) {
		Scaffold.nextState = state;
	}

	Scaffold.run = function() {
		if (Scaffold.nextState!=null) {
			Scaffold.state = Scaffold.nextState;
		}

		var d =Date.now();
	    var elapsedTime = d-Scaffold.lastTime;
	    if (Scaffold.lastTime==0) elapsedTime = 16.67;

	    Scaffold.timeScale = elapsedTime/16.67; //percentage based on 60 fps
	    if (Scaffold.timeScale > Scaffold.maxTimeScale) {
	    	Scaffold.timeScale = Scaffold.maxTimeScale;
	    } else if (Scaffold.timeScale<1) {
	    	Scaffold.timeScale=1; //cap at 100%
	    }
	    Scaffold.lastTime = d;

	    Scaffold.currentFPS = (1000/elapsedTime + .5) | 0;

	    if (!Scaffold.paused) {
			var i = Scaffold.timers.length;
			while(i--) {
				Scaffold.timers[i].update(elapsedTime);
			}

		    if (Scaffold.state!=null) {
		    	Scaffold.state.update(elapsedTime);
		    	if (Scaffold.renderMode==1) {
		    		Scaffold.renderer.context.clearRect(0,0, Scaffold.camera.bounds.width, Scaffold.camera.bounds.height);
		    	} else {
		    		Scaffold.renderer.startRender();
		    	}
		    	Scaffold.state.render();
		    }
	    }

	    requestAnimationFrame(Scaffold.run);
	};

	Scaffold.playSound = function(src) {
		this.loader.assets[src].play();
	};

	Scaffold.keyDown = function(e) {
		//if (e.keyCode >=37 && e.keyCode <=40) {
			Scaffold.keysDown[e.keyCode] = 1;

			/*
			 * Default keys:
			 *  "+ -" Volume control
			 *  "p" pause
			 */
			if (e.keyCode==189) {
				//volume down
				if (Sound.volume>0) {
					Sound.setVolume(Sound.volume-.1);
				}
			} else if (e.keyCode==187) {
				//volume up
				if (Sound.volume<1) {
					Sound.setVolume(Sound.volume+.1);
				}
			} if (e.keyCode==80) {
				Scaffold.paused = !Scaffold.paused;
			}
		//}
	}

	Scaffold.keyUp = function(e) {
		delete Scaffold.keysDown[e.keyCode];
	}

	Scaffold.gamepadConnected = function(e) {
		Scaffold.gamepads.push(e.gamepad);
	}

	Scaffold.gamepadDisconnected = function(e) {

	}

	Scaffold.collideSprites = function(a,b) {

	}

	Scaffold.gamepadDown = function(key) {

	}

	Scaffold.getOverlap = function(boundsA, boundsB) {

		var xBottomRight = Math.min(boundsB.x+boundsB.width, boundsA.x+boundsA.width);
		var xTopLeft = Math.max(boundsB.x,boundsA.x);

		var xOverlap = Math.max(0, xBottomRight - xTopLeft);

		var yBottomRight = Math.min(boundsB.y+boundsB.height, boundsA.y+boundsA.height);
		var yTopLeft = Math.max(boundsB.y, boundsA.y);

		var yOverlap = Math.max(0, (yBottomRight - yTopLeft));

		return {total : xOverlap * yOverlap, y:yOverlap, x:xOverlap};
	}

	Scaffold.resolveX = function(spA, spB) {

		var diffA = spA.x - spA.prevPos.x;
		var diffB = spB.x - spB.prevPos.x;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*2;

		var diffA = spA.x - spA.prevPos.x;
		var diffB = spB.x - spB.prevPos.x;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*1;

		if (diffA > diffB) {
			overlap = spA.x + spA.spriteWidth - spB.x;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.x - spB.spriteWidth - spB.x;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}

		if (diffA > diffB) {
			overlap = spA.x + spA.spriteWidth - spB.x;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.x - spB.spriteWidth - spB.x;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}

		if (!spA.moveable || spA.locked.left) {
			spB.x += overlap;
			spB.velocity.x *= -spB.bounce;
		} else if (!spB.moveable || spB.locked.right) {
			spA.x -= overlap;
			spA.velocity.x *= -spA.bounce;
		} else {
			spA.prevPos.x = spA.x;
			spB.prevPos.x = spB.x;
			spA.x -= overlap*.5;
			spB.x += overlap*.5;

			var vA = spB.velocity.x;
			var vB = spA.velocity.x;
			var average = (vA + vB) /2;

			spA.velocity.x = average;
			spB.velocity.x = average;
		}

	}

	Scaffold.resolveY = function(spA, spB) {
		var diffA = spA.y - spA.prevPos.y;
		var diffB = spB.y - spB.prevPos.y;
		var diffTotal = Math.abs(diffA) + Math.abs(diffB);
		var overlap = 0;
		var tolerance = diffTotal + Scaffold.timeScale*2;

		//console.log(diffA + " " + diffB);

		if (diffA > diffB) {
			overlap = spA.y + spA.spriteHeight - spB.y;
			if (overlap > tolerance) {
				return;
			}
		} else if (diffA < diffB) {
			overlap = spA.y - spB.y - spB.spriteHeight;
			if (-overlap > tolerance) {
				return;
			}
		} else {
			return;
		}
		if (!spA.moveable || spA.locked.top) {
			spB.y += overlap;
			spB.y = spA.y+spA.spriteHeight;
			spB.velocity.y *=-spB.bounce;
		} else if (!spB.moveable || spB.locked.bottom) {
			spA.y -= overlap;
			spA.velocity.y *= -spA.bounce;

		} else {

			spA.y -= overlap*.5;
			spB.y += overlap*.5;

			var vA = spB.velocity.y * ((spB.velocity.y>0)? 1: -1);
			var vB = spA.velocity.y * ((spA.velocity.y>0)? 1: -1);
			var average = (vA + vB) /2;

			spA.velocity.y = average * ((spA.velocity.y>0)?1:-1);
			spB.velocity.y = average * ((spA.velocity.y>0)?1:-1);

		}
	}

	//Collide Two sprites
	Scaffold.collide = function(spA, spB) {

		var overlap = Scaffold.getOverlap(spA.getBounds(), spB.getBounds());
		spA.colliding = false; spB.colliding = false;

		if (overlap.total>0) {

			if (spA.solidCollide && spB.solidCollide) {
				Scaffold.resolveY(spA, spB);
				if (spA.prevPos.y != spA.y || spB.prevPos.y!=spB.prevPos.y) { //could be part of a series of objects
					Scaffold.resolveX(spA, spB);
				}

			}

			//Do A
			var e = {top:0, bottom:0, left:0, right:0, type:spB.type, obj:spB};
			spA.colliding = true; spB.colliding = true;
			if (spA.onCollide!=null) {
				e = Scaffold.setDirection(spB,spA,e);
				spA.onCollide(e);
			}

			//Do B
			if (spB.onCollide!=null) {
				e = {top:0, bottom:0, left:0, right:0, type:spA.type, obj:spA};
				e = Scaffold.setDirection(spA,spB,e);
				spB.onCollide(e);
			}

		}
	}

	Scaffold.min= function() {
		var i=arguments.length;
		while(i--) {
			if (arguments[0]>arguments[i]) {
				arguments[0] = arguments[i];
			}
		}
		return arguments[0];
	}

	Scaffold.max = function() {
		var i=arguments.length;
		while(i--) {
			if (arguments[0]<arguments[i]) {
				arguments[0] = arguments[i];
			}
		}
		return arguments[0];
	}

	Scaffold.setDirection=function(a,b,event) {
		if (a.prevPos.x+a.spriteWidth<=b.prevPos.x) {
			event.left = 1;
		} else if (a.prevPos.x>=b.prevPos.x+b.spriteWidth) {
			event.right = 1;
		}
		if (a.prevPos.y+a.spriteHeight<=b.prevPos.y) {
			event.top = 1;
		} else if (a.prevPos.y>=b.prevPos.y+b.spriteHeight) {
			event.bottom = 1;
		}
		return event;
	}

	//Collide a sprite with a group
	Scaffold.collideGroup=function(sp,grp) {
			var objects = grp.quadTree.retrieve(sp);
			var i = objects.length;

			while (i--) {
				var obj = objects[i];
				Scaffold.collide(sp, obj);
			}
	}

	//collide two groups
	Scaffold.collideGroups = function(grpA, grpB) {
		var i = grpA.members.length;
		while (i--) {
			Scaffold.collideGroup(grpA.members[i],grpB);
		}
	}

    window.addEventListener('keydown', Scaffold.keyDown, false);
    window.addEventListener('keyup', Scaffold.keyUp, false);

<|endoftext|>


<commit_before>var push = require('pushover-notifications');

module.exports.pair = function( socket ) {
	// socket is a direct channel to the front-end

	// this method is run when Homey.emit('list_devices') is run on the front-end
	// which happens when you use the template `list_devices`
	socket.on('list_devices', function( data, callback ) {

		var devices = [{
			data: {
				id				: tempUser,
				pushoverUser : tempUser,
				pushoverToken : tempToken
			},
			name: 'Pushover user'
		}];

		callback( null, devices );

	});

	socket.on('get_devices', function( data, callback ) {

		// Set passed pair settings in variables
		tempUser = data.pushoverUser;
		tempToken = data.pushoverToken;

		socket.emit ( 'continue', null );

	});

	socket.on('disconnect', function(){
			console.log("Pushover - User aborted pairing, or pairing is finished");
	})

}

Homey.manager('flow').on('action.pushoverSend_normal', function( callback, args ){
		console.log("Pushover notification - user id "+args.device.id);
		tempUser = args.device.pushoverUser;
		tempToken = args.device.pushoverToken;
		console.log("Pushover notification - Token id "+tempToken);
		var pMessage_normal = args.pushoverMessage_normal;
		pushoverSend_normal ( tempUser, tempToken, pMessage_normal );
    callback( null, true ); // we've fired successfully
});

Homey.manager('flow').on('action.pushoverSend_lowest', function( callback, args ){
		console.log("Pushover notification - user id "+args.device.id);
		tempUser = args.device.pushoverUser;
		tempToken = args.device.pushoverToken;
		console.log("Pushover notification - Token id "+tempToken);
		var pMessage_lowest = args.pushoverMessage_lowest;
		pushoverSend_lowest ( tempUser, tempToken, pMessage_lowest );
    callback( null, true ); // we've fired successfully
});

Homey.manager('flow').on('action.pushoverSend_low', function( callback, args ){
		console.log("Pushover notification - user id "+args.device.id);
		tempUser = args.device.pushoverUser;
		tempToken = args.device.pushoverToken;
		console.log("Pushover notification - Token id "+tempToken);
		var pMessage_low = args.pushoverMessage_low;
		pushoverSend_low ( tempUser, tempToken, pMessage_low );
    callback( null, true ); // we've fired successfully
});

Homey.manager('flow').on('action.pushoverSend_high', function( callback, args ){
		console.log("Pushover notification - user id "+args.device.id);
		tempUser = args.device.pushoverUser;
		tempToken = args.device.pushoverToken;
		console.log("Pushover notification - Token id "+tempToken);
		var pMessage_high = args.pushoverMessage_high;
		pushoverSend_high ( tempUser, tempToken, pMessage_high );
    callback( null, true ); // we've fired successfully
});

Homey.manager('flow').on('action.pushoverSend_normal_device', function( callback, args ){
		console.log("Pushover notification - user id "+args.device.id);
		tempUser = args.device.pushoverUser;
		tempToken = args.device.pushoverToken;
		console.log("Pushover notification - Token id "+tempToken);
		var pMessage_normal = args.pushoverMessage_normal_message;
		var pDevice = args.pushoverMessage_normal_device;
		pushoverSend_normal_device ( tempUser, tempToken, pMessage_normal, pDevice );
    callback( null, true ); // we've fired successfully
});

function pushoverSend_normal ( pUser, pToken , pMessage_normal) {
var p = new push( {
    user: pUser,
    token: pToken,
    // onerror: function(error) {},
    // update_sounds: true // update the list of sounds every day - will
    // prevent app from exiting.
});

var msg = {
    // These values correspond to the parameters detailed on https://pushover.net/api
    // 'message' is required. All other values are optional.
    message: pMessage_normal,   // required
    title: "Homey",
    priority: 0
};

p.send( msg, function( err, result ) {
    if ( err ) {
        throw err;
    }

    console.log( result );
});
}

function pushoverSend_normal_device ( pUser, pToken , pMessage_normal, pDevice) {
var p = new push( {
    user: pUser,
    token: pToken,
    // onerror: function(error) {},
    // update_sounds: true // update the list of sounds every day - will
    // prevent app from exiting.
});

var msg = {
    // These values correspond to the parameters detailed on https://pushover.net/api
    // 'message' is required. All other values are optional.
    message: pMessage_normal,   // required
    title: "Homey",
    device: pDevice,
    priority: 0,
};

p.send( msg, function( err, result ) {
    if ( err ) {
        throw err;
    }

    console.log( result );
});
}

function pushoverSend_lowest ( pUser, pToken , pMessage_lowest) {
var p = new push( {
    user: pUser,
    token: pToken,
    // onerror: function(error) {},
    // update_sounds: true // update the list of sounds every day - will
    // prevent app from exiting.
});

var msg = {
    // These values correspond to the parameters detailed on https://pushover.net/api
    // 'message' is required. All other values are optional.
    message: pMessage_lowest,   // required
    title: "Homey",
    priority: -2
};

p.send( msg, function( err, result ) {
    if ( err ) {
        throw err;
    }

    console.log( result );
});
}

function pushoverSend_low ( pUser, pToken , pMessage_low) {
var p = new push( {
    user: pUser,
    token: pToken,
    // onerror: function(error) {},
    // update_sounds: true // update the list of sounds every day - will
    // prevent app from exiting.
});

var msg = {
    // These values correspond to the parameters detailed on https://pushover.net/api
    // 'message' is required. All other values are optional.
    message: pMessage_low,   // required
    title: "Homey",
    priority: -1
};

p.send( msg, function( err, result ) {
    if ( err ) {
        throw err;
    }

    console.log( result );
});
}

function pushoverSend_high ( pUser, pToken , pMessage_high) {
var p = new push( {
    user: pUser,
    token: pToken,
    // onerror: function(error) {},
    // update_sounds: true // update the list of sounds every day - will
    // prevent app from exiting.
});

var msg = {
    // These values correspond to the parameters detailed on https://pushover.net/api
    // 'message' is required. All other values are optional.
    message: pMessage_high,   // required
    title: "Homey",
    priority: 1
};

p.send( msg, function( err, result ) {
    if ( err ) {
        throw err;
    }

    console.log( result );
});
}
<commit_msg>Delete driver.js<commit_after><|endoftext|>


<commit_before>/**
 * This file is part of Mobile Robot Framework.
 * Mobile Robot Framework is free software under the terms of GNU AFFERO GENERAL PUBLIC LICENSE.
 */
'use strict';

// Declare app level module which depends on views, and components
angular.module('myApp', [
  'ngRoute',
  'ngWebSocket',
  'ngMaterial',
  'angularCSS',
  'dcbImgFallback',
  'myApp.main',
  'myApp.roverMaster',
  'myApp.roverDrive',
  'myApp.roverObserve',
  'myApp.roverService',
  'myApp.logs',
  'myApp.settings',
  'myApp.info',
  'myApp.developer',
  'myApp.version',
  'myApp.dpad',
  'myApp.joystickService',
  'myApp.joystickDpadSwitch',
  'myApp.driverCard',
  'myApp.parkingSensors'
])
  .config(function ($mdThemingProvider) {
    $mdThemingProvider.theme('default')
      .primaryPalette('blue', {
        'default': '800',
        'hue-1': '200',
        'hue-2': '600',
        'hue-3': '800'
      })
      .accentPalette('green', {'default': '500'})
      .warnPalette('red');

    $mdThemingProvider.theme("success-toast");
    $mdThemingProvider.theme("alert-toast");
    $mdThemingProvider.theme("error-toast");
  })
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/main', {
      templateUrl: 'main/main.html',
      controller: 'MainCtrl'
    }).when('/drive', {
      templateUrl: 'roverDrive/roverDrive.html',
      controller: 'RoverDriveCtrl'
    }).when('/drive/driveonly', {
      templateUrl: 'roverDrive/roverDriveOnly.html',
      controller: 'RoverDriveCtrl'
    }).when('/drive/roverMaster', {
      templateUrl: 'roverMaster/roverMaster.html',
      controller: 'RoverMasterCtrl'
    }).when('/stop', {
      templateUrl: 'roverDrive/roverStop.html',
      controller: 'RoverDriveCtrl'
    }).when('/observe', {
      templateUrl: 'roverObserve/roverObserve.html',
      controller: 'RoverObserveCtrl'
    }).when('/observe/cameraController', {
      templateUrl: 'roverObserve/roverCameraController.html',
      controller: 'RoverObserveCtrl'
    }).when('/settings', {
      templateUrl: 'settings/settings.html',
      controller: 'SettingsCtrl'
    }).when('/logs', {
      templateUrl: 'logs/logs.html',
      controller: 'LogsCtrl'
    }).when('/info', {
      templateUrl: 'info/info.html',
      controller: 'InfoCtrl'
    }).when('/developer', {
      templateUrl: 'developer/developer.html',
      controller: 'DeveloperCtrl'
    }).otherwise({redirectTo: '/main'});

  }])
  .controller('SidebarCtrl', function ($scope, $timeout, $mdSidenav, $mdUtil, roverService) {
    $scope.roverService = roverService;

    $scope.closeSidebar = function () {
      $mdSidenav('sidebar').close();
    };

    $scope.toggleSidebar = $mdUtil.debounce(function () {
      console.log('toggle sidebar');
      $mdSidenav('sidebar').toggle();
    }, 200);

  })
;
<commit_msg>when the app gets startet the user will automatically be redirected to /observe.<commit_after>/**
 * This file is part of Mobile Robot Framework.
 * Mobile Robot Framework is free software under the terms of GNU AFFERO GENERAL PUBLIC LICENSE.
 */
'use strict';

// Declare app level module which depends on views, and components
angular.module('myApp', [
  'ngRoute',
  'ngWebSocket',
  'ngMaterial',
  'angularCSS',
  'dcbImgFallback',
  'myApp.main',
  'myApp.roverMaster',
  'myApp.roverDrive',
  'myApp.roverObserve',
  'myApp.roverService',
  'myApp.logs',
  'myApp.settings',
  'myApp.info',
  'myApp.developer',
  'myApp.version',
  'myApp.dpad',
  'myApp.joystickService',
  'myApp.joystickDpadSwitch',
  'myApp.driverCard',
  'myApp.parkingSensors'
])
  .config(function ($mdThemingProvider) {
    $mdThemingProvider.theme('default')
      .primaryPalette('blue', {
        'default': '800',
        'hue-1': '200',
        'hue-2': '600',
        'hue-3': '800'
      })
      .accentPalette('green', {'default': '500'})
      .warnPalette('red');

    $mdThemingProvider.theme("success-toast");
    $mdThemingProvider.theme("alert-toast");
    $mdThemingProvider.theme("error-toast");
  })
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/main', {
      templateUrl: 'main/main.html',
      controller: 'MainCtrl'
    }).when('/drive', {
      templateUrl: 'roverDrive/roverDrive.html',
      controller: 'RoverDriveCtrl'
    }).when('/drive/driveonly', {
      templateUrl: 'roverDrive/roverDriveOnly.html',
      controller: 'RoverDriveCtrl'
    }).when('/drive/roverMaster', {
      templateUrl: 'roverMaster/roverMaster.html',
      controller: 'RoverMasterCtrl'
    }).when('/stop', {
      templateUrl: 'roverDrive/roverStop.html',
      controller: 'RoverDriveCtrl'
    }).when('/observe', {
      templateUrl: 'roverObserve/roverObserve.html',
      controller: 'RoverObserveCtrl'
    }).when('/observe/cameraController', {
      templateUrl: 'roverObserve/roverCameraController.html',
      controller: 'RoverObserveCtrl'
    }).when('/settings', {
      templateUrl: 'settings/settings.html',
      controller: 'SettingsCtrl'
    }).when('/logs', {
      templateUrl: 'logs/logs.html',
      controller: 'LogsCtrl'
    }).when('/info', {
      templateUrl: 'info/info.html',
      controller: 'InfoCtrl'
    }).when('/developer', {
      templateUrl: 'developer/developer.html',
      controller: 'DeveloperCtrl'
    }).otherwise({redirectTo: '/observe'});

  }])
  .controller('SidebarCtrl', function ($scope, $timeout, $mdSidenav, $mdUtil, roverService) {
    $scope.roverService = roverService;

    $scope.closeSidebar = function () {
      $mdSidenav('sidebar').close();
    };

    $scope.toggleSidebar = $mdUtil.debounce(function () {
      console.log('toggle sidebar');
      $mdSidenav('sidebar').toggle();
    }, 200);

  })
;
<|endoftext|>


<commit_before>/* Login */
app.filter('startFrom', function() {
    return function(input, start) {
        if(input) {
            start = +start; //parse to int
            return input.slice(start);
        }
        return [];
    }
});

app.controller('ModalInstanceLogCtrl',['$scope', '$location', '$routeSegment', '$http', '$timeout', datajson, function ($scope, $location, $routeSegment, $http, $timeout, datajson) {
    $scope.datajson = datajson;
}]);

app.controller('managefilesCtrl',['$scope','$location','$routeSegment','$http', '$timeout','$modal', '$sessionStorage', function($scope,$location,$routeSegment,$http, $timeout,$modal, $sessionStorage) {
	if($sessionStorage.isLoggedIn){
		$("#userDetails").html($sessionStorage.account.emailAddress);
	}
	$scope.sessionToken = $sessionStorage.sessionToken;
    Service.GetFilesListRECENT($http,
    	    //success
    	    function(data){
    	        $scope.listRECENT = data;
    	        $scope.currentPageRECENT = 1; //current page
    	        $scope.entryLimitRECENT = 10; //max no of items to display in a page
    	        $scope.filteredItemsRECENT = $scope.listRECENT.length; //Initially for no filter
    	        $scope.totalItemsRECENT = $scope.listRECENT.length;
    	    },$scope)

    	    $scope.setPageRECENT = function (pageNo) {
    	        $scope.currentPageRECENT = pageNo;
    	    };
    Service.GetFilesListSTAGING($http,
    //success
    function(data){
        $scope.listSTAGING = data;
        $scope.currentPageSTAGING = 1; //current page
        $scope.entryLimitSTAGING = 10; //max no of items to display in a page
        $scope.filteredItemsSTAGING = $scope.listSTAGING.length; //Initially for no filter
        $scope.totalItemsSTAGING = $scope.listSTAGING.length;
    },$scope)

    $scope.setPageSTAGING = function (pageNo) {
        $scope.currentPageSTAGING = pageNo;
    };

    Service.GetFilesListLIVE($http,
   //success
   function (data) {
       $scope.listLIVE = data;
       $scope.currentPageLIVE = 1; //current page
       $scope.entryLimitLIVE = 10; //max no of items to display in a page
       $scope.filteredItemsLIVE = $scope.listLIVE.length; //Initially for no filter
       $scope.totalItemsLIVE = $scope.listLIVE.length;
   },$scope)

    $scope.setPageLIVE = function (pageNo) {
        $scope.currentPageLIVE = pageNo;
    };

    Service.GetFilesListERROR($http,
  //success
  function (data) {
      $scope.listERROR = data;
      $scope.currentPageERROR = 1; //current page
      $scope.entryLimitERROR = 10; //max no of items to display in a page
      $scope.filteredItemsERROR = $scope.listERROR.length; //Initially for no filter
      $scope.totalItemsERROR = $scope.listERROR.length;
  },$scope)

    $scope.setPageERROR = function (pageNo) {
        $scope.currentPageERROR = pageNo;
    };

    Service.GetFilesListDELETED($http,
    		  //success
    		  function (data) {
    		      $scope.listDELETED = data;
    		      $scope.currentPageDELETED = 1; //current page
    		      $scope.entryLimitDELETED = 10; //max no of items to display in a page
    		      $scope.filteredItemsDELETED = $scope.listDELETED.length; //Initially for no filter
    		      $scope.totalItemsDELETED = $scope.listDELETED.length;
    		  },$scope)

    		    $scope.setPageDELETED = function (pageNo) {
    		        $scope.currentPageDELETED = pageNo;
    		    };

    		    $scope.openlog = function (id,year) {
    		        $scope.idForLog = id
    		        $scope.year = year;
    		Service.GetFilesLogList($http,
            //success
            function (data) {
                var modalInstance = $modal.open({
                    templateUrl: 'templates/partial/syncfilelogpopopup.html',
                    controller: 'ModalInstanceLogCtrl',
                    resolve: {
                        datajson: function () {
                            return data.bulkUploadActivities.bulkUploadActivities;
                        }
                    }
                });

            }, $scope)

      };
}]);
<commit_msg>Making minification work for the admin app<commit_after>/* Login */
app.filter('startFrom', function() {
    return function(input, start) {
        if(input) {
            start = +start; //parse to int
            return input.slice(start);
        }
        return [];
    }
});

app.controller('ModalInstanceLogCtrl',['$scope', '$location', '$routeSegment', '$http', '$timeout', 'datajson', function ($scope, $location, $routeSegment, $http, $timeout, datajson) {
    $scope.datajson = datajson;
}]);

app.controller('managefilesCtrl',['$scope','$location','$routeSegment','$http', '$timeout','$modal', '$sessionStorage', function($scope,$location,$routeSegment,$http, $timeout,$modal, $sessionStorage) {
	if($sessionStorage.isLoggedIn){
		$("#userDetails").html($sessionStorage.account.emailAddress);
	}
	$scope.sessionToken = $sessionStorage.sessionToken;
    Service.GetFilesListRECENT($http,
    	    //success
    	    function(data){
    	        $scope.listRECENT = data;
    	        $scope.currentPageRECENT = 1; //current page
    	        $scope.entryLimitRECENT = 10; //max no of items to display in a page
    	        $scope.filteredItemsRECENT = $scope.listRECENT.length; //Initially for no filter
    	        $scope.totalItemsRECENT = $scope.listRECENT.length;
    	    },$scope)

    	    $scope.setPageRECENT = function (pageNo) {
    	        $scope.currentPageRECENT = pageNo;
    	    };
    Service.GetFilesListSTAGING($http,
    //success
    function(data){
        $scope.listSTAGING = data;
        $scope.currentPageSTAGING = 1; //current page
        $scope.entryLimitSTAGING = 10; //max no of items to display in a page
        $scope.filteredItemsSTAGING = $scope.listSTAGING.length; //Initially for no filter
        $scope.totalItemsSTAGING = $scope.listSTAGING.length;
    },$scope)

    $scope.setPageSTAGING = function (pageNo) {
        $scope.currentPageSTAGING = pageNo;
    };

    Service.GetFilesListLIVE($http,
   //success
   function (data) {
       $scope.listLIVE = data;
       $scope.currentPageLIVE = 1; //current page
       $scope.entryLimitLIVE = 10; //max no of items to display in a page
       $scope.filteredItemsLIVE = $scope.listLIVE.length; //Initially for no filter
       $scope.totalItemsLIVE = $scope.listLIVE.length;
   },$scope)

    $scope.setPageLIVE = function (pageNo) {
        $scope.currentPageLIVE = pageNo;
    };

    Service.GetFilesListERROR($http,
  //success
  function (data) {
      $scope.listERROR = data;
      $scope.currentPageERROR = 1; //current page
      $scope.entryLimitERROR = 10; //max no of items to display in a page
      $scope.filteredItemsERROR = $scope.listERROR.length; //Initially for no filter
      $scope.totalItemsERROR = $scope.listERROR.length;
  },$scope)

    $scope.setPageERROR = function (pageNo) {
        $scope.currentPageERROR = pageNo;
    };

    Service.GetFilesListDELETED($http,
    		  //success
    		  function (data) {
    		      $scope.listDELETED = data;
    		      $scope.currentPageDELETED = 1; //current page
    		      $scope.entryLimitDELETED = 10; //max no of items to display in a page
    		      $scope.filteredItemsDELETED = $scope.listDELETED.length; //Initially for no filter
    		      $scope.totalItemsDELETED = $scope.listDELETED.length;
    		  },$scope)

    		    $scope.setPageDELETED = function (pageNo) {
    		        $scope.currentPageDELETED = pageNo;
    		    };

    		    $scope.openlog = function (id,year) {
    		        $scope.idForLog = id
    		        $scope.year = year;
    		Service.GetFilesLogList($http,
            //success
            function (data) {
                var modalInstance = $modal.open({
                    templateUrl: 'templates/partial/syncfilelogpopopup.html',
                    controller: 'ModalInstanceLogCtrl',
                    resolve: {
                        'datajson': function () {
                            return data.bulkUploadActivities.bulkUploadActivities;
                        }
                    }
                });

            }, $scope)

      };
}]);
<|endoftext|>


<commit_before>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

// XXX sort does not yet support subkeys ('a.b') .. fix that!

LocalCollection._compileSort = function (spec) {
  var keys = [];
  var asc = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        keys.push(spec[i]);
        asc.push(true);
      } else {
        keys.push(spec[i][0]);
        asc.push(spec[i][1] !== "desc");
      }
    }
  } else if (typeof spec === "object") {
    for (key in spec) {
      keys.push(key);
      asc.push(!(spec[key] < 0));
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  if (keys.length === 0)
    return function () {return 0;};

  // eval() does not return a value in IE8, nor does the spec say it
  // should. Assign to a local to get the value, instead.
  var _func;
  var code = "_func = (function(c){return function(a,b){var x;";
  for (var i = 0; i < keys.length; i++) {
      var splittedKeys = keys[i].split(".");
      var keyString = "";
      for(o = 0;o<splittedKeys.length;o++){
        keyString  = keyString + "["+ JSON.stringify(splittedKeys[o]) +"]";
      }
      if (i !== 0){
        code += "if(x!==0)return x;";
      }
      code += "x=" + (asc[i] ? "" : "-") +
        "c(a" + keyString +",b"+keyString+");";
  }
  code += "return x;};})";
  eval(code);
  return _func(LocalCollection._f._cmp);
};
<commit_msg>Make sub-key sort check for undefined before dereferencing.<commit_after>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

LocalCollection._compileSort = function (spec) {
  var keys = [];
  var asc = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        keys.push(spec[i]);
        asc.push(true);
      } else {
        keys.push(spec[i][0]);
        asc.push(spec[i][1] !== "desc");
      }
    }
  } else if (typeof spec === "object") {
    for (key in spec) {
      keys.push(key);
      asc.push(!(spec[key] < 0));
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  if (keys.length === 0)
    return function () {return 0;};

  // eval() does not return a value in IE8, nor does the spec say it
  // should. Assign to a local to get the value, instead.
  var _func;
  var code = "_func = (function(c){return function(a,b){var x;";
  for (var i = 0; i < keys.length; i++) {
    // handle dotted subpaths. Make sure to avoid dereferencing
    // undefined if a subkey doesn't exist.
    var splittedKeys = keys[i].split(".");
    var keyString = "";
    var aCode = "a";
    var bCode = "b";
    for(var o = 0; o < splittedKeys.length; o++) {
      keyString  = keyString + "[" + JSON.stringify(splittedKeys[o]) + "]";
      aCode += '&&a' + keyString;
      bCode += '&&b' + keyString;
    }
    if (i !== 0){
      code += "if(x!==0)return x;";
    }
    code += "x=" + (asc[i] ? "" : "-") +
      "c(" + aCode + "," + bCode + ");";
  }
  code += "return x;};})";
  eval(code);
  return _func(LocalCollection._f._cmp);
};
<|endoftext|>


<commit_before>
var   cmd = require('./process')
    , path = require('path')
    , util = require('./util')

//caches a list of installed haxelibs for the remaining execution,
var libs = {};
var internal = {};

    function HaxelibError(message) {
        this.name = "HaxelibError";
        this.message = message;
    }

    HaxelibError.prototype = Error.prototype;

        //caches all libs and values from haxelib list
    exports.init = function init(flow, done) {

            //always reset these because we are flushing cache
        libs = {};

            //find haxelib library path
        cmd.exec(flow, 'haxelib', ['config'], {quiet:true}, function(code, out, err) {

            if(code != 0) {
                var reason = '> haxelib config cannot be called. Is haxe/haxelib installed?\n';
                throw new HaxelibError(reason);
            }

            exports.haxelib_path = util.normalize(out.trim());

            flow.log(3, 'haxelib path %s', exports.haxelib_path);

                //find and cache the list

            cmd.exec(flow, 'haxelib', ['list'], {quiet:true}, function(lcode, lout, lerr) {

                var list = lout.trim();
                var name_ver = /^([0-9a-zA-Z-_]*)(:{1})\s(.*)$/igm;

                var match = name_ver.exec(list);
                while (match != null) {
                    var name = match[1];
                    libs[name] = { name:name, _versions_ : match[3] }
                    match = name_ver.exec(list);
                }

                internal.parse_versions();

                if(done) {
                    done();
                }

            });

        });

    } //init

    exports.current = function current(flow, name) {
        if(libs[name]) {
            return libs[name].versions['*'];
        } else {
            return null;
        }
    }

    exports.version = function version(flow, name, ver) {

        if(libs[name]) {
            return libs[name].versions[ver];
        } else {
            return null;
        }

    } //version

    exports.version_list = function version_list(flow, name) {

        var result = [];

        if(libs[name]) {
            var versions = libs[name].versions;
            for(index in versions) {
                if(index != '*') {
                    if(index == 'dev') {
                        result.push(index + ':' + versions[index]);
                    } else {
                        result.push(index);
                    }
                }
            }
        }

        return result.join(', ');

    } //version

    exports.path = function path(flow, name, version) {

            //current if none specified
        version = version || "*";

        flow.log(3, 'haxelib get path for %s(%s)', name, version );

        return libs[name].versions[version].path;

    } //path

    exports.get = function(flow, name) {

        return libs[name];

    } //get

internal.parse_versions = function() {

    for(lib in libs) {

        var _lib = libs[lib];
        var _vlist = _lib._versions_.split(' ');

        _lib.versions = {};

        for(index in _vlist) {

            var v = _vlist[index].trim();
            var current = v.indexOf('[') != -1;

                //strip [ ] if current
            if(current) {
                v = v.replace(/\[(.*)\]/gi,'$1');
            }

            var lib_path = '';
            if(v.substr(0,4) == 'dev:') {
                    //dev path is already here, so store it
                lib_path = v.replace(/dev:/gi,'');
                    //set name to dev
                v = 'dev';
            } else if(v == 'git') {
                    //git folder is in the root like so
                lib_path = path.join( exports.haxelib_path, lib, 'git' );
            } else {
                    //the other types becomes /v,e,r/
                lib_path = path.join( exports.haxelib_path, lib, v.replace(/\./gi,',') );
            }

            lib_path = util.normalize(lib_path, true);
            _lib.versions[v] = { version:v, path:lib_path };

            if(current) {
                _lib.versions['*'] = { version:v, path:lib_path };
            }

                //remove _versions_
            delete _lib._versions_;

        } //each in vlist
    } //each in libs

}<commit_msg>haxelib; add some more logging<commit_after>
var   cmd = require('./process')
    , path = require('path')
    , util = require('./util')

//caches a list of installed haxelibs for the remaining execution,
var libs = {};
var internal = {};

    function HaxelibError(message) {
        this.name = "HaxelibError";
        this.message = message;
    }

    HaxelibError.prototype = Error.prototype;

        //caches all libs and values from haxelib list
    exports.init = function init(flow, done) {

            //always reset these because we are flushing cache
        libs = {};

            //find haxelib library path
        cmd.exec(flow, 'haxelib', ['config'], {quiet:true}, function(code, out, err) {

            if(code != 0) {
                var reason = '> haxelib config cannot be called. Is haxe/haxelib installed?\n';
                throw new HaxelibError(reason);
            }

            exports.haxelib_path = util.normalize(out.trim());

            flow.log(3, 'haxelib path %s', exports.haxelib_path);

                //find and cache the list

            cmd.exec(flow, 'haxelib', ['list'], {quiet:true}, function(lcode, lout, lerr) {

                var list = lout.trim();
                var name_ver = /^([0-9a-zA-Z-_]*)(:{1})\s(.*)$/igm;

                var match = name_ver.exec(list);
                while (match != null) {
                    var name = match[1];
                    libs[name] = { name:name, _versions_ : match[3] }
                    match = name_ver.exec(list);
                }

                internal.parse_versions(flow);

                if(done) {
                    done();
                }

            });

        });

    } //init

    exports.current = function current(flow, name) {
        if(libs[name]) {
            return libs[name].versions['*'];
        } else {
            return null;
        }
    }

    exports.version = function version(flow, name, ver) {

        if(libs[name]) {
            return libs[name].versions[ver];
        } else {
            return null;
        }

    } //version

    exports.version_list = function version_list(flow, name) {

        var result = [];

        if(libs[name]) {
            var versions = libs[name].versions;
            for(index in versions) {
                if(index != '*') {
                    if(index == 'dev') {
                        result.push(index + ':' + versions[index]);
                    } else {
                        result.push(index);
                    }
                }
            }
        }

        return result.join(', ');

    } //version

    exports.path = function path(flow, name, version) {

            //current if none specified
        version = version || "*";

        flow.log(3, 'haxelib get path for %s(%s)', name, version );

        return libs[name].versions[version].path;

    } //path

    exports.get = function(flow, name) {

        return libs[name];

    } //get

internal.parse_versions = function(flow) {

    for(lib in libs) {

        var _lib = libs[lib];
        var _vlist = _lib._versions_.split(' ');

        _lib.versions = {};

        for(index in _vlist) {

            var v = _vlist[index].trim();
            var current = v.indexOf('[') != -1;

                //strip [ ] if current
            if(current) {
                v = v.replace(/\[(.*)\]/gi,'$1');
            }

            var lib_path = '';
            if(v.substr(0,4) == 'dev:') {
                    //dev path is already here, so store it
                lib_path = v.replace(/dev:/gi,'');
                    //set name to dev
                v = 'dev';
            } else if(v == 'git') {
                    //git folder is in the root like so
                lib_path = path.join( exports.haxelib_path, lib, 'git' );
            } else {
                    //the other types becomes /v,e,r/
                lib_path = path.join( exports.haxelib_path, lib, v.replace(/\./gi,',') );
            }

            lib_path = util.normalize(lib_path, true);
            _lib.versions[v] = { version:v, path:lib_path };

            if(current) {
                _lib.versions['*'] = { version:v, path:lib_path };
            }

            flow.log(3, '    haxelib - lib %s', lib, _lib);

                //remove _versions_
            delete _lib._versions_;

        } //each in vlist
    } //each in libs

}<|endoftext|>