<commit_before>// load dummy data
require('./data_nodes');

// vars
var previousIndex = 0;
var pointIndex = 0;
var currentNode = 0;
// network load color array for use in order of 10
// order is from red to green for modulo purpose
// var colorArray = [
// "#F33B3B",
// "#D9473A",
// "#C05439",
// "#A76139",
// "#8D6E38",
// "#747A38",
// "#5B8737",
// "#419437",
// "#28A136",
// "#0FAE36"
// ]

var colorArray = [
"#F33B3B",
"#F33BAA",
"#793BF3",
"#3BB0F3",
"#3BF37F"
]

// update and highlight functions
$(document).ready(function() {
    updateCurrentNode('overall');
});

function updateCurrentNode(id) {
    var index = nodes.indexOf(id);
    if (index < 0) {
        currentNode = numberOfNodes;
    } else {
        currentNode = index;
    }
    $("#currentNodeLabel").text(id);
    updateDataSources();
    update();
    showHideCharts();
}

function updateDataSources() {
    cpuChart.data.datasets[0].data = cpuData[currentNode];
    cpuChart.update();
    if (currentNode < numberOfNodes) {
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            portCharts[i].data.datasets[0].data = throughputData[currentNode][i];
            portCharts[i].data.datasets[1].data = latencyData[currentNode][i];
            portCharts[i].data.datasets[2].data = dropPacketData[currentNode][i];
            portCharts[i].update();
        }
    } else {
        networkChart.data.datasets[0].data = networkData_overall;
        networkChart.update();
    }
}

function update() {
    updateHighlights();
    updateLabels();
}

function updateHighlights() {
    highlightPointOnCharts();
    highlightOverallNetworkLoad();
    highlightNetworkLoad();
}

function updateLabels() {
    $("#currentTimeLabel").text(pointIndex);
}

function highlightPointOnCharts() {
    var cpuMeta = cpuChart.getDatasetMeta(0);
    var networkMeta = networkChart.getDatasetMeta(0);

    // Reset previous point
    var cpuOldPoint = cpuMeta.data[previousIndex];
    cpuOldPoint.custom = cpuOldPoint.custom || {};
    cpuOldPoint.custom.backgroundColor = "#fff";
    cpuOldPoint.custom.radius = 3;

    //Get point object and change the radius/color
    var cpuPoint = cpuMeta.data[pointIndex];
    cpuPoint.custom = cpuPoint.custom || {};
    cpuPoint.custom.backgroundColor = "#828282";
    cpuPoint.custom.radius = 5;

    // first parameter to update is the animation duration.
    // if none is specified, the config animation duration
    // is used. Using 0 here will do the draw immediately.
    cpuChart.update();

    if (currentNode < numberOfNodes) {
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            var portMeta1 = portCharts[i].getDatasetMeta(0);
            var portMeta2 = portCharts[i].getDatasetMeta(1);
            var portMeta3 = portCharts[i].getDatasetMeta(2);

            // Reset previous point
            var portOldPoint1 = portMeta1.data[previousIndex];
            var portOldPoint2 = portMeta2.data[previousIndex];
            var portOldPoint3 = portMeta3.data[previousIndex];
            portOldPoint1.custom = portOldPoint1.custom || {};
            portOldPoint2.custom = portOldPoint2.custom || {};
            portOldPoint3.custom = portOldPoint3.custom || {};
            portOldPoint1.custom.backgroundColor = "#fff";
            portOldPoint2.custom.backgroundColor = "#fff";
            portOldPoint3.custom.backgroundColor = "#fff";
            portOldPoint1.custom.radius = 3;
            portOldPoint2.custom.radius = 3;
            portOldPoint3.custom.radius = 3;

            //Get point object and change the radius/color
            var portPoint1 = portMeta1.data[pointIndex];
            var portPoint2 = portMeta2.data[pointIndex];
            var portPoint3 = portMeta3.data[pointIndex];
            portPoint1.custom = portPoint1.custom || {};
            portPoint2.custom = portPoint2.custom || {};
            portPoint3.custom = portPoint3.custom || {};
            portPoint1.custom.backgroundColor = "#828282";
            portPoint2.custom.backgroundColor = "#828282";
            portPoint3.custom.backgroundColor = "#828282";
            portPoint1.custom.radius = 5;
            portPoint2.custom.radius = 5;
            portPoint3.custom.radius = 5;

            portCharts[i].update();
        }
    } else {
        var networkOldPoint = networkMeta.data[previousIndex];
        networkOldPoint.custom = networkOldPoint.custom || {};
        networkOldPoint.custom.backgroundColor = "#fff";

        networkOldPoint.custom.radius = 3;
        var networkPoint = networkMeta.data[pointIndex];
        networkPoint.custom = networkPoint.custom || {};
        networkPoint.custom.backgroundColor = "#828282";

        networkPoint.custom.radius = 5;
        networkChart.update();
    }

    previousIndex = pointIndex;
}

function highlightNetworkLoad() {
    if (currentNode != numberOfNodes) {
        cy.nodes().style({ 'background-color':'gray' });
        if (cpuData[currentNode][pointIndex] > 70) {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'red' });
        } else if (cpuData[currentNode][pointIndex] > 40) {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'orange' });
        } else {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'green' });
        }
        cy.edges().style({ 'line-color':'gray' });
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            if (throughputData[currentNode][i][pointIndex] > 7) {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'red' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'red' });
            } else if (throughputData[currentNode][i][pointIndex] > 4) {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'orange' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'orange' });
            } else {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'green' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'green' });
            }
        }
    }
}

function highlightOverallNetworkLoad() {
    for (i = 0; i < nodes.length; i++) {
        var index = cpuData[i][pointIndex] % 5;
        cy.edges().style({'line-color': colorArray[index]});
        cy.nodes('#' + nodes[i]).style({'background-color': colorArray[index]});
    }
    // cy.nodes().forEach(function( ele, i) {
    //     if (ele.id().lastIndexOf("isp", 0) == -1) {
    //         // search for nodes whose id is not a 'ispXXX' which is a parent node holding the cluster
    //         // lastIndexOf returns -1 if does not match
    //         // we want to color all other nodes instead
    //         console.log(i + ":" + ele.id());
    //     }
    // });
    // console.log(cpuData[currentNode][pointIndex])
    // console.log(ele.id)

    // cy.nodes().forEach(function( ele, i ){
    //     console.log("index is " + i)
    //     console.log("it works" + currentNode)
    // });
}

// reset nodes and edges colors for mouse click on cy container
function resetNodesAndEdgesColors() {
    cy.nodes().style({ 'background-color':'gray' });
    cy.edges().style({ 'line-color':'gray' });
}

function showHideCharts() {
    if (currentNode < numberOfNodes) {
        if (!$('#placeholder-network').hasClass("no-visibility")) {
            $('#placeholder-network').addClass("no-visibility");
        }
        for (i = 1; i <= 5; i++) {
            if (i <= numberOfPorts[currentNode]) {
                if ($('#placeholder-row' + i).hasClass("no-visibility")) {
                    $('#placeholder-row' + i).removeClass("no-visibility");
                }
            } else {
                if (!$('#placeholder-row' + i).hasClass("no-visibility")) {
                    $('#placeholder-row' + i).addClass("no-visibility");
                }
            }
        }
    } else {
        if ($('#placeholder-network').hasClass("no-visibility")) {
            $('#placeholder-network').removeClass("no-visibility");
        }
        for (i = 1; i <= 5; i++) {
            if (!$('#placeholder-row' + i).hasClass("no-visibility")) {
                $('#placeholder-row' + i).addClass("no-visibility");
            }
        }
    }
}

// button functions
$('#startButton').on('click', function () {
    pointIndex = $('#ex1').slider('getAttribute', 'min');
    $('#ex1').slider('setValue', pointIndex);
    update();
});
$('#endButton').on('click', function () {
    pointIndex = $('#ex1').slider('getAttribute', 'max');
    $('#ex1').slider('setValue', pointIndex);
    update();
});
var isPlaying = false;
$('#playPauseButton').on('click', function () {
    if (isPlaying) {
        isPlaying = false;
        $('#playPauseIcon').removeClass('glyphicon-pause').addClass('glyphicon-play');
    } else {
        isPlaying = true;
        $('#playPauseIcon').removeClass('glyphicon-play').addClass('glyphicon-pause');
        if (pointIndex == $('#ex1').slider('getAttribute', 'max')) {
            pointIndex = $('#ex1').slider('getAttribute', 'min');
            $('#ex1').slider('setValue', pointIndex);
            update();
            window.setTimeout(playbackTicker, 500);
        } else {
            playbackTicker();
        }
    }
});
function playbackTicker() {
    if (isPlaying && pointIndex < $('#ex1').slider('getAttribute', 'max')) {
        pointIndex++;
        $('#ex1').slider('setValue', pointIndex);
        update();
        window.setTimeout(playbackTicker, 500);
    } else if (isPlaying && pointIndex >= $('#ex1').slider('getAttribute', 'max')) {
        isPlaying = false;
        $('#playPauseIcon').removeClass('glyphicon-pause').addClass('glyphicon-play');
    }
}

// slider
$('#ex1').slider({
    formatter: function(value) {
        return 'Current time: ' + value;
    }
});
$("#ex1").on("slide", function(slideEvt) {
    pointIndex = slideEvt.value;
    update();
});
$("#ex1").on("slideStop", function(slideEvt) {
    pointIndex = slideEvt.value;
    update();
});

// topology
var cy = cytoscape({
    container: $('#cy'),
    elements: dataset,

    boxSelectionEnabled: false,
    autounselectify: true,

    layout: {
        name: 'cose-bilkent'
    },
    style: [
        {
            selector: 'node',
            style: {
                'label': 'data(label)',
                'text-valign': 'bottom',
                'text-halign': 'center'
            }
        },
        {
            selector: ':parent',
            style: {
                'background-opacity': '0.0',
                'background-fit': 'contain',
                'background-image': 'images/cloud.png',
                'background-image-opacity': '0.333',
                'border-width': 0
            }
        },
        {
            // add background image, class should be same as the one define in data_topology
            selector: '.switch',
            style: {
                'height': 30,
                'width': 50,
                'background-opacity': '0.0',
                'background-fit': 'contain',
                'background-image': 'images/switch.png'
            }
        }
    ]
});
cy.on('mouseover', 'node', function(event) {
    var node = event.cyTarget;
    node.qtip({
         content: 'id: ' + this.id(),
         show: {
            event: event.type,
            ready: true
         },
         hide: {
            event: 'mouseout unfocus'
         }
    }, event);
});
cy.on('click', function(event) {
    var node = event.cyTarget;
    if (node === cy) {
        updateCurrentNode('overall');
        // resetNodesAndEdgesColors();
    } else {
        updateCurrentNode(node.id());
    }
});

require('./chart_styles');

// cpu chart
var cpuCanvas = document.getElementById("cpu-chart");
cpuCanvas.width = parseInt($('#well1').css('width'), 10);
cpuCanvas.height = parseInt($('#well1').css('height'), 10);
var cpuChart = new Chart(cpuCanvas, {
    type: 'line',
    data: cpuChartStyle
});

// network chart
var networkCanvas = document.getElementById("network-chart");
networkCanvas.width = parseInt($('#well2').css('width'), 10);
networkCanvas.height = parseInt($('#well2').css('height'), 10);
var networkChart = new Chart(networkCanvas, {
    type: 'line',
    data: networkChartStyle
});

// port charts
var portCanvas1 = document.getElementById("port-chart1");
portCanvas1.width = parseInt($('#well3').css('width'), 10);
portCanvas1.height = parseInt($('#well3').css('height'), 10);
var portChart1 = new Chart(portCanvas1, {
    type: "line",
    data: portChartStyle1,
    options: {
        title: {
            display: true,
            text: 'Port [0]'
        },
        scales: portChartScales
    }
});

var portCanvas2 = document.getElementById("port-chart2");
portCanvas2.width = parseInt($('#well4').css('width'), 10);
portCanvas2.height = parseInt($('#well4').css('height'), 10);
var portChart2 = new Chart(portCanvas2, {
    type: "line",
    data: portChartStyle2,
    options: {
        title: {
            display: true,
            text: 'Port [1]'
        },
        scales: portChartScales
    }
});

var portCanvas3 = document.getElementById("port-chart3");
portCanvas3.width = parseInt($('#well5').css('width'), 10);
portCanvas3.height = parseInt($('#well5').css('height'), 10);
var portChart3 = new Chart(portCanvas3, {
    type: "line",
    data: portChartStyle3,
    options: {
        title: {
            display: true,
            text: 'Port [2]'
        },
        scales: portChartScales
    }
});

var portCanvas4 = document.getElementById("port-chart4");
portCanvas4.width = parseInt($('#well6').css('width'), 10);
portCanvas4.height = parseInt($('#well6').css('height'), 10);
var portChart4 = new Chart(portCanvas4, {
    type: "line",
    data: portChartStyle4,
    options: {
        title: {
            display: true,
            text: 'Port [3]'
        },
        scales: portChartScales
    }
});

var portCanvas5 = document.getElementById("port-chart5");
portCanvas5.width = parseInt($('#well7').css('width'), 10);
portCanvas5.height = parseInt($('#well7').css('height'), 10);
var portChart5 = new Chart(portCanvas5, {
    type: "line",
    data: portChartStyle5,
    options: {
        title: {
            display: true,
            text: 'Port [4]'
        },
        scales: portChartScales
    }
});

portCharts = [
    portChart1,
    portChart2,
    portChart3,
    portChart4,
    portChart5];
<commit_msg>only add colors to overall side<commit_after>// load dummy data
require('./data_nodes');

// vars
var previousIndex = 0;
var pointIndex = 0;
var currentNode = 0;
// network load color array for use in order of 10
// order is from red to green for modulo purpose
// var colorArray = [
// "#F33B3B",
// "#D9473A",
// "#C05439",
// "#A76139",
// "#8D6E38",
// "#747A38",
// "#5B8737",
// "#419437",
// "#28A136",
// "#0FAE36"
// ]

var colorArray = [
"#F33B3B",
"#F33BAA",
"#793BF3",
"#3BB0F3",
"#3BF37F"
]

// update and highlight functions
$(document).ready(function() {
    updateCurrentNode('overall');
});

function updateCurrentNode(id) {
    var index = nodes.indexOf(id);
    if (index < 0) {
        currentNode = numberOfNodes;
    } else {
        currentNode = index;
    }
    $("#currentNodeLabel").text(id);
    updateDataSources();
    update();
    showHideCharts();
}

function updateDataSources() {
    cpuChart.data.datasets[0].data = cpuData[currentNode];
    cpuChart.update();
    if (currentNode < numberOfNodes) {
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            portCharts[i].data.datasets[0].data = throughputData[currentNode][i];
            portCharts[i].data.datasets[1].data = latencyData[currentNode][i];
            portCharts[i].data.datasets[2].data = dropPacketData[currentNode][i];
            portCharts[i].update();
        }
    } else {
        networkChart.data.datasets[0].data = networkData_overall;
        networkChart.update();
    }
}

function update() {
    updateHighlights();
    updateLabels();
}

function updateHighlights() {
    highlightPointOnCharts();
    highlightOverallNetworkLoad();
    highlightNetworkLoad();
}

function updateLabels() {
    $("#currentTimeLabel").text(pointIndex);
}

function highlightPointOnCharts() {
    var cpuMeta = cpuChart.getDatasetMeta(0);
    var networkMeta = networkChart.getDatasetMeta(0);

    // Reset previous point
    var cpuOldPoint = cpuMeta.data[previousIndex];
    cpuOldPoint.custom = cpuOldPoint.custom || {};
    cpuOldPoint.custom.backgroundColor = "#fff";
    cpuOldPoint.custom.radius = 3;

    //Get point object and change the radius/color
    var cpuPoint = cpuMeta.data[pointIndex];
    cpuPoint.custom = cpuPoint.custom || {};
    cpuPoint.custom.backgroundColor = "#828282";
    cpuPoint.custom.radius = 5;

    // first parameter to update is the animation duration.
    // if none is specified, the config animation duration
    // is used. Using 0 here will do the draw immediately.
    cpuChart.update();

    if (currentNode < numberOfNodes) {
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            var portMeta1 = portCharts[i].getDatasetMeta(0);
            var portMeta2 = portCharts[i].getDatasetMeta(1);
            var portMeta3 = portCharts[i].getDatasetMeta(2);

            // Reset previous point
            var portOldPoint1 = portMeta1.data[previousIndex];
            var portOldPoint2 = portMeta2.data[previousIndex];
            var portOldPoint3 = portMeta3.data[previousIndex];
            portOldPoint1.custom = portOldPoint1.custom || {};
            portOldPoint2.custom = portOldPoint2.custom || {};
            portOldPoint3.custom = portOldPoint3.custom || {};
            portOldPoint1.custom.backgroundColor = "#fff";
            portOldPoint2.custom.backgroundColor = "#fff";
            portOldPoint3.custom.backgroundColor = "#fff";
            portOldPoint1.custom.radius = 3;
            portOldPoint2.custom.radius = 3;
            portOldPoint3.custom.radius = 3;

            //Get point object and change the radius/color
            var portPoint1 = portMeta1.data[pointIndex];
            var portPoint2 = portMeta2.data[pointIndex];
            var portPoint3 = portMeta3.data[pointIndex];
            portPoint1.custom = portPoint1.custom || {};
            portPoint2.custom = portPoint2.custom || {};
            portPoint3.custom = portPoint3.custom || {};
            portPoint1.custom.backgroundColor = "#828282";
            portPoint2.custom.backgroundColor = "#828282";
            portPoint3.custom.backgroundColor = "#828282";
            portPoint1.custom.radius = 5;
            portPoint2.custom.radius = 5;
            portPoint3.custom.radius = 5;

            portCharts[i].update();
        }
    } else {
        var networkOldPoint = networkMeta.data[previousIndex];
        networkOldPoint.custom = networkOldPoint.custom || {};
        networkOldPoint.custom.backgroundColor = "#fff";

        networkOldPoint.custom.radius = 3;
        var networkPoint = networkMeta.data[pointIndex];
        networkPoint.custom = networkPoint.custom || {};
        networkPoint.custom.backgroundColor = "#828282";

        networkPoint.custom.radius = 5;
        networkChart.update();
    }

    previousIndex = pointIndex;
}

function highlightNetworkLoad() {
    if (currentNode != numberOfNodes) {
        cy.nodes().style({ 'background-color':'gray' });
        if (cpuData[currentNode][pointIndex] > 70) {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'red' });
        } else if (cpuData[currentNode][pointIndex] > 40) {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'orange' });
        } else {
            cy.nodes('#' + nodes[currentNode]).style({ 'background-color':'green' });
        }
        cy.edges().style({ 'line-color':'gray' });
        for (i = 0; i < numberOfPorts[currentNode]; i++) {
            if (throughputData[currentNode][i][pointIndex] > 7) {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'red' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'red' });
            } else if (throughputData[currentNode][i][pointIndex] > 4) {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'orange' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'orange' });
            } else {
                cy.elements('node#' + nodes[currentNode] + ', edge[source = "' + nodes[currentNode] + '"][sPort = ' + i + ']').style({ 'line-color':'green' });
                cy.elements('node#' + nodes[currentNode] + ', edge[target = "' + nodes[currentNode] + '"][tPort = ' + i + ']').style({ 'line-color':'green' });
            }
        }
    }
}

function highlightOverallNetworkLoad() {
    if (currentNode == numberOfNodes) {
        // overall
        for (i = 0; i < nodes.length; i++) {
            var index = cpuData[i][pointIndex] % 5;
            cy.edges().style({'line-color': colorArray[index]});
            cy.nodes('#' + nodes[i]).style({'background-color': colorArray[index]});
        }
    }
}

// reset nodes and edges colors for mouse click on cy container
function resetNodesAndEdgesColors() {
    cy.nodes().style({ 'background-color':'gray' });
    cy.edges().style({ 'line-color':'gray' });
}

function showHideCharts() {
    if (currentNode < numberOfNodes) {
        if (!$('#placeholder-network').hasClass("no-visibility")) {
            $('#placeholder-network').addClass("no-visibility");
        }
        for (i = 1; i <= 5; i++) {
            if (i <= numberOfPorts[currentNode]) {
                if ($('#placeholder-row' + i).hasClass("no-visibility")) {
                    $('#placeholder-row' + i).removeClass("no-visibility");
                }
            } else {
                if (!$('#placeholder-row' + i).hasClass("no-visibility")) {
                    $('#placeholder-row' + i).addClass("no-visibility");
                }
            }
        }
    } else {
        if ($('#placeholder-network').hasClass("no-visibility")) {
            $('#placeholder-network').removeClass("no-visibility");
        }
        for (i = 1; i <= 5; i++) {
            if (!$('#placeholder-row' + i).hasClass("no-visibility")) {
                $('#placeholder-row' + i).addClass("no-visibility");
            }
        }
    }
}

// button functions
$('#startButton').on('click', function () {
    pointIndex = $('#ex1').slider('getAttribute', 'min');
    $('#ex1').slider('setValue', pointIndex);
    update();
});
$('#endButton').on('click', function () {
    pointIndex = $('#ex1').slider('getAttribute', 'max');
    $('#ex1').slider('setValue', pointIndex);
    update();
});
var isPlaying = false;
$('#playPauseButton').on('click', function () {
    if (isPlaying) {
        isPlaying = false;
        $('#playPauseIcon').removeClass('glyphicon-pause').addClass('glyphicon-play');
    } else {
        isPlaying = true;
        $('#playPauseIcon').removeClass('glyphicon-play').addClass('glyphicon-pause');
        if (pointIndex == $('#ex1').slider('getAttribute', 'max')) {
            pointIndex = $('#ex1').slider('getAttribute', 'min');
            $('#ex1').slider('setValue', pointIndex);
            update();
            window.setTimeout(playbackTicker, 500);
        } else {
            playbackTicker();
        }
    }
});
function playbackTicker() {
    if (isPlaying && pointIndex < $('#ex1').slider('getAttribute', 'max')) {
        pointIndex++;
        $('#ex1').slider('setValue', pointIndex);
        update();
        window.setTimeout(playbackTicker, 500);
    } else if (isPlaying && pointIndex >= $('#ex1').slider('getAttribute', 'max')) {
        isPlaying = false;
        $('#playPauseIcon').removeClass('glyphicon-pause').addClass('glyphicon-play');
    }
}

// slider
$('#ex1').slider({
    formatter: function(value) {
        return 'Current time: ' + value;
    }
});
$("#ex1").on("slide", function(slideEvt) {
    pointIndex = slideEvt.value;
    update();
});
$("#ex1").on("slideStop", function(slideEvt) {
    pointIndex = slideEvt.value;
    update();
});

// topology
var cy = cytoscape({
    container: $('#cy'),
    elements: dataset,

    boxSelectionEnabled: false,
    autounselectify: true,

    layout: {
        name: 'cose-bilkent'
    },
    style: [
        {
            selector: 'node',
            style: {
                'label': 'data(label)',
                'text-valign': 'bottom',
                'text-halign': 'center'
            }
        },
        {
            selector: ':parent',
            style: {
                'background-opacity': '0.0',
                'background-fit': 'contain',
                'background-image': 'images/cloud.png',
                'background-image-opacity': '0.333',
                'border-width': 0
            }
        },
        {
            // add background image, class should be same as the one define in data_topology
            selector: '.switch',
            style: {
                'height': 30,
                'width': 50,
                'background-opacity': '0.0',
                'background-fit': 'contain',
                'background-image': 'images/switch.png'
            }
        }
    ]
});
cy.on('mouseover', 'node', function(event) {
    var node = event.cyTarget;
    node.qtip({
         content: 'id: ' + this.id(),
         show: {
            event: event.type,
            ready: true
         },
         hide: {
            event: 'mouseout unfocus'
         }
    }, event);
});
cy.on('click', function(event) {
    var node = event.cyTarget;
    if (node === cy) {
        updateCurrentNode('overall');
        // resetNodesAndEdgesColors();
    } else {
        updateCurrentNode(node.id());
    }
});

require('./chart_styles');

// cpu chart
var cpuCanvas = document.getElementById("cpu-chart");
cpuCanvas.width = parseInt($('#well1').css('width'), 10);
cpuCanvas.height = parseInt($('#well1').css('height'), 10);
var cpuChart = new Chart(cpuCanvas, {
    type: 'line',
    data: cpuChartStyle
});

// network chart
var networkCanvas = document.getElementById("network-chart");
networkCanvas.width = parseInt($('#well2').css('width'), 10);
networkCanvas.height = parseInt($('#well2').css('height'), 10);
var networkChart = new Chart(networkCanvas, {
    type: 'line',
    data: networkChartStyle
});

// port charts
var portCanvas1 = document.getElementById("port-chart1");
portCanvas1.width = parseInt($('#well3').css('width'), 10);
portCanvas1.height = parseInt($('#well3').css('height'), 10);
var portChart1 = new Chart(portCanvas1, {
    type: "line",
    data: portChartStyle1,
    options: {
        title: {
            display: true,
            text: 'Port [0]'
        },
        scales: portChartScales
    }
});

var portCanvas2 = document.getElementById("port-chart2");
portCanvas2.width = parseInt($('#well4').css('width'), 10);
portCanvas2.height = parseInt($('#well4').css('height'), 10);
var portChart2 = new Chart(portCanvas2, {
    type: "line",
    data: portChartStyle2,
    options: {
        title: {
            display: true,
            text: 'Port [1]'
        },
        scales: portChartScales
    }
});

var portCanvas3 = document.getElementById("port-chart3");
portCanvas3.width = parseInt($('#well5').css('width'), 10);
portCanvas3.height = parseInt($('#well5').css('height'), 10);
var portChart3 = new Chart(portCanvas3, {
    type: "line",
    data: portChartStyle3,
    options: {
        title: {
            display: true,
            text: 'Port [2]'
        },
        scales: portChartScales
    }
});

var portCanvas4 = document.getElementById("port-chart4");
portCanvas4.width = parseInt($('#well6').css('width'), 10);
portCanvas4.height = parseInt($('#well6').css('height'), 10);
var portChart4 = new Chart(portCanvas4, {
    type: "line",
    data: portChartStyle4,
    options: {
        title: {
            display: true,
            text: 'Port [3]'
        },
        scales: portChartScales
    }
});

var portCanvas5 = document.getElementById("port-chart5");
portCanvas5.width = parseInt($('#well7').css('width'), 10);
portCanvas5.height = parseInt($('#well7').css('height'), 10);
var portChart5 = new Chart(portCanvas5, {
    type: "line",
    data: portChartStyle5,
    options: {
        title: {
            display: true,
            text: 'Port [4]'
        },
        scales: portChartScales
    }
});

portCharts = [
    portChart1,
    portChart2,
    portChart3,
    portChart4,
    portChart5];
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path');

var staticAPI = function (settings) {
    this.parseSettings(settings);
    this.createJsonFolderStructure();

};

staticAPI.prototype = {
    defaultOptions: {
        outputFolder: 'data',
        useBackUps: true,
        pagination: true
    },
    parseSettings: function (settings) {
        if (typeof settings !== 'object') {
            throw('A settings object is needed');
        }
        this.settings = this.merge(this.defaultOptions, settings);
    },
    createJsonFolderStructure: function () {
        this.deleteFolderRecursive(this.settings.outputFolder);
        fs.mkdirSync(this.settings.outputFolder);
        this.currentDirectory = this.settings.outputFolder;
        this.writeJsonFile(path.join(this.currentDirectory, path.basename(this.currentDirectory, '/') + '.json'), this.settings.object);
        this.processDataRecursive(this.settings.object);

    },
    processDataRecursive: function (jsonObject) {
        for (var id in jsonObject) {
            if( jsonObject.hasOwnProperty( id ) ) {
                if(typeof jsonObject[id] === 'object') {
                    this.currentDirectory = path.join(this.currentDirectory, id);
                    fs.mkdirSync(this.currentDirectory);
                    this.writeJsonFile(path.join(this.currentDirectory, id + '.json'), jsonObject[id]);

                    console.log(id + ' is an object creating directory');

                    this.processDataRecursive(jsonObject[id]);
                }
            }

        }
        this.currentDirectory = path.join(this.currentDirectory, '../');

    },
    writeJsonFile: function (filePath, object) {
        fs.writeFileSync(filePath, JSON.stringify(object));
    },
    deleteFolderRecursive: function (path) {
        var files = [];
        var _this = this;
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file){
                var curPath = path + "/" + file;
                if(fs.statSync(curPath).isDirectory()) { // recurse
                    _this.deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    },
    merge: function (obj1, obj2) {
        for (var attrname in obj2) {
            if( obj2.hasOwnProperty( attrname ) ) {
                obj1[attrname] = obj2[attrname];
            }
        }
        return obj1;
    }

};

module.exports = staticAPI;<commit_msg>Removed console logs<commit_after>var fs = require('fs'),
    path = require('path');

var staticAPI = function (settings) {
    this.parseSettings(settings);
    this.createJsonFolderStructure();

};

staticAPI.prototype = {
    defaultOptions: {
        outputFolder: 'data',
        useBackUps: true,
        pagination: true
    },
    parseSettings: function (settings) {
        if (typeof settings !== 'object') {
            throw('A settings object is needed');
        }
        this.settings = this.merge(this.defaultOptions, settings);
    },
    createJsonFolderStructure: function () {
        this.deleteFolderRecursive(this.settings.outputFolder);
        fs.mkdirSync(this.settings.outputFolder);
        this.currentDirectory = this.settings.outputFolder;
        this.writeJsonFile(path.join(this.currentDirectory, path.basename(this.currentDirectory, '/') + '.json'), this.settings.object);
        this.processDataRecursive(this.settings.object);

    },
    processDataRecursive: function (jsonObject) {
        for (var id in jsonObject) {
            if( jsonObject.hasOwnProperty( id ) ) {
                if(typeof jsonObject[id] === 'object') {
                    this.currentDirectory = path.join(this.currentDirectory, id);
                    fs.mkdirSync(this.currentDirectory);
                    this.writeJsonFile(path.join(this.currentDirectory, id + '.json'), jsonObject[id]);
                    this.processDataRecursive(jsonObject[id]);
                }
            }

        }
        this.currentDirectory = path.join(this.currentDirectory, '../');

    },
    writeJsonFile: function (filePath, object) {
        fs.writeFileSync(filePath, JSON.stringify(object));
    },
    deleteFolderRecursive: function (path) {
        var files = [];
        var _this = this;
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file){
                var curPath = path + "/" + file;
                if(fs.statSync(curPath).isDirectory()) { // recurse
                    _this.deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    },
    merge: function (obj1, obj2) {
        for (var attrname in obj2) {
            if( obj2.hasOwnProperty( attrname ) ) {
                obj1[attrname] = obj2[attrname];
            }
        }
        return obj1;
    }

};

module.exports = staticAPI;<|endoftext|>


<commit_before>/** Virtual list, only renders visible items.
 *	@param {Array<*>} data         List of data items
 *	@param {Function} renderRow    Renders a single row
 *	@param {Number} rowHeight      Static height of a row
 *	@param {Number} overscanCount  Amount of rows to render above and below visible area of the list
 *	@example
 *		new VirtualList(element, {
 *			data: ['a', 'b', 'c'],
 *			renderRow: (row) => {
{row}
 },
 *			rowHeight: 150
 *		)}
 *
 * TODO:
 * – Add support for variable heights
 * – Add a scroll to index method
 * – Add an initial scroll offset or index option
 */

const STYLE_INNER = 'position:relative; overflow:hidden; width:100%; min-height:100%;';
const STYLE_CONTENT = 'position:absolute; top:0; left:0; height:100%; width:100%; overflow:visible;';

class VirtualList {
	constructor(container, options) {
		this.container = container;
		this.options = options;

		// Initialization
		this.state = {};

		let inner = this.inner = document.createElement('div');
		let content = this.content = document.createElement('div');

		inner.appendChild(content);
		container.appendChild(inner);

		// Binding
		this.render = this.render.bind(this);
		this.handleScroll = this.handleScroll.bind(this);
		this.resize = this.resize.bind(this);

		// Resize
		this.resize();

		// Add event listeners
		this.container.addEventListener('scroll', this.handleScroll);

		window.addEventListener('resize', this.resize);
	}

	setState(state = {}) {
		this.state = Object.assign(this.state, state);

		window.requestAnimationFrame(this.render);
	}

	resize() {
		if (this.state.height !== this.container.offsetHeight) {
			this.setState({
				height: this.container.offsetHeight
			});
		}
	};

	handleScroll() {
		this.setState({
			offset: this.container.scrollTop
		});
	};

	destroy() {
		window.removeEventListener('resize', this.resize);

		// TODO: Destroy everything properly, silly
	}

	render() {
		const {data, rowHeight, renderRow, overscanCount = 3} = this.options;
		const {offset = 0, height = 0} = this.state;

		// first visible row index
		let start = (offset / rowHeight)|0;

		// actual number of visible rows (without overscan)
		let visibleRowCount = (height / rowHeight)|0;

		// Overscan: render blocks of rows modulo an overscan row count
		// This dramatically reduces DOM writes during scrolling
		if (overscanCount) {
			start = Math.max(0, start - (start % overscanCount));
			visibleRowCount += overscanCount;
		}

		// last visible + overscan row index
		const end = start + 1 + visibleRowCount;

		// data slice currently in viewport plus overscan items
		const selection = data.slice(start, end);

		const fragment = document.createDocumentFragment();
		selection.forEach(row => fragment.append(renderRow(row)));

		this.inner.setAttribute('style', `${STYLE_INNER} height:${data.length*rowHeight}px;`);
		this.content.setAttribute('style', `${STYLE_CONTENT} top:${start*rowHeight}px;`);

		this.content.innerHTML = '';
		this.content.appendChild(fragment);
	}
}
<commit_msg>Switch to soft tabs<commit_after>/** Virtual list, only renders visible items.
 *  @param {Array<*>} data         List of data items
 *  @param {Function} renderRow    Renders a single row
 *  @param {Number} rowHeight      Static height of a row
 *  @param {Number} overscanCount  Amount of rows to render above and below visible area of the list
 *  @example
 *  new VirtualList(element, {
 *    data: ['a', 'b', 'c'],
 *    renderRow: (row) => {
{row}
 },
 *    rowHeight: 150
 *  )}
 *
 *  TODO:
 *  – Add support for variable heights
 *  – Add a scroll to index method
 *  – Add an initial scroll offset or index option
 */

const STYLE_INNER = 'position:relative; overflow:hidden; width:100%; min-height:100%;';
const STYLE_CONTENT = 'position:absolute; top:0; left:0; height:100%; width:100%; overflow:visible;';

class VirtualList {
  constructor(container, options) {
    this.container = container;
    this.options = options;

    // Initialization
    this.state = {};

    let inner = this.inner = document.createElement('div');
    let content = this.content = document.createElement('div');

    inner.appendChild(content);
    container.appendChild(inner);

    // Binding
    this.render = this.render.bind(this);
    this.handleScroll = this.handleScroll.bind(this);
    this.resize = this.resize.bind(this);

    // Resize
    this.resize();

    // Add event listeners
    this.container.addEventListener('scroll', this.handleScroll);

    window.addEventListener('resize', this.resize);
  }

  setState(state = {}) {
    this.state = Object.assign(this.state, state);

    window.requestAnimationFrame(this.render);
  }

  resize() {
    if (this.state.height !== this.container.offsetHeight) {
      this.setState({
        height: this.container.offsetHeight
      });
    }
  };

  handleScroll() {
    this.setState({
      offset: this.container.scrollTop
    });
  };

  destroy() {
    window.removeEventListener('resize', this.resize);

    // TODO: Destroy everything properly, silly
  }

  render() {
    const {data, rowHeight, renderRow, overscanCount = 3} = this.options;
    const {offset = 0, height = 0} = this.state;

    // first visible row index
    let start = (offset / rowHeight)|0;

    // actual number of visible rows (without overscan)
    let visibleRowCount = (height / rowHeight)|0;

    // Overscan: render blocks of rows modulo an overscan row count
    // This dramatically reduces DOM writes during scrolling
    if (overscanCount) {
      start = Math.max(0, start - (start % overscanCount));
      visibleRowCount += overscanCount;
    }

    // last visible + overscan row index
    const end = start + 1 + visibleRowCount;

    // data slice currently in viewport plus overscan items
    const selection = data.slice(start, end);

    const fragment = document.createDocumentFragment();
    selection.forEach(row => fragment.append(renderRow(row)));

    this.inner.setAttribute('style', `${STYLE_INNER} height:${data.length*rowHeight}px;`);
    this.content.setAttribute('style', `${STYLE_CONTENT} top:${start*rowHeight}px;`);

    this.content.innerHTML = '';
    this.content.appendChild(fragment);
  }
}
<|endoftext|>


<commit_before>var express = require('express');
var exphbs  = require('express-handlebars');
var app = express();
var BME280 = require('node-bme280');
var barometer = new BME280({address: 0x77});
var latestTemp;
var latestPressure;
var latestHumidity;
var ready = false;

var Datastore = require('nedb')
  , db = new Datastore({ filename: 'data.txt', autoload: true });

barometer.begin(function(err) {
    if (err) {
        console.info('error initializing barometer', err);
        return;
    }
    console.info('barometer running');
	setImmediate(readData);
	setInterval(readData, 60 * 1000);
});

var readData = function () {
	barometer.readPressureAndTemparature(function(err, pressure, temperature, humidity) {
		latestTemp = temperature.toFixed(2);
		latestPressure = (pressure / 100).toFixed(2);
		latestHumidity = humidity.toFixed(2);
		ready = true;
		db.insert({
			time: new Date(),
			ambientTemperature: latestTemp,
			pressure: latestPressure,
			humidity: latestHumidity
		});
	});
};

app.engine('handlebars', exphbs({defaultLayout: false}));
app.set('view engine', 'handlebars');
app.use(express.static('static'));

app.get('/', function (req, res) {
	/*res.write("<meta http-equiv=\"refresh\" content=\"5\"><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
	if (ready) {
		res.write("Temperature: " + latestTemp + " ℃
");
		res.write("Pressure: " + latestPressure + " hPa
");
		res.write("Humidity: " + latestHumidity + "%\n");
	} else {
		res.write("No data is available currently.");
	}
	res.end("");*/
	res.render("index", {
		ambientTemperature: latestTemp,
		pressure: latestPressure,
		humidity: latestHumidity
	});
});

app.get('/output.csv', function (req, res) {
	db.find({}).sort({ time: 1 }).exec(function (err, docs) {
		res.write("Time,Temperature,Pressure,Humidity\n");
		for (var i = 0; i < docs.length; i++) {
			var time = docs[i].time;
			var formattedDate = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
			var formattedTime = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
			var formattedDateTime = formattedDate + " " + formattedTime; // github doesn't like long lines
			res.write(formattedDateTime + ",");
			res.write(docs[i].ambientTemperature + ",");
			res.write(docs[i].pressure + ",");
			res.write(docs[i].humidity + "\n");
		}
		res.end();
	});
});

app.listen(80, function () {
	console.log('Example app listening on port 80!');
});
<commit_msg>truncate decimals<commit_after>var express = require('express');
var exphbs  = require('express-handlebars');
var app = express();
var BME280 = require('node-bme280');
var barometer = new BME280({address: 0x77});
var latestTemp;
var latestPressure;
var latestHumidity;
var ready = false;

var Datastore = require('nedb')
  , db = new Datastore({ filename: 'data.txt', autoload: true });

barometer.begin(function(err) {
    if (err) {
        console.info('error initializing barometer', err);
        return;
    }
    console.info('barometer running');
	setImmediate(readData);
	setInterval(readData, 60 * 1000);
});

var readData = function () {
	barometer.readPressureAndTemparature(function(err, pressure, temperature, humidity) {
		latestTemp = temperature.toFixed(2);
		latestPressure = (pressure / 100).toFixed(2);
		latestHumidity = humidity.toFixed(2);
		ready = true;
		db.insert({
			time: new Date(),
			ambientTemperature: latestTemp,
			pressure: latestPressure,
			humidity: latestHumidity
		});
	});
};

app.engine('handlebars', exphbs({defaultLayout: false}));
app.set('view engine', 'handlebars');
app.use(express.static('static'));

app.get('/', function (req, res) {
	/*res.write("<meta http-equiv=\"refresh\" content=\"5\"><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
	if (ready) {
		res.write("Temperature: " + latestTemp + " ℃
");
		res.write("Pressure: " + latestPressure + " hPa
");
		res.write("Humidity: " + latestHumidity + "%\n");
	} else {
		res.write("No data is available currently.");
	}
	res.end("");*/
	res.render("index", {
		ambientTemperature: latestTemp.toFixed(1),
		pressure: latestPressure.toFixed(0),
		humidity: latestHumidity.toFixed(1)
	});
});

app.get('/output.csv', function (req, res) {
	db.find({}).sort({ time: 1 }).exec(function (err, docs) {
		res.write("Time,Temperature,Pressure,Humidity\n");
		for (var i = 0; i < docs.length; i++) {
			var time = docs[i].time;
			var formattedDate = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
			var formattedTime = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
			var formattedDateTime = formattedDate + " " + formattedTime; // github doesn't like long lines
			res.write(formattedDateTime + ",");
			res.write(docs[i].ambientTemperature + ",");
			res.write(docs[i].pressure + ",");
			res.write(docs[i].humidity + "\n");
		}
		res.end();
	});
});

app.listen(80, function () {
	console.log('Example app listening on port 80!');
});
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var {
    Component,
    StyleSheet,
    View,
    Text,
    TouchableOpacity,
} = React;

class Tabs extends Component {
    onSelect(el){
        if (el.props.onSelect) {
            el.props.onSelect(el);
        } else if (this.props.onSelect) {
            this.props.onSelect(el);
        }
    }

    render(){
        const self = this;
        let selected = this.props.selected
        if (!selected){
            React.Children.forEach(this.props.children, el=>{
                if (!selected || el.props.initial){
                    selected = el.props.name;
                }
            });
        }
        return (
            <View style={[styles.tabbarView, this.props.style]}>
                {React.Children.map(this.props.children,(el)=>
                    <TouchableOpacity key={el.props.name+"touch"}
                       style={[styles.iconView, this.props.iconStyle, el.props.name == selected ? this.props.selectedIconStyle || el.props.selectedIconStyle || {} : {} ]}
                       onPress={()=>!self.props.locked && self.onSelect(el)}
                       onLongPress={()=>self.props.locked && self.onSelect(el)}>
                         {selected == el.props.name ? React.cloneElement(el, {selected: true, style: [el.props.style, this.props.selectedStyle, el.props.selectedStyle]}) : el}
                    </TouchableOpacity>
                )}
            </View>
        );
    }
}
var styles = StyleSheet.create({
    tabbarView: {
        position:'absolute',
        bottom:0,
        right:0,
        left:0,
        height:50,
        opacity:1,
        backgroundColor:'transparent',
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    iconView: {
        flex: 1,
        height: 50,
        justifyContent: 'center',
        alignItems: 'center',
    }
});

module.exports = Tabs;
<commit_msg>Filter out falsy children<commit_after>'use strict';

var React = require('react-native');
var {
    Component,
    StyleSheet,
    View,
    Text,
    TouchableOpacity,
} = React;

class Tabs extends Component {
    onSelect(el){
        if (el.props.onSelect) {
            el.props.onSelect(el);
        } else if (this.props.onSelect) {
            this.props.onSelect(el);
        }
    }

    render(){
        const self = this;
        let selected = this.props.selected
        if (!selected){
            React.Children.forEach(this.props.children, el=>{
                if (!selected || el.props.initial){
                    selected = el.props.name;
                }
            });
        }
        return (
            <View style={[styles.tabbarView, this.props.style]}>
                {React.Children.map(this.props.children.filter(c=>c),(el)=>
                    <TouchableOpacity key={el.props.name+"touch"}
                       style={[styles.iconView, this.props.iconStyle, el.props.name == selected ? this.props.selectedIconStyle || el.props.selectedIconStyle || {} : {} ]}
                       onPress={()=>!self.props.locked && self.onSelect(el)}
                       onLongPress={()=>self.props.locked && self.onSelect(el)}>
                         {selected == el.props.name ? React.cloneElement(el, {selected: true, style: [el.props.style, this.props.selectedStyle, el.props.selectedStyle]}) : el}
                    </TouchableOpacity>
                )}
            </View>
        );
    }
}
var styles = StyleSheet.create({
    tabbarView: {
        position:'absolute',
        bottom:0,
        right:0,
        left:0,
        height:50,
        opacity:1,
        backgroundColor:'transparent',
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    iconView: {
        flex: 1,
        height: 50,
        justifyContent: 'center',
        alignItems: 'center',
    }
});

module.exports = Tabs;
<|endoftext|>


<commit_before>var events = require('events');
var wormhole = function (socket) {
	events.EventEmitter.call(this);
	this.isWormhole = null;
	this.setupListeners();
	this.setSocket(socket);

	this._rpc = {};
};
wormhole.prototype.__proto__ = events.EventEmitter.prototype;
wormhole.prototype.setSocket = function(socket) {
	this.socket && this.socket.removeAllListeners();
	this.socket = socket;
	this.setupSocketListeners();
};
wormhole.prototype.isWormhole = function(cb) {
	if (this.isWormhole === null) {
		this.socket.emit("isWormhole", function (err, isWormhole) {
			if (!err) {
				this.isWormhole = isWormhole;
			} else {
				this.isWormhole = !!isWormhole;
			}
		});
	} else {
		cb(null, isWormhole);
	}
};
wormhole.prototype.setupListeners = function() {
	// this.on("removeListener", this._unsubscribe);
	var self = this;
	this.on("newListener", function (event, func) {
		if (event != "removeListener" && event != "newListener") {
			// Oh, this is an RPC, Add the fucker!
			this._rpc[event] = func;
		}
	});
};
wormhole.prototype.setupSocketListeners = function() {
	this.socket.on("isWormhole", function (cb) {
		cb(null, true);
	});
};
wormhole.prototype.addFunction = function(func, cb) {
	this._rpc[func] = cb;
};
module.exports = wormhole;<commit_msg>base64 hash stuff<commit_after>var events = require('events');
var wormhole = function (socket) {
	events.EventEmitter.call(this);
	this.isWormhole = null;
	this.setupListeners();
	this.setSocket(socket);

	this._availablerpc = {};
	this.rpc = {};

	this.__hash__ = "";
};
wormhole.prototype.__proto__ = events.EventEmitter.prototype;
wormhole.prototype.setSocket = function(socket) {
	this.socket && this.socket.removeAllListeners();
	this.socket = socket;
	this.setupSocketListeners();
};
wormhole.prototype.isWormhole = function(cb) {
	if (this.isWormhole === null) {
		this.socket.emit("isWormhole", function (err, isWormhole) {
			if (!err) {
				this.isWormhole = isWormhole;
			} else {
				this.isWormhole = !!isWormhole;
			}
		});
	} else {
		cb(null, isWormhole);
	}
};
wormhole.prototype.setupListeners = function() {
	var self = this;
	this.on("newListener", function (event, func) {
		if (event != "removeListener" && event != "newListener") {
			// Oh, this is an RPC, Add the fucker!
			self.addFunction(event, func);
		}
	});
};
wormhole.prototype.setupSocketListeners = function() {
	var self = this;
	//Original func
	this.socket.on("isWormhole", function (cb) {
		cb(null, true);
		self.syncFunctions();
	});

	this.socket.on("rpc", function (data) {
		if (data.__hash__ != self.__hash__) {
			self.emit("outofsync", self);
		}
	});
};
wormhole.prototype.addFunction = function(func, cb) {
	this._availablerpc[func] = cb;
	var str = Object.keys(this._availablerpc).join("");
	this.__hash__ = new Buffer(str).toString('base64');
};
wormhole.prototype.syncFunctions = function() {
	this.socket.emit("functions", Object.keys(this._availablerpc));
};
wormhole.prototype.addClientFunction = function(func) {
	var self = this;
	this.rpc[func] = function () {
		var args = ["rpc", func].concat([].slice.call(arguments));
		self.socket.emit.apply(self, args);
	};
};
module.exports = wormhole;<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var EventEmitter = require('events').EventEmitter;
var rtc = require('rtc');
var debug = rtc.logger('rtc-quickconnect');
var signaller = require('rtc-signaller');
var defaults = require('cog/defaults');
var extend = require('cog/extend');
var reTrailingSlash = /\/$/;
var CHANNEL_HEARTBEAT = '__heartbeat';

/**
  # rtc-quickconnect

  This is a high level helper module designed to help you get up
  an running with WebRTC really, really quickly.  By using this module you
  are trading off some flexibility, so if you need a more flexible
  configuration you should drill down into lower level components of the
  [rtc.io](http://www.rtc.io) suite.  In particular you should check out
  [rtc](https://github.com/rtc-io/rtc).

  ## Example Usage

  In the simplest case you simply call quickconnect with a single string
  argument which tells quickconnect which server to use for signaling:

  <<< examples/simple.js

  ## Example Usage (using data channels)

  When working with WebRTC data channels, you can call the `createDataChannel`
  function helper that is attached to the object returned from the
  `quickconnect` call.  The `createDataChannel` function signature matches
  the signature of the `RTCPeerConnection` `createDataChannel` function.

  At the minimum it requires a label for the channel, but you can also pass
  through a dictionary of options that can be used to fine tune the
  data channel behaviour.  For more information on these options, I'd
  recommend having a quick look at the WebRTC spec:

  http://dev.w3.org/2011/webrtc/editor/webrtc.html#dictionary-rtcdatachannelinit-members

  If in doubt, I'd recommend not passing through options.

  <<< examples/datachannel.js

  __NOTE:__ Data channel interoperability has been tested between Chrome 32
  and Firefox 26, which both make use of SCTP data channels.

  __NOTE:__ The current stable version of Chrome is 31, so interoperability
  with Firefox right now will be hard to achieve.

  ## Example Usage (using captured media)

  Another example is displayed below, and this example demonstrates how
  to use `rtc-quickconnect` to create a simple video conferencing application:

  <<< examples/conference.js

  ## Regarding Signalling and a Signalling Server

  Signaling is an important part of setting up a WebRTC connection and for
  our examples we use our own test instance of the
  [rtc-switchboard](https://github.com/rtc-io/rtc-switchboard). For your
  testing and development you are more than welcome to use this also, but
  just be aware that we use this for our testing so it may go up and down
  a little.  If you need something more stable, why not consider deploying
  an instance of the switchboard yourself - it's pretty easy :)

  ## Reference

  ```
  quickconnect(signalhost, opts?) => rtc-sigaller instance (+ helpers)
  ```

  ### Valid Quick Connect Options

  The options provided to the `rtc-quickconnect` module function influence the
  behaviour of some of the underlying components used from the rtc.io suite.

  Listed below are some of the commonly used options:

  - `ns` (default: '')

    An optional namespace for your signalling room.  While quickconnect
    will generate a unique hash for the room, this can be made to be more
    unique by providing a namespace.  Using a namespace means two demos
    that have generated the same hash but use a different namespace will be
    in different rooms.

  - `room` (default: null) _added 0.6_

    Rather than use the internal hash generation
    (plus optional namespace) for room name generation, simply use this room
    name instead.  __NOTE:__ Use of the `room` option takes precendence over
    `ns`.

  - `debug` (default: false)

  Write rtc.io suite debug output to the browser console.

  #### Options for Peer Connection Creation

  Options that are passed onto the
  [rtc.createConnection](https://github.com/rtc-io/rtc#createconnectionopts-constraints)
  function:

  - `constraints`

    Used to provide specific constraints when creating a new
    peer connection.

  #### Options for P2P negotiation

  Under the hood, quickconnect uses the
  [rtc/couple](https://github.com/rtc-io/rtc#rtccouple) logic, and the options
  passed to quickconnect are also passed onto this function.

**/
module.exports = function(signalhost, opts) {
  var hash = location.hash.slice(1);
  var signaller = require('rtc-signaller')(signalhost);

  // init configurable vars
  var ns = (opts || {}).ns || '';
  var room = (opts || {}).room;
  var debugging = (opts || {}).debug;
  var disableHeartbeat = (opts || {}).disableHeartbeat;
  var heartbeatInterval = (opts || {}).heartbeatInterval || 3000;
  var profile = {};

  // collect the local streams
  var localStreams = [];

  // create the known data channels registry
  var channels = {};

  // create the heartbeats registry
  var beats = {};

  function gotPeerChannel(channel, pc, data) {
    // create the channelOpen function
    var emitChannelOpen = signaller.emit.bind(
      signaller,
      channel.label + ':open',
      channel,
      data.id,
      data,
      pc
    );

    debug('channel ' + channel.label + ' discovered for peer: ' + data.id, channel);
    if (channel.readyState === 'open') {
      return emitChannelOpen();
    }

    channel.onopen = emitChannelOpen;
  }

  function initHeartbeat(channel, pc, data) {
    debug('created heartbeat channel for peer: ' + data.id);

    // save the heartbeat information
    beats[data.id] = channel;

    // start monitoring using the heartbeat channel to keep tabs on our
    // peers availability
    channel.onmessage = function(evt) {
      // console.log('received hearbeat message: ' + evt.data)
    };

    setInterval(function() {
      channel.send('tick: ' + Date.now());
    }, heartbeatInterval);
  }

  // if the room is not defined, then generate the room name
  if (! room) {
    // if the hash is not assigned, then create a random hash value
    if (! hash) {
      hash = location.hash = '' + (Math.pow(2, 53) * Math.random());
    }

    room = ns + '#' + hash;
  }

  if (debugging) {
    rtc.logger.enable.apply(rtc.logger, Array.isArray(debug) ? debugging : ['*']);
  }

  signaller.on('peer:announce', function(data) {
    var pc;
    var monitor;

    // if the room is not a match, abort
    if (data.room !== room) {
      return;
    }

    // create a peer connection
    pc = rtc.createConnection(opts, (opts || {}).constraints);

    // add the local streams
    localStreams.forEach(function(stream) {
      pc.addStream(stream);
    });

    // add the data channels
    // do this differently based on whether the connection is a
    // master or a slave connection
    if (signaller.isMaster(data.id)) {
      debug('is master, creating data channels: ', Object.keys(channels));

      // unless the heartbeat is disabled then create a heartbeat datachannel
      if (! disableHeartbeat) {
        initHeartbeat(pc.createDataChannel(CHANNEL_HEARTBEAT), pc, data);
      }

      // create the channels
      Object.keys(channels).forEach(function(label) {
        gotPeerChannel(pc.createDataChannel(label, channels[label]), pc, data);
      });
    }
    else {
      pc.ondatachannel = function(evt) {
        var channel = evt && evt.channel;

        // if we have no channel, abort
        if (! channel) {
          return;
        }

        // if the channel is the heartbeat, then init the heartbeat
        if (channel.label === CHANNEL_HEARTBEAT) {
          initHeartbeat(channel, pc, data);
        }
        // otherwise, if this is a known channel, initialise it
        else if (channels[channel.label] !== undefined) {
          gotPeerChannel(channel, pc, data);
        }
      };
    }

    // couple the connections
    monitor = rtc.couple(pc, data.id, signaller, opts);

    // emit the peer event as per <= rtc-quickconnect@0.7
    signaller.emit('peer', pc, data.id, data, monitor);

    // once active, trigger the peer connect event
    monitor.once('active', function() {
      signaller.emit('peer:connect', pc, data.id, data);
    });

    // if we are the master connnection, create the offer
    // NOTE: this only really for the sake of politeness, as rtc couple
    // implementation handles the slave attempting to create an offer
    if (signaller.isMaster(data.id)) {
      monitor.createOffer();
    }
  });

  // announce ourselves to our new friend
  setTimeout(function() {
    var data = extend({}, profile, { room: room });

    // announce and emit the local announce event
    signaller.announce(data);
    signaller.emit('local:announce', data);
  }, 0);

  /**
    ### Quickconnect Broadcast and Data Channel Helper Functions

    The following are functions that are patched into the `rtc-signaller`
    instance that make working with and creating functional WebRTC applications
    a lot simpler.

  **/

  /**
    #### broadcast(stream)

    Add the stream to the set of local streams that we will broadcast
    to other peers.

  **/
  signaller.broadcast = function(stream) {
    localStreams.push(stream);
    return signaller;
  };

  /**
    #### createDataChannel(label, config)

    Request that a data channel with the specified `label` is created on
    the peer connection.  When the data channel is open and available, an
    event will be triggered using the label of the data channel.

    For example, if a new data channel was requested using the following
    call:

    ```js
    var qc = quickconnect('http://rtc.io/switchboard').createDataChannel('test');
    ```

    Then when the data channel is ready for use, a `test:open` event would
    be emitted by `qc`.

  **/
  signaller.createDataChannel = function(label, opts) {
    // save the data channel opts in the local channels dictionary
    channels[label] = opts || null;
    return signaller;
  };

  /**
    #### profile(data)

    Update the profile data with the attached information, so when
    the signaller announces it includes this data in addition to any
    room and id information.

  **/
  signaller.profile = function(data) {
    extend(profile, data);
    return signaller;
  };

  // pass the signaller on
  return signaller;
};<commit_msg>More progress on heartbeat implementation<commit_after>/* jshint node: true */
'use strict';

var EventEmitter = require('events').EventEmitter;
var rtc = require('rtc');
var debug = rtc.logger('rtc-quickconnect');
var signaller = require('rtc-signaller');
var defaults = require('cog/defaults');
var extend = require('cog/extend');
var reTrailingSlash = /\/$/;
var CHANNEL_HEARTBEAT = '__heartbeat';

/**
  # rtc-quickconnect

  This is a high level helper module designed to help you get up
  an running with WebRTC really, really quickly.  By using this module you
  are trading off some flexibility, so if you need a more flexible
  configuration you should drill down into lower level components of the
  [rtc.io](http://www.rtc.io) suite.  In particular you should check out
  [rtc](https://github.com/rtc-io/rtc).

  ## Example Usage

  In the simplest case you simply call quickconnect with a single string
  argument which tells quickconnect which server to use for signaling:

  <<< examples/simple.js

  ## Example Usage (using data channels)

  When working with WebRTC data channels, you can call the `createDataChannel`
  function helper that is attached to the object returned from the
  `quickconnect` call.  The `createDataChannel` function signature matches
  the signature of the `RTCPeerConnection` `createDataChannel` function.

  At the minimum it requires a label for the channel, but you can also pass
  through a dictionary of options that can be used to fine tune the
  data channel behaviour.  For more information on these options, I'd
  recommend having a quick look at the WebRTC spec:

  http://dev.w3.org/2011/webrtc/editor/webrtc.html#dictionary-rtcdatachannelinit-members

  If in doubt, I'd recommend not passing through options.

  <<< examples/datachannel.js

  __NOTE:__ Data channel interoperability has been tested between Chrome 32
  and Firefox 26, which both make use of SCTP data channels.

  __NOTE:__ The current stable version of Chrome is 31, so interoperability
  with Firefox right now will be hard to achieve.

  ## Example Usage (using captured media)

  Another example is displayed below, and this example demonstrates how
  to use `rtc-quickconnect` to create a simple video conferencing application:

  <<< examples/conference.js

  ## Regarding Signalling and a Signalling Server

  Signaling is an important part of setting up a WebRTC connection and for
  our examples we use our own test instance of the
  [rtc-switchboard](https://github.com/rtc-io/rtc-switchboard). For your
  testing and development you are more than welcome to use this also, but
  just be aware that we use this for our testing so it may go up and down
  a little.  If you need something more stable, why not consider deploying
  an instance of the switchboard yourself - it's pretty easy :)

  ## Reference

  ```
  quickconnect(signalhost, opts?) => rtc-sigaller instance (+ helpers)
  ```

  ### Valid Quick Connect Options

  The options provided to the `rtc-quickconnect` module function influence the
  behaviour of some of the underlying components used from the rtc.io suite.

  Listed below are some of the commonly used options:

  - `ns` (default: '')

    An optional namespace for your signalling room.  While quickconnect
    will generate a unique hash for the room, this can be made to be more
    unique by providing a namespace.  Using a namespace means two demos
    that have generated the same hash but use a different namespace will be
    in different rooms.

  - `room` (default: null) _added 0.6_

    Rather than use the internal hash generation
    (plus optional namespace) for room name generation, simply use this room
    name instead.  __NOTE:__ Use of the `room` option takes precendence over
    `ns`.

  - `debug` (default: false)

  Write rtc.io suite debug output to the browser console.

  #### Options for Peer Connection Creation

  Options that are passed onto the
  [rtc.createConnection](https://github.com/rtc-io/rtc#createconnectionopts-constraints)
  function:

  - `constraints`

    Used to provide specific constraints when creating a new
    peer connection.

  #### Options for P2P negotiation

  Under the hood, quickconnect uses the
  [rtc/couple](https://github.com/rtc-io/rtc#rtccouple) logic, and the options
  passed to quickconnect are also passed onto this function.

**/
module.exports = function(signalhost, opts) {
  var hash = location.hash.slice(1);
  var signaller = require('rtc-signaller')(signalhost);

  // init configurable vars
  var ns = (opts || {}).ns || '';
  var room = (opts || {}).room;
  var debugging = (opts || {}).debug;
  var disableHeartbeat = (opts || {}).disableHeartbeat;
  var heartbeatInterval = (opts || {}).heartbeatInterval || 3000;
  var profile = {};

  // collect the local streams
  var localStreams = [];

  // create the known data channels registry
  var channels = {};

  // create the heartbeats registry
  var beats = {};

  function gotPeerChannel(channel, pc, data) {
    // create the channelOpen function
    var emitChannelOpen = signaller.emit.bind(
      signaller,
      channel.label + ':open',
      channel,
      data.id,
      data,
      pc
    );

    debug('channel ' + channel.label + ' discovered for peer: ' + data.id, channel);
    if (channel.readyState === 'open') {
      return emitChannelOpen();
    }

    channel.onopen = emitChannelOpen;
  }

  function initHeartbeat(channel, pc, data) {
    var hbTimeoutTimer;
    var hbTimer;

    function timeoutConnection() {
      console.log('connection with ' + data.id + ' timed out');

      // stop trying to send heartbeat messages
      clearInterval(hbTimer);
    }

    debug('created heartbeat channel for peer: ' + data.id);

    // save the heartbeat information
    beats[data.id] = channel;

    // start monitoring using the heartbeat channel to keep tabs on our
    // peers availability
    channel.onmessage = function(evt) {
      // console.log('received hearbeat message: ' + evt.data)
      if (evt.data === '!HB') {
        clearTimeout(hbTimeoutTimer);
        hbTimeoutTimer = setTimeout(timeoutConnection, heartbeatInterval * 2);
      }
    };

    hbTimer  = setInterval(function() {
      channel.send('!HB');
    }, heartbeatInterval);
  }

  // if the room is not defined, then generate the room name
  if (! room) {
    // if the hash is not assigned, then create a random hash value
    if (! hash) {
      hash = location.hash = '' + (Math.pow(2, 53) * Math.random());
    }

    room = ns + '#' + hash;
  }

  if (debugging) {
    rtc.logger.enable.apply(rtc.logger, Array.isArray(debug) ? debugging : ['*']);
  }

  signaller.on('peer:announce', function(data) {
    var pc;
    var monitor;

    // if the room is not a match, abort
    if (data.room !== room) {
      return;
    }

    // create a peer connection
    pc = rtc.createConnection(opts, (opts || {}).constraints);

    // add the local streams
    localStreams.forEach(function(stream) {
      pc.addStream(stream);
    });

    // add the data channels
    // do this differently based on whether the connection is a
    // master or a slave connection
    if (signaller.isMaster(data.id)) {
      debug('is master, creating data channels: ', Object.keys(channels));

      // unless the heartbeat is disabled then create a heartbeat datachannel
      if (! disableHeartbeat) {
        initHeartbeat(pc.createDataChannel(CHANNEL_HEARTBEAT), pc, data);
      }

      // create the channels
      Object.keys(channels).forEach(function(label) {
        gotPeerChannel(pc.createDataChannel(label, channels[label]), pc, data);
      });
    }
    else {
      pc.ondatachannel = function(evt) {
        var channel = evt && evt.channel;

        // if we have no channel, abort
        if (! channel) {
          return;
        }

        // if the channel is the heartbeat, then init the heartbeat
        if (channel.label === CHANNEL_HEARTBEAT) {
          initHeartbeat(channel, pc, data);
        }
        // otherwise, if this is a known channel, initialise it
        else if (channels[channel.label] !== undefined) {
          gotPeerChannel(channel, pc, data);
        }
      };
    }

    // couple the connections
    monitor = rtc.couple(pc, data.id, signaller, opts);

    // emit the peer event as per <= rtc-quickconnect@0.7
    signaller.emit('peer', pc, data.id, data, monitor);

    // once active, trigger the peer connect event
    monitor.once('active', function() {
      signaller.emit('peer:connect', pc, data.id, data);
    });

    // if we are the master connnection, create the offer
    // NOTE: this only really for the sake of politeness, as rtc couple
    // implementation handles the slave attempting to create an offer
    if (signaller.isMaster(data.id)) {
      monitor.createOffer();
    }
  });

  // announce ourselves to our new friend
  setTimeout(function() {
    var data = extend({}, profile, { room: room });

    // announce and emit the local announce event
    signaller.announce(data);
    signaller.emit('local:announce', data);
  }, 0);

  /**
    ### Quickconnect Broadcast and Data Channel Helper Functions

    The following are functions that are patched into the `rtc-signaller`
    instance that make working with and creating functional WebRTC applications
    a lot simpler.

  **/

  /**
    #### broadcast(stream)

    Add the stream to the set of local streams that we will broadcast
    to other peers.

  **/
  signaller.broadcast = function(stream) {
    localStreams.push(stream);
    return signaller;
  };

  /**
    #### createDataChannel(label, config)

    Request that a data channel with the specified `label` is created on
    the peer connection.  When the data channel is open and available, an
    event will be triggered using the label of the data channel.

    For example, if a new data channel was requested using the following
    call:

    ```js
    var qc = quickconnect('http://rtc.io/switchboard').createDataChannel('test');
    ```

    Then when the data channel is ready for use, a `test:open` event would
    be emitted by `qc`.

  **/
  signaller.createDataChannel = function(label, opts) {
    // save the data channel opts in the local channels dictionary
    channels[label] = opts || null;
    return signaller;
  };

  /**
    #### profile(data)

    Update the profile data with the attached information, so when
    the signaller announces it includes this data in addition to any
    room and id information.

  **/
  signaller.profile = function(data) {
    extend(profile, data);
    return signaller;
  };

  // pass the signaller on
  return signaller;
};<|endoftext|>


<commit_before>'use strict';

var defaults = require('lodash.defaults');

module.exports = function role(schema, options) {

  // Set the default options
  options = options || {};
  defaults(options, {
    roles: [],
    accessLevels: {},
    rolePath: 'role',
    rolesStaticPath: 'roles',
    accessLevelsStaticPath: 'accessLevels',
    hasAccessMethod: 'hasAccess'
  });

  // Set the role path
  schema
    .path(options.rolePath, String)
    .path(options.rolePath)
      .enum(options.roles)
      .required(true);

  // Expose the roles
  schema.static(options.rolesStaticPath, options.roles);
  schema.static(options.accessLevelsStaticPath, options.accessLevels);

  // Set the hasAccess method
  schema.method(options.hasAccessMethod, function (accessLevel) {
    // if nothing is passed, then return true
    if (typeof accessLevel === 'undefined') { return true; }
    var validRoles = options.accessLevels[accessLevel];
    // if there is nothing in the access levels for the given accessLevel, then
    // the return false.
    if (!validRoles) { return false; }
    var userRole   = this.get(options.rolePath);
    return validRoles.indexOf(userRole) !== -1;
  });

};
<commit_msg>fixed issue with enum values<commit_after>'use strict';

var defaults = require('lodash.defaults');

module.exports = function role(schema, options) {

  // Set the default options
  options = options || {};
  defaults(options, {
    roles: [],
    accessLevels: {},
    rolePath: 'role',
    rolesStaticPath: 'roles',
    accessLevelsStaticPath: 'accessLevels',
    hasAccessMethod: 'hasAccess'
  });

  // Set the role path
  schema
    .path(options.rolePath, String)
    .path(options.rolePath)
      .enum({values: options.roles})
      .required(true);

  // Expose the roles
  schema.static(options.rolesStaticPath, options.roles);
  schema.static(options.accessLevelsStaticPath, options.accessLevels);

  // Set the hasAccess method
  schema.method(options.hasAccessMethod, function (accessLevel) {
    // if nothing is passed, then return true
    if (typeof accessLevel === 'undefined') { return true; }
    var validRoles = options.accessLevels[accessLevel];
    // if there is nothing in the access levels for the given accessLevel, then
    // the return false.
    if (!validRoles) { return false; }
    var userRole   = this.get(options.rolePath);
    return validRoles.indexOf(userRole) !== -1;
  });

};
<|endoftext|>


<commit_before>/**
 * espowerify - Browserify transform for power-assert.
 *
 * https://github.com/twada/espowerify
 *
 * Copyright (c) 2014 Takuto Wada
 * Licensed under the MIT license.
 *   https://github.com/twada/espowerify/blob/master/MIT-LICENSE.txt
 */
'use strict';

var through = require('through'),
    espower = require('espower'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    extend = require('xtend'),
    convert = require('convert-source-map'),
    transfer = require('multi-stage-sourcemap').transfer;

function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
    if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
        outgoingSourceMap = JSON.parse(outgoingSourceMap);
    }
    if (!incomingSourceMap) {
        return outgoingSourceMap;
    }
    return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
}

function handleUpstreamSourceMap (jsCode, options) {
    var inMap;
    if (options.sourceMap) {
        inMap = options.sourceMap;
    } else {
        var commented = convert.fromSource(jsCode);
        if (commented) {
            inMap = commented.toObject();
            options.sourceMap = inMap;
        }
    }
    return inMap;
}

function instrument (jsCode, filepath, options) {
    var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: filepath});
    var modifiedAst = espower(jsAst, options);
    // keep paths absolute by not using `file` and `sourceMapRoot`
    // paths will be resolved by mold-source-map
    return escodegen.generate(modifiedAst, {
        sourceMap: true,
        sourceMapWithCode: true
    });
}

function mergeEspowerOptions (options, filepath) {
    return extend(espower.defaultOptions(), options, {
        destructive: true,
        path: filepath
    });
}

function transform (jsCode, filepath, options) {
    var espowerOptions = mergeEspowerOptions(options, filepath);
    var inMap = handleUpstreamSourceMap(jsCode, espowerOptions);
    var instrumented = instrument(jsCode, filepath, espowerOptions);
    var outMap = convert.fromJSON(instrumented.map.toString());
    if (inMap) {
        var mergedRawMap = mergeSourceMap(inMap, outMap.toObject());
        var reMap = convert.fromObject(mergedRawMap);
        reMap.setProperty('sources', inMap.sources);
        reMap.setProperty('sourcesContent', inMap.sourcesContent);
        return instrumented.code + '\n' + reMap.toComment() + '\n';
    } else {
        outMap.setProperty('sources', [filepath]);
        outMap.setProperty('sourcesContent', [jsCode]);
        return instrumented.code + '\n' + outMap.toComment() + '\n';
    }
}

/**
 * Apply espower through the browserify transform chain.
 *
 * @param {String} filepath
 * @param {Object} options
 * @return {Stream}
 */
function espowerify(filepath, options) {

    var data = '',
        stream = through(write, end);

    function write(buf) {
        data += buf;
    }

    function end() {
        stream.queue(transform(data, filepath, options));
        stream.queue(null);
    }

    return stream;
}

module.exports = espowerify;
<commit_msg>chore(espowerify): add comment to reveal intention<commit_after>/**
 * espowerify - Browserify transform for power-assert.
 *
 * https://github.com/twada/espowerify
 *
 * Copyright (c) 2014 Takuto Wada
 * Licensed under the MIT license.
 *   https://github.com/twada/espowerify/blob/master/MIT-LICENSE.txt
 */
'use strict';

var through = require('through'),
    espower = require('espower'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    extend = require('xtend'),
    convert = require('convert-source-map'),
    transfer = require('multi-stage-sourcemap').transfer;

function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
    if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
        outgoingSourceMap = JSON.parse(outgoingSourceMap);
    }
    if (!incomingSourceMap) {
        return outgoingSourceMap;
    }
    return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
}

function handleUpstreamSourceMap (jsCode, options) {
    var inMap;
    if (options.sourceMap) {
        inMap = options.sourceMap;
    } else {
        var commented = convert.fromSource(jsCode);
        if (commented) {
            inMap = commented.toObject();
            options.sourceMap = inMap;
        }
    }
    return inMap;
}

function instrument (jsCode, filepath, options) {
    var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: filepath});
    var modifiedAst = espower(jsAst, options);
    // keep paths absolute by not using `file` and `sourceMapRoot`
    // paths will be resolved by mold-source-map
    return escodegen.generate(modifiedAst, {
        sourceMap: true,
        sourceMapWithCode: true
    });
}

function mergeEspowerOptions (options, filepath) {
    return extend(espower.defaultOptions(), options, {
        destructive: true,
        path: filepath
    });
}

function transform (jsCode, filepath, options) {
    var espowerOptions = mergeEspowerOptions(options, filepath);
    var inMap = handleUpstreamSourceMap(jsCode, espowerOptions);
    var instrumented = instrument(jsCode, filepath, espowerOptions);
    var outMap = convert.fromJSON(instrumented.map.toString());
    if (inMap) {
        var mergedRawMap = mergeSourceMap(inMap, outMap.toObject());
        var reMap = convert.fromObject(mergedRawMap);
        reMap.setProperty('sources', inMap.sources);
        reMap.setProperty('sourcesContent', inMap.sourcesContent);
        return instrumented.code + '\n' + reMap.toComment() + '\n';
    } else {
        // Keeping paths absolute. Paths will be resolved by mold-source-map.
        outMap.setProperty('sources', [filepath]);
        outMap.setProperty('sourcesContent', [jsCode]);
        return instrumented.code + '\n' + outMap.toComment() + '\n';
    }
}

/**
 * Apply espower through the browserify transform chain.
 *
 * @param {String} filepath
 * @param {Object} options
 * @return {Stream}
 */
function espowerify(filepath, options) {

    var data = '',
        stream = through(write, end);

    function write(buf) {
        data += buf;
    }

    function end() {
        stream.queue(transform(data, filepath, options));
        stream.queue(null);
    }

    return stream;
}

module.exports = espowerify;
<|endoftext|>


<commit_before>'use strict'
var sodium = require('sodium-universal')
var assert = require('assert')

var BYTES = 16

module.exports = create
function create (buf) {
  assert(buf == null ? true : Buffer.isBuffer(buf), 'buf must be Buffer')
  assert(buf == null ? true : buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes')

  if (buf == null) {
    buf = Buffer.allocUnsafe(BYTES)
  }

  sodium.randombytes_buf(buf.slice(0, BYTES))

  // Mask then set bits
  // https://tools.ietf.org/html/rfc4122#section-4.1.2

  // clock_seq_hi_and_reserved
  // version
  buf[6] &= 0x0f // 0b00001111
  buf[6] |= 0x40 // 0b01000000

  // time_hi_and_version
  // IETF variant
  buf[8] &= 0x3f // 0b00111111
  buf[8] |= 0x80 // 0b10000000

  return buf
}

create.stringify = function (buf) {
  assert(Buffer.isBuffer(buf), 'buf must be Buffer')
  assert(buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes')

  return [
    buf.slice(0, 4),
    buf.slice(4, 6),
    buf.slice(6, 8),
    buf.slice(8, 10),
    buf.slice(10, 16)
  ].map(function (subbuf) {
    return subbuf.toString('hex')
  }).join('-')
}

create.BYTES = BYTES
<commit_msg>Got the comments wrong on the RFC and tidier masking<commit_after>'use strict'
var sodium = require('sodium-universal')
var assert = require('assert')

var BYTES = 16

module.exports = create
function create (buf) {
  assert(buf == null ? true : Buffer.isBuffer(buf), 'buf must be Buffer')
  assert(buf == null ? true : buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes')

  if (buf == null) {
    buf = Buffer.allocUnsafe(BYTES)
  }

  sodium.randombytes_buf(buf.slice(0, BYTES))

  // Mask then set bits
  // https://tools.ietf.org/html/rfc4122#section-4.1.2

  // time_hi_and_version (MSB half)
  // IETF variant
  buf[6] = (buf[6] & 0b00001111) | 0b01000000

  // clock_seq_hi_and_reserved
  // version
  buf[8] = (buf[8] & 0b00111111) | 0b10000000

  return buf
}

create.stringify = function (buf) {
  assert(Buffer.isBuffer(buf), 'buf must be Buffer')
  assert(buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes')

  return [
    buf.slice(0, 4),
    buf.slice(4, 6),
    buf.slice(6, 8),
    buf.slice(8, 10),
    buf.slice(10, 16)
  ].map(function (subbuf) {
    return subbuf.toString('hex')
  }).join('-')
}

create.BYTES = BYTES
<|endoftext|>


<commit_before>/**
 * R1C1 pattern
 *
 * @type {RegExp}
 */

var R1C1 = /^R(\d+)C(\d+)$/;

/**
 * A1 pattern
 *
 * @type {RegExp}
 */

var A1 = /^([A-Z]+)(\d+)$/;

/**
 * Convert A1 notation to R1C1 notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function A1toR1C1(ref) {
  if (!A1.test(ref)) {
    throw new Error(ref + ' is not a valid A1 cell reference');
  }

  var refParts = ref
    .replace(A1, '$1,$2')
    .split(',');

  var columnStr = refParts[0];
  var row = refParts[1];
  var column = 0;

  for (var i = 0; i < columnStr.length; i++) {
    column = 26 * column + columnStr.charCodeAt(i) - 64;
  }

  return 'R' + row + 'C' + column;
}

/**
 * Convert R1C1 notation to A1 notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function R1C1toA1(ref) {
  if (!R1C1.test(ref)) {
    throw new Error(ref + ' is not a valid R1C1 cell reference');
  }

  var refParts = ref
    .replace(R1C1, '$1,$2')
    .split(',');

  var row = refParts[0];
  var column = refParts[1];
  var columnStr = '';

  for (; column; column = Math.floor(column / 26)) {
    columnStr = String.fromCharCode((column % 26) + 64) + columnStr;
  }

  return columnStr + row;
}

/**
 * Auto detects notation used and converts to the opposite notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function cellref(ref) {
  if (R1C1.test(ref)) {
    return R1C1toA1(ref);
  }

  if (A1.test(ref)) {
    return A1toR1C1(ref);
  }

  throw new Error('could not detect cell reference notation for ' + ref);
}

/**
 * Exports
 */

module.exports = cellref;
module.exports.toA1 = R1C1toA1;
module.exports.toR1C1 = A1toR1C1;
<commit_msg>rename internal methods for clarity<commit_after>/**
 * R1C1 pattern
 *
 * @type {RegExp}
 */

var R1C1 = /^R(\d+)C(\d+)$/;

/**
 * A1 pattern
 *
 * @type {RegExp}
 */

var A1 = /^([A-Z]+)(\d+)$/;

/**
 * Convert A1 notation to R1C1 notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function convertA1toR1C1(ref) {
  if (!A1.test(ref)) {
    throw new Error(ref + ' is not a valid A1 cell reference');
  }

  var refParts = ref
    .replace(A1, '$1,$2')
    .split(',');

  var columnStr = refParts[0];
  var row = refParts[1];
  var column = 0;

  for (var i = 0; i < columnStr.length; i++) {
    column = 26 * column + columnStr.charCodeAt(i) - 64;
  }

  return 'R' + row + 'C' + column;
}

/**
 * Convert R1C1 notation to A1 notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function convertR1C1toA1(ref) {
  if (!R1C1.test(ref)) {
    throw new Error(ref + ' is not a valid R1C1 cell reference');
  }

  var refParts = ref
    .replace(R1C1, '$1,$2')
    .split(',');

  var row = refParts[0];
  var column = refParts[1];
  var columnStr = '';

  for (; column; column = Math.floor(column / 26)) {
    columnStr = String.fromCharCode((column % 26) + 64) + columnStr;
  }

  return columnStr + row;
}

/**
 * Auto detects notation used and converts to the opposite notation
 *
 * @param {string} ref
 * @returns {string}
 * @throws {Error}
 */

function cellref(ref) {
  if (R1C1.test(ref)) {
    return convertR1C1toA1(ref);
  }

  if (A1.test(ref)) {
    return convertA1toR1C1(ref);
  }

  throw new Error('could not detect cell reference notation for ' + ref);
}

/**
 * Exports
 */

module.exports = cellref;
module.exports.toA1 = convertR1C1toA1;
module.exports.toR1C1 = convertA1toR1C1;
<|endoftext|>