<commit_before>// See gregfranko.com/blog/jquery-best-practices
//
// IIFE: Immediately Invoked Function Expression
(function(main_iife_function) {
        main_iife_function(window.jQuery, window, document);
    }(function($,window,document) {

        // Put local variables and functions into this namespace
        local_ns = {}

        local_ns.unique = function(arr) {
            return arr.filter(function(value, index, array) {
                return array.indexOf(value) === index;
            });
        };

        local_ns.setPlotTimezone = function(val) {
            // console.log("calling Highcharts.setOptions,val",val);
            local_ns.plotTimezone = val;
            local_ns.zone = moment.tz.zone(val);
            Highcharts.setOptions({
                global: {
                    getTimezoneOffset: function(timestamp) {
                        var timezoneOffset =
                            -moment.tz(timestamp,local_ns.plotTimezone).utcOffset();
                        // console.log("timezoneOffset=",timezoneOffset);
                        return timezoneOffset;
                    },
                    // Documentation on this seems wrong. With the current
                    // logic here, we must set this to true.
                    useUTC: true,
                }
            });
        };

        // Add support for %Z time formatter
        Highcharts.dateFormats = {
            Z: function (timestamp) {
                // console.log("zone.abbr=",local_ns.zone.abbr(timestamp));
                return local_ns.zone.abbr(timestamp);
            }
        };

        $(function() {
            // console.log("DOM is ready!");

            // When doc is ready, grab the selected time zone
            var tzelem = $("select#id_timezone");
            var tz = tzelem.val();
            local_ns.pickerTimezone = tz;
            local_ns.setPlotTimezone(tz);
            // console.log("select#id_timezone tz=",tz)

            $("select#id_timezone").change(function() {
                // When user changes the timezone, adjust the time
                // in the datetimepicker so that it is the
                // same moment in time as with the previous timezone.
                //
                // Unfortunately datetimepicker time formats
                // are different than moment time formats:
                // datetimepicker:  "yyyy-mm-dd hh:ii"
                // moment:          "YYYY-MM-DD HH:mm"
                // The moment format is hard-coded here, and so
                // if the datetimepicker format is changed in
                // django/python, it must be changed here.
                //
                // Also couldn't find out how to get the current
                // datetimepicker format.
                //
                // To avoid formatting times one would get/set
                // from datetimepicker using javascript Date objects.
                // However, a javascript Date is either in the
                // browser's time zone or UTC. I believe there would
                // always be a problem right around the time of
                // daylight savings switches, if Date is used.

                // Note that we don't change the value of
                // the timezone in local_ns, since that must match
                // what is plotted.

                var picker = $("input#id_start_time");
                var dstr = picker.val();

                // console.log("picker.val()=",dstr);

                // parse time using current timezone
                var mom = moment.tz(dstr,'YYYY-MM-DD HH:mm',local_ns.pickerTimezone);

                // get the new timezone
                var new_tz = $(this).val();

                // save previous value, but don't
                local_ns.pickerTimezone = new_tz;

                // adjust time for new timezone
                mom = mom.tz(new_tz);

                // format it, and set it on the picker
                dstr = mom.format('YYYY-MM-DD HH:mm');
                picker.val(dstr);
            });

            $("div[id^='time-series']").each(function(index) {
                // console.log("time-series");

                var vnames =  $( this ).data("variables");
                var vunits =  $( this ).data("units");
                var long_names =  $( this ).data("long_names");
                if (long_names.length == 0) {
                    long_names = vnames;
                }
                // console.log("time-series, time.length=",time.length);
                // console.log("vnames=",vnames,", vunits=",vunits);

                // series and yAxis are arrays of dictionaries
                var yAxis = [];

                var unique_units = local_ns.unique(vunits);
                // console.log("unique_units=",unique_units);
                var opposite = false;
                for (var unit of unique_units) {
                    // console.log("unit=",unit);
                    ya = {
                        opposite: opposite,
                        title: {
                            text: unit,
                        },
                    };
                    yAxis.push(ya);
                    opposite = !opposite;
                }

                var series = [];

                if (vnames.length > 1) {
                    ptitle = vnames[0] + "...";
                }
                else {
                    ptitle = vnames[0];
                }
                for (var iv = 0; iv < vnames.length; iv++ ) {
                    var vname = vnames[iv];
                    var vunit = vunits[iv];
                    var long_name = long_names[iv];
                    var vseries = {};
                    var vdata = [];
                    for (var i = 0; i < time.length; i++) {
                        vdata.push([(time0 + time[i])*1000, data[vname][i]]);
                    }
                    vseries['data'] = vdata;
                    if (unique_units.length > 1) {
                        vseries['name'] = vname + '(' + vunit + ')';
                    }
                    else {
                        vseries['name'] = vname;
                    }
                    vseries['yAxis'] = unique_units.indexOf(vunit);
                    vseries['tooltip'] = {
                        // valueSuffix: long_name,
                        headerFormat: '{point.key}
',
                        pointFormat: '\u25CF ' + long_name + ',{series.name}: {point.y}
',
                        valueDecimals: 6,
                        xDateFormat: '%Y-%m-%d %H:%M:%S.%L %Z',
                    };
                    /* a checkbox allows one to "select" the series, but
                     * I'm not sure what that does. Clicking it doesn't
                     * make the series disappear. That is done by clicking
                     * on the name in the legend, which by default goes below
                     * the xaxis.
                     * Supposidly if you return anything other than false,
                     * the default action is to toggle the selected state
                     * of the series.
                        events: {
                            checkboxClick: function (event) {
                                alert('The checkbox is now ' + event.checked);
                                return false;
                            }
                        },
                     */
                    series.push(vseries);
                }

                $( this ).highcharts('StockChart',{
                    chart: {
                        type: 'line',
                        // zoomType: 'x',
                        // panning: true,
                        // panKey: 'shift',
                        spacingLeft: 20,
                        spacingRight: 20,
                        // marginLeft: 20,
                        // marginRight: 20,
                        // marginTop: 40,
                        // marginBottom: 80,
                    },
                    plotOptions: {
                        series: {
                            dataGrouping: {
                                dateTimeLabelFormats: {
                                   millisecond:
                ['%Y-%m-%d %H:%M:%S.%L %Z', '%Y-%m-%d %H:%M:%S.%L', '-%H:%M:%S.%L %Z'],
                                   second:
                ['%Y-%m-%d %H:%M:%S %Z', '%Y-%m-%d %H:%M:%S', '-%H:%M:%S %Z'],
                                   minute:
                ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                   hour:
                ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                   day:
                ['%Y-%m-%d %Z', '%Y-%m-%d', '-%m-%d %Z'],
                                   week:
                ['Week from %Y-%m-%d', '%Y-%m-%d', '-%Y-%m-%d'],
                                   month:
                ['%Y-%m', '%Y-%m', '-%Y-%m'],
                                   year: ['%Y', '%Y', '-%Y']
                ['%Y', '%Y', '-%Y'],
                                }
                            }
                        }
                    },
                    xAxis: {
                        type: 'datetime',
                        // opted not to add %Z to these formats.
                        // The timezone is in the xAxis label, and in
                        // the tooltip popups.
                        dateTimeLabelFormats: {
                            millisecond: '%H:%M:%S.%L',
                            second: '%H:%M:%S',
                            minute: '%H:%M',
                            hour: '%H:%M',
                            day: '%Y
%m-%d',
                            month: '%Y
%m',
                            year: '%Y'
                        },
                        startOnTick: false,
                        endOnTick: false,
                        title: {
                            text: "time (" + local_ns.plotTimezone + ")"
                        },
                    },
                    yAxis: yAxis,
                    series: series,
                    legend: {
                        enabled: true,
                        margin: 0,
                    },
                    rangeSelector: {
                        enabled: false,
                    },
                    navigator: {
                        height: 25,
                        margin: 5,
                    },
                    title: {
                            text: ptitle,
                    }
                });
            });

            $("div[id^='heatmap']").each(function(index) {

                var vnames =  $( this ).data("variables");
                var vunits =  $( this ).data("units");
                var long_names = $( this ).data("long_names");

                console.log("heatmap, vnames=",vnames,
                        ",time.length=",time.length,
                        ",dim2.length=",dim2['data'].length);

                if (long_names.length == 0) {
                    long_names = vnames;
                }

                // var vname =  $( this ).data("variable");
                // var units =  $( this ).data("units");
                // var long_name =  $( this ).data("long_name");
                // var dim2_name =  $( this ).data("dim2_name");
                var dim2_name = dim2['name'];
                var dim2_units = dim2['units'];

                for (var iv = 0; iv < vnames.length; iv++) {
                    vname = vnames[iv];
                    long_name = long_names[iv];
                    units = vunits[iv];

                    minval = Number.POSITIVE_INFINITY;
                    maxval = Number.NEGATIVE_INFINITY;

                    var datetime = true;

                    if (datetime) {
                        mintime = (time0 + time[0]) * 1000;
                        maxtime = (time0 + time[time.length-1]) * 1000;
                    }
                    else {
                        // mintime = time[0] * 1000;
                        // maxtime = time[time.length-1] * 1000;
                        mintime = time[0];
                        maxtime = time[time.length-1];
                    }

                    mindim2 = dim2['data'][0];
                    maxdim2 = dim2['data'][dim2['data'].length-1];

                    var chart_data = [];
                    for (var i = 0; i < time.length; i++) {
                        if (datetime) {
                            var tx = (time0 + time[i]) * 1000;
                        }
                        else {
                            // var tx = time[i] * 1000;
                            var tx = time[i];
                        }
                        for (var j = 0; j < dim2['data'].length; j++) {
                            dx = data[vname][i][j];
                            if (dx !== null) {
                                minval = Math.min(minval,dx);
                                maxval = Math.max(maxval,dx);
                            }
                            chart_data.push([tx, dim2['data'][j],dx]);
                        }
                    }
                    console.log("heatmap, chart_data.length=",chart_data.length,
                            ", chart_data[0].length=",chart_data[0].length);
                    console.log("heatmap, minval=",minval,", maxval=",maxval);

                    console.log("heatmap, colsize=", (maxtime - mintime) / 20);
                    // var colsize = 3600 * 1000;
                    var colsize = (maxtime - mintime) / (time.length - 1);
                    var rowsize = (maxdim2 - mindim2) / (dim2.length - 1);

                    /*
                    for (var i = 0; i < chart_data.length; i++) {
                        if (chart_data[i][2] === null) {
                            chart_data[i][2] = minval;
                        }
                    }
                    */

                    for (var i = 0; i < chart_data.length && i < 10; i++) {
                        for (var j = 0; j < chart_data[i].length; j++) {
                            console.log("chart_data[",i,"]=",
                                chart_data[i][0],",",chart_data[i][1],",",chart_data[i][2]);
                        }
                    }

                    $( this ).highcharts({
                        chart: {
                            type: 'heatmap',
                            marginTop: 40,
                            marginBottom: 60,
                            zoomType: 'x',
                            panning: true,
                            panKey: 'shift',
                            plotOptions: {
                                series: {
                                    dataGrouping: {
                                        dateTimeLabelFormats: {
                                           millisecond:
                        ['%Y-%m-%d %H:%M:%S.%L %Z', '%Y-%m-%d %H:%M:%S.%L', '-%H:%M:%S.%L %Z'],
                                           second:
                        ['%Y-%m-%d %H:%M:%S %Z', '%Y-%m-%d %H:%M:%S', '-%H:%M:%S %Z'],
                                           minute:
                        ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                           hour:
                        ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                           day:
                        ['%Y-%m-%d %Z', '%Y-%m-%d', '-%m-%d %Z'],
                                           week:
                        ['Week from %Y-%m-%d', '%Y-%m-%d', '-%Y-%m-%d'],
                                           month:
                        ['%Y-%m', '%Y-%m', '-%Y-%m'],
                                           year: ['%Y', '%Y', '-%Y']
                        ['%Y', '%Y', '-%Y'],
                                        }
                                    }
                                }
                            },
                        },
                        title: {
                            text: long_name + '(' + units + ')'
                        },
                        xAxis: {
                            type: 'datetime',
                            dateTimeLabelFormats: {
                                millisecond: '%H:%M:%S.%L',
                                second: '%H:%M:%S',
                                minute: '%H:%M',
                                hour: '%H:%M',
                                day: '%Y
%m-%d',
                                month: '%Y
%m',
                                year: '%Y'
                            },
                            /*
                            min: mintime,
                            max: maxtime,
                            */
                            title: {
                                margin: 0,
                                text: "time (" + local_ns.plotTimezone + ")",
                            },
                            /*
                            tickPixelInterval: (maxtime - mintime) / 100,
                            ordinal: false,
                            */
                        },
                        yAxis: {
                            title: {
                                text: dim2_name + '(' + dim2_units + ')'
                            },
                            min: mindim2,
                            max: maxdim2,
                            tickWidth: 2,
                            /*
                            ordinal: false,
                            */
                        },
                        colorAxis: {
                            stops: [
                                [0, '#3060cf'],
                                [0.5, '#fffbbc'],
                                [0.9, '#c4463a']
                            ],
                            min: minval,
                            max: maxval,
                            // minColor: '#FFFFFF',
                            // maxColor: Highcharts.getOptions().colors[0]
                        },
                        legend: {
                            title: vname,
                            reversed: true,
                            align: 'right',
                            layout: 'vertical',
                            margin: 15,
                            verticalAlign: 'bottom'
                        },
                        series:[{
                            data: chart_data,
                            colsize: colsize,
                            rowsize: rowsize,
                            tooltip: {
                                enabled: true,
                                /*
                                headerFormat: vname + "
",
                                */
                                headerFormat: '',
                                pointFormat: 'time:{point.x:%H:%M:%S %Z},' + dim2_name + ':{point.y},' + vname + ':{point.value}'
                            }
                        }],
                    });
                }
            });
            /*
            $("#id_time_length_choice").change(function() {
                console.log("time_length_choice change, val=",$(this).val());
                if ($(this).val() == '0' || $(this).val() == '') {
                    $("#id_time_length_val").show();
                }
                else {
                    $("#id_time_length_val").hide();
                }
            });
            */
        });
    })
);

<commit_msg>Reformatted tooltip in heatmap<commit_after>// See gregfranko.com/blog/jquery-best-practices
//
// IIFE: Immediately Invoked Function Expression
(function(main_iife_function) {
        main_iife_function(window.jQuery, window, document);
    }(function($,window,document) {

        // Put local variables and functions into this namespace
        local_ns = {}

        local_ns.unique = function(arr) {
            return arr.filter(function(value, index, array) {
                return array.indexOf(value) === index;
            });
        };

        local_ns.setPlotTimezone = function(val) {
            // console.log("calling Highcharts.setOptions,val",val);
            local_ns.plotTimezone = val;
            local_ns.zone = moment.tz.zone(val);
            Highcharts.setOptions({
                global: {
                    getTimezoneOffset: function(timestamp) {
                        var timezoneOffset =
                            -moment.tz(timestamp,local_ns.plotTimezone).utcOffset();
                        // console.log("timezoneOffset=",timezoneOffset);
                        return timezoneOffset;
                    },
                    // Documentation on this seems wrong. With the current
                    // logic here, we must set this to true.
                    useUTC: true,
                }
            });
        };

        // Add support for %Z time formatter
        Highcharts.dateFormats = {
            Z: function (timestamp) {
                // console.log("zone.abbr=",local_ns.zone.abbr(timestamp));
                return local_ns.zone.abbr(timestamp);
            }
        };

        $(function() {
            // console.log("DOM is ready!");

            // When doc is ready, grab the selected time zone
            var tzelem = $("select#id_timezone");
            var tz = tzelem.val();
            local_ns.pickerTimezone = tz;
            local_ns.setPlotTimezone(tz);
            // console.log("select#id_timezone tz=",tz)

            $("select#id_timezone").change(function() {
                // When user changes the timezone, adjust the time
                // in the datetimepicker so that it is the
                // same moment in time as with the previous timezone.
                //
                // Unfortunately datetimepicker time formats
                // are different than moment time formats:
                // datetimepicker:  "yyyy-mm-dd hh:ii"
                // moment:          "YYYY-MM-DD HH:mm"
                // The moment format is hard-coded here, and so
                // if the datetimepicker format is changed in
                // django/python, it must be changed here.
                //
                // Also couldn't find out how to get the current
                // datetimepicker format.
                //
                // To avoid formatting times one would get/set
                // from datetimepicker using javascript Date objects.
                // However, a javascript Date is either in the
                // browser's time zone or UTC. I believe there would
                // always be a problem right around the time of
                // daylight savings switches, if Date is used.

                // Note that we don't change the value of
                // the timezone in local_ns, since that must match
                // what is plotted.

                var picker = $("input#id_start_time");
                var dstr = picker.val();

                // console.log("picker.val()=",dstr);

                // parse time using current timezone
                var mom = moment.tz(dstr,'YYYY-MM-DD HH:mm',local_ns.pickerTimezone);

                // get the new timezone
                var new_tz = $(this).val();

                // save previous value, but don't
                local_ns.pickerTimezone = new_tz;

                // adjust time for new timezone
                mom = mom.tz(new_tz);

                // format it, and set it on the picker
                dstr = mom.format('YYYY-MM-DD HH:mm');
                picker.val(dstr);
            });

            $("div[id^='time-series']").each(function(index) {
                // console.log("time-series");

                var vnames =  $( this ).data("variables");
                var vunits =  $( this ).data("units");
                var long_names =  $( this ).data("long_names");
                if (long_names.length == 0) {
                    long_names = vnames;
                }
                // console.log("time-series, time.length=",time.length);
                // console.log("vnames=",vnames,", vunits=",vunits);

                // series and yAxis are arrays of dictionaries
                var yAxis = [];

                var unique_units = local_ns.unique(vunits);
                // console.log("unique_units=",unique_units);
                var opposite = false;
                for (var unit of unique_units) {
                    // console.log("unit=",unit);
                    ya = {
                        opposite: opposite,
                        title: {
                            text: unit,
                        },
                    };
                    yAxis.push(ya);
                    opposite = !opposite;
                }

                var series = [];

                if (vnames.length > 1) {
                    ptitle = vnames[0] + "...";
                }
                else {
                    ptitle = vnames[0];
                }
                for (var iv = 0; iv < vnames.length; iv++ ) {
                    var vname = vnames[iv];
                    var vunit = vunits[iv];
                    var long_name = long_names[iv];
                    var vseries = {};
                    var vdata = [];
                    for (var i = 0; i < time.length; i++) {
                        vdata.push([(time0 + time[i])*1000, data[vname][i]]);
                    }
                    vseries['data'] = vdata;
                    if (unique_units.length > 1) {
                        vseries['name'] = vname + '(' + vunit + ')';
                    }
                    else {
                        vseries['name'] = vname;
                    }
                    vseries['yAxis'] = unique_units.indexOf(vunit);
                    vseries['tooltip'] = {
                        // valueSuffix: long_name,
                        headerFormat: '{point.key}
',
                        pointFormat: '\u25CF ' + long_name + ',{series.name}: {point.y}
',
                        valueDecimals: 6,
                        xDateFormat: '%Y-%m-%d %H:%M:%S.%L %Z',
                    };
                    /* a checkbox allows one to "select" the series, but
                     * I'm not sure what that does. Clicking it doesn't
                     * make the series disappear. That is done by clicking
                     * on the name in the legend, which by default goes below
                     * the xaxis.
                     * Supposidly if you return anything other than false,
                     * the default action is to toggle the selected state
                     * of the series.
                        events: {
                            checkboxClick: function (event) {
                                alert('The checkbox is now ' + event.checked);
                                return false;
                            }
                        },
                     */
                    series.push(vseries);
                }

                $( this ).highcharts('StockChart',{
                    chart: {
                        type: 'line',
                        // zoomType: 'x',
                        // panning: true,
                        // panKey: 'shift',
                        spacingLeft: 20,
                        spacingRight: 20,
                        // marginLeft: 20,
                        // marginRight: 20,
                        // marginTop: 40,
                        // marginBottom: 80,
                    },
                    plotOptions: {
                        series: {
                            dataGrouping: {
                                dateTimeLabelFormats: {
                                   millisecond:
                ['%Y-%m-%d %H:%M:%S.%L %Z', '%Y-%m-%d %H:%M:%S.%L', '-%H:%M:%S.%L %Z'],
                                   second:
                ['%Y-%m-%d %H:%M:%S %Z', '%Y-%m-%d %H:%M:%S', '-%H:%M:%S %Z'],
                                   minute:
                ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                   hour:
                ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                   day:
                ['%Y-%m-%d %Z', '%Y-%m-%d', '-%m-%d %Z'],
                                   week:
                ['Week from %Y-%m-%d', '%Y-%m-%d', '-%Y-%m-%d'],
                                   month:
                ['%Y-%m', '%Y-%m', '-%Y-%m'],
                                   year: ['%Y', '%Y', '-%Y']
                ['%Y', '%Y', '-%Y'],
                                }
                            }
                        }
                    },
                    xAxis: {
                        type: 'datetime',
                        // opted not to add %Z to these formats.
                        // The timezone is in the xAxis label, and in
                        // the tooltip popups.
                        dateTimeLabelFormats: {
                            millisecond: '%H:%M:%S.%L',
                            second: '%H:%M:%S',
                            minute: '%H:%M',
                            hour: '%H:%M',
                            day: '%Y
%m-%d',
                            month: '%Y
%m',
                            year: '%Y'
                        },
                        startOnTick: false,
                        endOnTick: false,
                        title: {
                            text: "time (" + local_ns.plotTimezone + ")"
                        },
                    },
                    yAxis: yAxis,
                    series: series,
                    legend: {
                        enabled: true,
                        margin: 0,
                    },
                    rangeSelector: {
                        enabled: false,
                    },
                    navigator: {
                        height: 25,
                        margin: 5,
                    },
                    title: {
                        text: ptitle,
                    }
                });
            });

            $("div[id^='heatmap']").each(function(index) {

                var vnames =  $( this ).data("variables");
                var vunits =  $( this ).data("units");
                var long_names = $( this ).data("long_names");

                console.log("heatmap, vnames=",vnames,
                        ",time.length=",time.length,
                        ",dim2.length=",dim2['data'].length);

                if (long_names.length == 0) {
                    long_names = vnames;
                }

                // var vname =  $( this ).data("variable");
                // var units =  $( this ).data("units");
                // var long_name =  $( this ).data("long_name");
                // var dim2_name =  $( this ).data("dim2_name");
                var dim2_name = dim2['name'];
                var dim2_units = dim2['units'];

                for (var iv = 0; iv < vnames.length; iv++) {
                    vname = vnames[iv];
                    long_name = long_names[iv];
                    units = vunits[iv];

                    minval = Number.POSITIVE_INFINITY;
                    maxval = Number.NEGATIVE_INFINITY;

                    var datetime = true;

                    if (datetime) {
                        mintime = (time0 + time[0]) * 1000;
                        maxtime = (time0 + time[time.length-1]) * 1000;
                    }
                    else {
                        // mintime = time[0] * 1000;
                        // maxtime = time[time.length-1] * 1000;
                        mintime = time[0];
                        maxtime = time[time.length-1];
                    }

                    mindim2 = dim2['data'][0];
                    maxdim2 = dim2['data'][dim2['data'].length-1];

                    var chart_data = [];
                    for (var i = 0; i < time.length; i++) {
                        if (datetime) {
                            var tx = (time0 + time[i]) * 1000;
                        }
                        else {
                            // var tx = time[i] * 1000;
                            var tx = time[i];
                        }
                        for (var j = 0; j < dim2['data'].length; j++) {
                            dx = data[vname][i][j];
                            if (dx !== null) {
                                minval = Math.min(minval,dx);
                                maxval = Math.max(maxval,dx);
                            }
                            chart_data.push([tx, dim2['data'][j],dx]);
                        }
                    }
                    console.log("heatmap, chart_data.length=",chart_data.length,
                            ", chart_data[0].length=",chart_data[0].length);
                    console.log("heatmap, minval=",minval,", maxval=",maxval);

                    console.log("heatmap, colsize=", (maxtime - mintime) / 20);
                    // var colsize = 3600 * 1000;
                    var colsize = (maxtime - mintime) / (time.length - 1);
                    var rowsize = (maxdim2 - mindim2) / (dim2.length - 1);

                    /*
                    for (var i = 0; i < chart_data.length; i++) {
                        if (chart_data[i][2] === null) {
                            chart_data[i][2] = minval;
                        }
                    }
                    */

                    for (var i = 0; i < chart_data.length && i < 10; i++) {
                        for (var j = 0; j < chart_data[i].length; j++) {
                            console.log("chart_data[",i,"]=",
                                chart_data[i][0],",",chart_data[i][1],",",chart_data[i][2]);
                        }
                    }

                    $( this ).highcharts({
                        chart: {
                            type: 'heatmap',
                            marginTop: 40,
                            marginBottom: 60,
                            zoomType: 'x',
                            panning: true,
                            panKey: 'shift',
                            plotOptions: {
                                series: {
                                    dataGrouping: {
                                        dateTimeLabelFormats: {
                                           millisecond:
                        ['%Y-%m-%d %H:%M:%S.%L %Z', '%Y-%m-%d %H:%M:%S.%L', '-%H:%M:%S.%L %Z'],
                                           second:
                        ['%Y-%m-%d %H:%M:%S %Z', '%Y-%m-%d %H:%M:%S', '-%H:%M:%S %Z'],
                                           minute:
                        ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                           hour:
                        ['%Y-%m-%d %H:%M %Z', '%Y-%m-%d %H:%M', '-%H:%M %Z'],
                                           day:
                        ['%Y-%m-%d %Z', '%Y-%m-%d', '-%m-%d %Z'],
                                           week:
                        ['Week from %Y-%m-%d', '%Y-%m-%d', '-%Y-%m-%d'],
                                           month:
                        ['%Y-%m', '%Y-%m', '-%Y-%m'],
                                           year: ['%Y', '%Y', '-%Y']
                        ['%Y', '%Y', '-%Y'],
                                        }
                                    }
                                }
                            },
                        },
                        title: {
                            text: long_name + '(' + units + ')'
                        },
                        xAxis: {
                            type: 'datetime',
                            dateTimeLabelFormats: {
                                millisecond: '%H:%M:%S.%L',
                                second: '%H:%M:%S',
                                minute: '%H:%M',
                                hour: '%H:%M',
                                day: '%Y
%m-%d',
                                month: '%Y
%m',
                                year: '%Y'
                            },
                            /*
                            min: mintime,
                            max: maxtime,
                            */
                            title: {
                                margin: 0,
                                text: "time (" + local_ns.plotTimezone + ")",
                            },
                            /*
                            tickPixelInterval: (maxtime - mintime) / 100,
                            ordinal: false,
                            */
                        },
                        yAxis: {
                            title: {
                                text: dim2_name + '(' + dim2_units + ')'
                            },
                            min: mindim2,
                            max: maxdim2,
                            tickWidth: 2,
                            /*
                            ordinal: false,
                            */
                        },
                        colorAxis: {
                            stops: [
                                [0, '#3060cf'],
                                [0.5, '#fffbbc'],
                                [0.9, '#c4463a']
                            ],
                            min: minval,
                            max: maxval,
                            // minColor: '#FFFFFF',
                            // maxColor: Highcharts.getOptions().colors[0]
                        },
                        legend: {
                            title: vname,
                            reversed: true,
                            align: 'right',
                            layout: 'vertical',
                            margin: 15,
                            verticalAlign: 'bottom'
                        },
                        series:[{
                            data: chart_data,
                            colsize: colsize,
                            rowsize: rowsize,
                            tooltip: {
                                enabled: true,
                                /*
                                headerFormat: vname + "
",
                                */
                                headerFormat: '',
                                pointFormat:  dim2_name + '={point.y}, ' + vname + '={point.value}, {point.x:%H:%M:%S %Z}'
                            }
                        }],
                    });
                }
            });
            /*
            $("#id_time_length_choice").change(function() {
                console.log("time_length_choice change, val=",$(this).val());
                if ($(this).val() == '0' || $(this).val() == '') {
                    $("#id_time_length_val").show();
                }
                else {
                    $("#id_time_length_val").hide();
                }
            });
            */
        });
    })
);

<|endoftext|>


<commit_before>var postcss = require('reduce-css-postcss');
var path = require('path')

var fixtures = path.resolve.bind(path, __dirname);

function customTransform() {
}

module.exports = {
  watch: {

  },
  css: {
    transforms: [
         //[customTransform, args1, args2],
         //[anothercustomTransform, args1, args2],
    ],
    entry: "**/*.css",
    output: [
         fixtures('build'),
         null,
         {
           maxSize: 0,
           useHash: false,
           assetOutFolder: fixtures('build/assets/i')
         }
    ],
    deps: {
      //atDeps: 'deps',
      basedir: fixtures('src'),
      factor: {
        needFactor: true,
        common: 'common.css',
        //threshold: 1,
      },
    },
    on: {
      log: console.log.bind(console),
      error: function (err) {
        console.log(err);
      },
      instance: function (b) {
        b.plugin(postcss);
      },
    },
  },
  js: {
    transforms: [],
    entry: '**/*.js',
    output: fixtures('build'),
    deps: {
      basedir: fixtures('src'),
      factor: {
        needFactor: true,
        common: 'common.js',
        //threshold: ['**/common.js'],
      },
    },
    on: {
      log: console.log.bind(console),
      error: function (err) {
        console.log(err);
      },
      instance: function (b) {
      },
    },
  },
};
<commit_msg>update config file<commit_after>var postcss = require('reduce-css-postcss');
var path = require('path')

var fixtures = path.resolve.bind(path, __dirname);

function customTransform() {
}

module.exports = {
  watch: {

  },
  css: {
    transforms: [
         //[customTransform, args1, args2],
         //[anothercustomTransform, args1, args2],
    ],
    entry: "**/*.css",
    output: [
         fixtures('build'),
         null,
         //Doc: https://github.com/zoubin/postcss-custom-url#util
         {
           maxSize: 0,
           useHash: false,
           assetOutFolder: fixtures('build/assets/i')
         }
    ],
    //Doc: https://github.com/zoubin/reduce-css#api
    deps: {
      basedir: fixtures('src'),
      //Doc: https://github.com/zoubin/factor-vinylify#options
      factor: {
        needFactor: true,
        common: 'common.css',
        //threshold: 1,
      },
    },
    on: {
      log: console.log.bind(console),
      error: function (err) {
        console.log(err);
      },
      instance: function (b) {
        b.plugin(postcss, {
          processorFilter: [require('postcss-calc')],
        });
      },
    },
  },
  js: {
    transforms: [],
    entry: '**/*.js',
    output: fixtures('build'),
    //Doc: https://github.com/zoubin/reduce-js#api
    deps: {
      basedir: fixtures('src'),
      //Doc: https://github.com/zoubin/factor-vinylify#options
      factor: {
        needFactor: true,
        common: 'common.js',
        //threshold: ['**/common.js'],
      },
    },
    on: {
      log: console.log.bind(console),
      error: function (err) {
        console.log(err);
      },
      instance: function (b) {
      },
    },
  },
};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";

ChromeUtils.defineModuleGetter(
  this,
  "Services",
  "resource://gre/modules/Services.jsm"
);
ChromeUtils.defineModuleGetter(
  this,
  "EveryWindow",
  "resource:///modules/EveryWindow.jsm"
);

const WHATSNEW_ENABLED_PREF = "browser.messaging-system.whatsNewPanel.enabled";

const TOOLBAR_BUTTON_ID = "whats-new-menu-button";
const APPMENU_BUTTON_ID = "appMenu-whatsnew-button";
const PANEL_HEADER_SELECTOR = "#PanelUI-whatsNew-title > label";

const BUTTON_STRING_ID = "cfr-whatsnew-button";

class _ToolbarPanelHub {
  constructor() {
    this._showAppmenuButton = this._showAppmenuButton.bind(this);
    this._hideAppmenuButton = this._hideAppmenuButton.bind(this);
    this._showToolbarButton = this._showToolbarButton.bind(this);
    this._hideToolbarButton = this._hideToolbarButton.bind(this);
  }

  init({ getMessages }) {
    this._getMessages = getMessages;
    if (this.whatsNewPanelEnabled) {
      this.enableAppmenuButton();
    }
  }

  uninit() {
    EveryWindow.unregisterCallback(TOOLBAR_BUTTON_ID);
    EveryWindow.unregisterCallback(APPMENU_BUTTON_ID);
  }

  get whatsNewPanelEnabled() {
    return Services.prefs.getBoolPref(WHATSNEW_ENABLED_PREF, false);
  }

  maybeInsertFTL(win) {
    win.MozXULElement.insertFTLIfNeeded("browser/newtab/asrouter.ftl");
  }

  // Turns on the Appmenu (hamburger menu) button for all open windows and future windows.
  enableAppmenuButton() {
    EveryWindow.registerCallback(
      APPMENU_BUTTON_ID,
      this._showAppmenuButton,
      this._hideAppmenuButton
    );
  }

  // Turns on the Toolbar button for all open windows and future windows.
  enableToolbarButton() {
    EveryWindow.registerCallback(
      TOOLBAR_BUTTON_ID,
      this._showToolbarButton,
      this._hideToolbarButton
    );
  }

  // Render what's new messages into the panel.
  async renderMessages(win, doc, containerId) {
    const messages = (await this._getMessages({
      template: "whatsnew_panel_message",
      triggerId: "whatsNewPanelOpened",
      returnAll: true,
    })).sort((m1, m2) => {
      // Sort by published_date in descending order.
      if (m1.content.published_date === m2.content.published_date) {
        return 0;
      }
      if (m1.content.published_date > m2.content.published_date) {
        return -1;
      }
      return 1;
    });
    const container = doc.getElementById(containerId);

    if (messages && !container.querySelector(".whatsNew-message")) {
      let previousDate = 0;
      for (let { content } of messages) {
        container.appendChild(
          this._createMessageElements(win, doc, content, previousDate)
        );
        previousDate = content.published_date;
      }
    }

    // TODO: TELEMETRY
  }

  _createMessageElements(win, doc, content, previousDate) {
    const messageEl = this._createElement(doc, "div");
    messageEl.classList.add("whatsNew-message");

    // Only render date if it is different from the one rendered before.
    if (content.published_date !== previousDate) {
      messageEl.appendChild(
        this._createDateElement(doc, content.published_date)
      );
    }

    const wrapperEl = this._createElement(doc, "div");
    wrapperEl.classList.add("whatsNew-message-body");
    messageEl.appendChild(wrapperEl);
    wrapperEl.addEventListener("click", () => {
      win.ownerGlobal.openLinkIn(content.cta_url, "tabshifted", {
        private: false,
        triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
          {}
        ),
        csp: null,
      });

      // TODO: TELEMETRY
    });

    if (content.icon_url) {
      wrapperEl.classList.add("has-icon");
      const iconEl = this._createElement(doc, "img");
      iconEl.src = content.icon_url;
      iconEl.classList.add("whatsNew-message-icon");
      wrapperEl.appendChild(iconEl);
    }

    const titleEl = this._createElement(doc, "h2");
    titleEl.classList.add("whatsNew-message-title");
    this._setString(doc, titleEl, content.title);
    wrapperEl.appendChild(titleEl);

    const bodyEl = this._createElement(doc, "p");
    this._setString(doc, bodyEl, content.body);
    wrapperEl.appendChild(bodyEl);

    if (content.link_text) {
      const linkEl = this._createElement(doc, "button");
      linkEl.classList.add("text-link");
      this._setString(doc, linkEl, content.link_text);
      wrapperEl.appendChild(linkEl);
    }

    return messageEl;
  }

  _createElement(doc, elem) {
    return doc.createElementNS("http://www.w3.org/1999/xhtml", elem);
  }

  _createDateElement(doc, date) {
    const dateEl = this._createElement(doc, "p");
    dateEl.classList.add("whatsNew-message-date");
    dateEl.textContent = new Date(date).toLocaleDateString("default", {
      month: "long",
      day: "numeric",
      year: "numeric",
    });
  }

  // If `string_id` is present it means we are relying on fluent for translations.
  // Otherwise, we have a vanilla string.
  _setString(doc, el, stringObj) {
    if (stringObj.string_id) {
      doc.l10n.setAttributes(el, stringObj.string_id);
    } else {
      el.textContent = stringObj;
    }
  }

  _showAppmenuButton(win) {
    this.maybeInsertFTL(win);
    this._showElement(
      win.browser.ownerDocument,
      APPMENU_BUTTON_ID,
      BUTTON_STRING_ID
    );
  }

  _hideAppmenuButton(win) {
    this._hideElement(win.browser.ownerDocument, APPMENU_BUTTON_ID);
  }

  _showToolbarButton(win) {
    const document = win.browser.ownerDocument;
    this.maybeInsertFTL(win);
    this._showElement(document, TOOLBAR_BUTTON_ID, BUTTON_STRING_ID);
    // The toolbar dropdown panel uses this extra header element that is hidden
    // in the appmenu subview version of the panel. We only need to set it
    // when showing the toolbar button.
    document.l10n.setAttributes(
      document.querySelector(PANEL_HEADER_SELECTOR),
      "cfr-whatsnew-panel-header"
    );
  }

  _hideToolbarButton(win) {
    this._hideElement(win.browser.ownerDocument, TOOLBAR_BUTTON_ID);
  }

  _showElement(document, id, string_id) {
    const el = document.getElementById(id);
    document.l10n.setAttributes(el, string_id);
    el.removeAttribute("hidden");
  }

  _hideElement(document, id) {
    document.getElementById(id).setAttribute("hidden", true);
  }
}

this._ToolbarPanelHub = _ToolbarPanelHub;

/**
 * ToolbarPanelHub - singleton instance of _ToolbarPanelHub that can initiate
 * message requests and render messages.
 */
this.ToolbarPanelHub = new _ToolbarPanelHub();

const EXPORTED_SYMBOLS = ["ToolbarPanelHub", "_ToolbarPanelHub"];
<commit_msg>(nobug) - Fix _createDateElement() helper (#5166)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";

ChromeUtils.defineModuleGetter(
  this,
  "Services",
  "resource://gre/modules/Services.jsm"
);
ChromeUtils.defineModuleGetter(
  this,
  "EveryWindow",
  "resource:///modules/EveryWindow.jsm"
);

const WHATSNEW_ENABLED_PREF = "browser.messaging-system.whatsNewPanel.enabled";

const TOOLBAR_BUTTON_ID = "whats-new-menu-button";
const APPMENU_BUTTON_ID = "appMenu-whatsnew-button";
const PANEL_HEADER_SELECTOR = "#PanelUI-whatsNew-title > label";

const BUTTON_STRING_ID = "cfr-whatsnew-button";

class _ToolbarPanelHub {
  constructor() {
    this._showAppmenuButton = this._showAppmenuButton.bind(this);
    this._hideAppmenuButton = this._hideAppmenuButton.bind(this);
    this._showToolbarButton = this._showToolbarButton.bind(this);
    this._hideToolbarButton = this._hideToolbarButton.bind(this);
  }

  init({ getMessages }) {
    this._getMessages = getMessages;
    if (this.whatsNewPanelEnabled) {
      this.enableAppmenuButton();
    }
  }

  uninit() {
    EveryWindow.unregisterCallback(TOOLBAR_BUTTON_ID);
    EveryWindow.unregisterCallback(APPMENU_BUTTON_ID);
  }

  get whatsNewPanelEnabled() {
    return Services.prefs.getBoolPref(WHATSNEW_ENABLED_PREF, false);
  }

  maybeInsertFTL(win) {
    win.MozXULElement.insertFTLIfNeeded("browser/newtab/asrouter.ftl");
  }

  // Turns on the Appmenu (hamburger menu) button for all open windows and future windows.
  enableAppmenuButton() {
    EveryWindow.registerCallback(
      APPMENU_BUTTON_ID,
      this._showAppmenuButton,
      this._hideAppmenuButton
    );
  }

  // Turns on the Toolbar button for all open windows and future windows.
  enableToolbarButton() {
    EveryWindow.registerCallback(
      TOOLBAR_BUTTON_ID,
      this._showToolbarButton,
      this._hideToolbarButton
    );
  }

  // Render what's new messages into the panel.
  async renderMessages(win, doc, containerId) {
    const messages = (await this._getMessages({
      template: "whatsnew_panel_message",
      triggerId: "whatsNewPanelOpened",
      returnAll: true,
    })).sort((m1, m2) => {
      // Sort by published_date in descending order.
      if (m1.content.published_date === m2.content.published_date) {
        return 0;
      }
      if (m1.content.published_date > m2.content.published_date) {
        return -1;
      }
      return 1;
    });
    const container = doc.getElementById(containerId);

    if (messages && !container.querySelector(".whatsNew-message")) {
      let previousDate = 0;
      for (let { content } of messages) {
        container.appendChild(
          this._createMessageElements(win, doc, content, previousDate)
        );
        previousDate = content.published_date;
      }
    }

    // TODO: TELEMETRY
  }

  _createMessageElements(win, doc, content, previousDate) {
    const messageEl = this._createElement(doc, "div");
    messageEl.classList.add("whatsNew-message");

    // Only render date if it is different from the one rendered before.
    if (content.published_date !== previousDate) {
      messageEl.appendChild(
        this._createDateElement(doc, content.published_date)
      );
    }

    const wrapperEl = this._createElement(doc, "div");
    wrapperEl.classList.add("whatsNew-message-body");
    messageEl.appendChild(wrapperEl);
    wrapperEl.addEventListener("click", () => {
      win.ownerGlobal.openLinkIn(content.cta_url, "tabshifted", {
        private: false,
        triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
          {}
        ),
        csp: null,
      });

      // TODO: TELEMETRY
    });

    if (content.icon_url) {
      wrapperEl.classList.add("has-icon");
      const iconEl = this._createElement(doc, "img");
      iconEl.src = content.icon_url;
      iconEl.classList.add("whatsNew-message-icon");
      wrapperEl.appendChild(iconEl);
    }

    const titleEl = this._createElement(doc, "h2");
    titleEl.classList.add("whatsNew-message-title");
    this._setString(doc, titleEl, content.title);
    wrapperEl.appendChild(titleEl);

    const bodyEl = this._createElement(doc, "p");
    this._setString(doc, bodyEl, content.body);
    wrapperEl.appendChild(bodyEl);

    if (content.link_text) {
      const linkEl = this._createElement(doc, "button");
      linkEl.classList.add("text-link");
      this._setString(doc, linkEl, content.link_text);
      wrapperEl.appendChild(linkEl);
    }

    return messageEl;
  }

  _createElement(doc, elem) {
    return doc.createElementNS("http://www.w3.org/1999/xhtml", elem);
  }

  _createDateElement(doc, date) {
    const dateEl = this._createElement(doc, "p");
    dateEl.classList.add("whatsNew-message-date");
    dateEl.textContent = new Date(date).toLocaleDateString("default", {
      month: "long",
      day: "numeric",
      year: "numeric",
    });
    return dateEl;
  }

  // If `string_id` is present it means we are relying on fluent for translations.
  // Otherwise, we have a vanilla string.
  _setString(doc, el, stringObj) {
    if (stringObj.string_id) {
      doc.l10n.setAttributes(el, stringObj.string_id);
    } else {
      el.textContent = stringObj;
    }
  }

  _showAppmenuButton(win) {
    this.maybeInsertFTL(win);
    this._showElement(
      win.browser.ownerDocument,
      APPMENU_BUTTON_ID,
      BUTTON_STRING_ID
    );
  }

  _hideAppmenuButton(win) {
    this._hideElement(win.browser.ownerDocument, APPMENU_BUTTON_ID);
  }

  _showToolbarButton(win) {
    const document = win.browser.ownerDocument;
    this.maybeInsertFTL(win);
    this._showElement(document, TOOLBAR_BUTTON_ID, BUTTON_STRING_ID);
    // The toolbar dropdown panel uses this extra header element that is hidden
    // in the appmenu subview version of the panel. We only need to set it
    // when showing the toolbar button.
    document.l10n.setAttributes(
      document.querySelector(PANEL_HEADER_SELECTOR),
      "cfr-whatsnew-panel-header"
    );
  }

  _hideToolbarButton(win) {
    this._hideElement(win.browser.ownerDocument, TOOLBAR_BUTTON_ID);
  }

  _showElement(document, id, string_id) {
    const el = document.getElementById(id);
    document.l10n.setAttributes(el, string_id);
    el.removeAttribute("hidden");
  }

  _hideElement(document, id) {
    document.getElementById(id).setAttribute("hidden", true);
  }
}

this._ToolbarPanelHub = _ToolbarPanelHub;

/**
 * ToolbarPanelHub - singleton instance of _ToolbarPanelHub that can initiate
 * message requests and render messages.
 */
this.ToolbarPanelHub = new _ToolbarPanelHub();

const EXPORTED_SYMBOLS = ["ToolbarPanelHub", "_ToolbarPanelHub"];
<|endoftext|>


<commit_before>'use strict';

var winston = require('winston');
var mkdirp = require('mkdirp');
var path = require('path');
var winlog2 = (process.platform === 'win32') ? require('winston-winlog2') : null;
var throttler = require('mini-throttle');

function createLogDir(filename) {
  var logDir = path.dirname(filename);
  mkdirp(logDir, function (err) {
    if (err) { throw('Unable to create log directory \'' + logDir + '\': ERROR: ' + err); }
  });
}

var newCategory = function(categoryName, config) {

  categoryName = categoryName || 'undefined';
  var transports = [];

  config = config || {};
  config.console_level = config.console_level || 'info';

  var consoleTransport = new (winston.transports.Console)({
    level:            config.console_level,
    label:            categoryName,
    json:             false,
    //handleExceptions: true,
    timestamp:        true,

    colorize:  true
  });
  transports.push(consoleTransport);

  config.file_level = config.file_level || 'info';
  config.filename = config.filename || 'log/app.log'; // uses current working dir by default
  config.maxsize  = config.maxsize  || 1000000;       // Size in Bytes
  config.maxFile  = config.maxFiles || 3;

  createLogDir(config.filename);
  var fileTransport    = new (winston.transports.File)({
    level:            config.file_level,
    label:            categoryName,
    json:             false,
    //handleExceptions: true,
    timestamp:        true,

    tailable: true,
    filename: config.filename,
    maxsize:  config.maxsize,
    maxFiles: config.maxFiles
  });
  transports.push(fileTransport);

  if (winlog2) {

    config.winlog_level  = config.winlog_level  || 'info';
    config.winlog_source = config.winlog_source || 'node_app';

    var winlogTransport = new (winlog2)({
      level:            config.winlog_level,
      label:            categoryName,
      json:             false,
      //handleExceptions: true,
      timestamp:        true,

      source: config.winlog_source
    });

    // replace log() with throttled version

    var throttle = throttler(config.winlog_throttle || {});

    winlogTransport._log = winlogTransport.log;
    winlogTransport.log = function(level, msg, meta, callback) {

      return throttle( winlogTransport._log, level, msg, meta, callback);

    };

    // add to Winston transports

    transports.push(winlogTransport);

  }

  return winston.loggers.add(categoryName, {
    transports: transports
  });

};

module.exports = newCategory;
<commit_msg>fix call(this)<commit_after>'use strict';

var winston = require('winston');
var mkdirp = require('mkdirp');
var path = require('path');
var winlog2 = (process.platform === 'win32') ? require('winston-winlog2') : null;
var throttler = require('mini-throttle');

function createLogDir(filename) {
  var logDir = path.dirname(filename);
  mkdirp(logDir, function (err) {
    if (err) { throw('Unable to create log directory \'' + logDir + '\': ERROR: ' + err); }
  });
}

var newCategory = function(categoryName, config) {

  categoryName = categoryName || 'undefined';
  var transports = [];

  config = config || {};
  config.console_level = config.console_level || 'info';

  var consoleTransport = new (winston.transports.Console)({
    level:            config.console_level,
    label:            categoryName,
    json:             false,
    //handleExceptions: true,
    timestamp:        true,

    colorize:  true
  });
  transports.push(consoleTransport);

  config.file_level = config.file_level || 'info';
  config.filename = config.filename || 'log/app.log'; // uses current working dir by default
  config.maxsize  = config.maxsize  || 1000000;       // Size in Bytes
  config.maxFile  = config.maxFiles || 3;

  createLogDir(config.filename);
  var fileTransport    = new (winston.transports.File)({
    level:            config.file_level,
    label:            categoryName,
    json:             false,
    //handleExceptions: true,
    timestamp:        true,

    tailable: true,
    filename: config.filename,
    maxsize:  config.maxsize,
    maxFiles: config.maxFiles
  });
  transports.push(fileTransport);

  if (winlog2) {

    config.winlog_level  = config.winlog_level  || 'info';
    config.winlog_source = config.winlog_source || 'node_app';

    var winlogTransport = new (winlog2)({
      level:            config.winlog_level,
      label:            categoryName,
      json:             false,
      //handleExceptions: true,
      timestamp:        true,

      source: config.winlog_source
    });

    // replace log() with throttled version

    var throttle = throttler(config.winlog_throttle || {});

    winlogTransport._log = winlogTransport.log;
    winlogTransport.log = function(level, msg, meta, callback) {

      return throttle.call(this, winlogTransport._log, level, msg, meta, callback);

    };

    // add to Winston transports

    transports.push(winlogTransport);

  }

  return winston.loggers.add(categoryName, {
    transports: transports
  });

};

module.exports = newCategory;
<|endoftext|>


<commit_before>module.exports = function(grasshopper){
    "use strict";

    var contentTypes = {},
        base = require('./api-base')(grasshopper);

    contentTypes.getById = function (req, res){

    };

    contentTypes.getList = function (req, res){
        base.authenticateRequest(req, res, function(token){
            var limit = base.getListPageSize(req),
                skip = base.getListSkipSize(req);

            if(base.userCan(token, base.AVAILABLE_PRIVILEGES.ADMIN)) {
                grasshopper.contentTypes.list({
                    limit: limit,
                    skip: skip
                }, function(err, list){
                    if(err){
                        base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                    }
                    else {
                        base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(list), res);
                    }
                });
            }
        });
    };

    contentTypes.create = function(req, res){

    };

    return contentTypes;
};<commit_msg>Added 403 forbidden error case so tests will pass.<commit_after>module.exports = function(grasshopper){
    "use strict";

    var contentTypes = {},
        base = require('./api-base')(grasshopper);

    contentTypes.getById = function (req, res){

    };

    contentTypes.getList = function (req, res){
        base.authenticateRequest(req, res, function(token){
            var limit = base.getListPageSize(req),
                skip = base.getListSkipSize(req);

            if(base.userCan(token, base.AVAILABLE_PRIVILEGES.ADMIN)) {
                grasshopper.contentTypes.list({
                    limit: limit,
                    skip: skip
                }, function(err, list){
                    if(err){
                        base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                    }
                    else {
                        base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(list), res);
                    }
                });
            }
            else {
                base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
            }
        });
    };

    contentTypes.create = function(req, res){

    };

    return contentTypes;
};<|endoftext|>


<commit_before>const ProtocolAction = require('./_base-action.js');
const ora = require('ora');

/**
 * Retrieve the URL of the current page or navigate to a new URL.
 *
 * @example
 * module.exports = {
 *  'demo Test' : function(browser) {
 *     browser.url(function(result) {
 *       // return the current url
 *       console.log(result);
 *     });
 *
 *     // navigate to new url:
 *     browser.url('{URL}');
 *
 *     // navigate to new url:
 *     browser.url('{URL}', function(result) {
 *       console.log(result);
 *     });
 *   }
 * }
 *
 * @link /#navigate-to
 * @syntax .url([url], [callback])
 * @syntax .url(callback)
 * @param {string|function} [url] If missing, it will return the URL of the current page as an argument to the supplied callback.
 * @param {Function} [callback]
 * @api protocol.navigation
 */
module.exports = class Action extends ProtocolAction {
  command(url, callback = function(r) {return r}) {
    if (typeof url == 'string') {
      let startTime = new Date();
      let spinner;
      if (this.settings.output) {
        spinner = ora({
          text: `Loading url: ${url}\n`,
          prefixText: ' '
        }).start();
      }

      return this.transportActions.navigateTo(url).then(result => {
        if (spinner) {
          const ms = new Date() - startTime;
          spinner.info(`Loaded url ${url} in ${ms}ms`);
        }

        return callback.call(this.api, result);
      });
    }

    if (typeof url == 'function') {
      callback = url;
    }

    return this.transportActions.getCurrentUrl().then(result => {
      return callback.call(this.api, result);
    });
  }
};
<commit_msg>Set discardStdin to false while initializing ora. (#3269)<commit_after>const ProtocolAction = require('./_base-action.js');
const ora = require('ora');

/**
 * Retrieve the URL of the current page or navigate to a new URL.
 *
 * @example
 * module.exports = {
 *  'demo Test' : function(browser) {
 *     browser.url(function(result) {
 *       // return the current url
 *       console.log(result);
 *     });
 *
 *     // navigate to new url:
 *     browser.url('{URL}');
 *
 *     // navigate to new url:
 *     browser.url('{URL}', function(result) {
 *       console.log(result);
 *     });
 *   }
 * }
 *
 * @link /#navigate-to
 * @syntax .url([url], [callback])
 * @syntax .url(callback)
 * @param {string|function} [url] If missing, it will return the URL of the current page as an argument to the supplied callback.
 * @param {Function} [callback]
 * @api protocol.navigation
 */
module.exports = class Action extends ProtocolAction {
  command(url, callback = function(r) {return r}) {
    if (typeof url == 'string') {
      let startTime = new Date();
      let spinner;
      if (this.settings.output) {
        spinner = ora({
          text: `Loading url: ${url}\n`,
          prefixText: ' ',
          discardStdin: false
        }).start();
      }

      return this.transportActions.navigateTo(url).then(result => {
        if (spinner) {
          const ms = new Date() - startTime;
          spinner.info(`Loaded url ${url} in ${ms}ms`);
        }

        return callback.call(this.api, result);
      });
    }

    if (typeof url == 'function') {
      callback = url;
    }

    return this.transportActions.getCurrentUrl().then(result => {
      return callback.call(this.api, result);
    });
  }
};
<|endoftext|>


<commit_before>module.exports = (function(){
    'use strict';

    var engine = {},
        AWS = require('aws-sdk'),
        createError = require('../../utils/error'),
        sort = require('../sort'),
        async = require('async'),
        q = require('q'),
        fs = require('fs'),
        path = require('path'),
        url = require('url'),
        mime = require('mime'),
        internal = {},
        LOGGING_CATEGORY = 'AWS-ASSET-MANAGER';

    internal.buildKey = function(nodeid, filename) {
        return (internal.configs.assetsDir ? internal.configs.assetsDir + '/' : '') + nodeid + '/' + filename;
    };

    internal.constructUrl = function(fileKey){
        return url.resolve(internal.config.urlbase, path.join(internal.config.bucket,fileKey));
    };

    internal.putObject = function(nodeid, filename, path){
        var self = this,
            deferred = q.defer();

        fs.stat(path, function(err, info) {
            var stream = fs.createReadStream(path);

            self.s3.putObject({
                Bucket: internal.config.bucket,
                ACL: 'public-read',
                Key: internal.buildKey(nodeid, filename),
                ContentLength: info.size,
                ContentType : mime.lookup(path),
                Body: stream
            }, function (err, data) {
                if(err){
                    deferred.reject(err);
                }
                else {
                    deferred.resolve(data);
                }
            });
        });

        return deferred.promise;
    };

    internal.copyObject = function(sourceNodeId, sourceName, destNodeId, destName){
        var deferred = q.defer();

        this.s3.copyObject({
            Bucket: internal.config.bucket,
            ACL: 'public-read',
            CopySource: internal.buildKey(sourceNodeId, sourceName),
            Key: internal.buildKey(destNodeId, destName)
        }, function (err, data) {
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve(data);
            }
        });

        return deferred.promise;
    };

    internal.deleteObject = function(nodeid, filename){
        var deferred = q.defer();

        this.s3.deleteObject({
            Bucket: internal.config.bucket,
            Key: internal.buildKey(nodeid, filename)
        }, function (err, data) {
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve(data);
            }
        });

        return deferred.promise;
    };

    internal.listObjects = function(nodeid){
        var allKeys = [],
            deferred = q.defer();

        if (nodeid) {
            this.s3.listObjects({
                Bucket: internal.config.bucket,
                Prefix: (internal.config.assetsDir || '') + nodeid
            }, function(err, data) {
                if (err) {
                    deferred.reject(err);
                } else {
                    allKeys.push(data.Contents);
                    deferred.resolve(allKeys);
                }
            });
        } else {
            // Cannot add assets to root node, and do not want to return all results for entire bucket, so show empty
            deferred.resolve([[]]);
        }
        return deferred.promise;
    };

    internal.getObject = function(nodeid, filename) {
        var deferred = q.defer();

        this.s3.getObject({
            Bucket: internal.config.bucket,
            Key: internal.buildKey(nodeid, filename)
        }, function(err, data) {
                if (err) {
                    if(err.statusCode === 404){
                        deferred.reject(createError(404));
                    }
                    else {
                        deferred.reject(err);
                    }
                    return;
                }
            deferred.resolve(data);
        });

        return deferred.promise;
    };

    internal.validateBucket = function(bucket){
        this.s3.headBucket({Bucket: bucket}, function (err) {
            if(err) {
                console.log(LOGGING_CATEGORY, '!!!!!!!!!!! ERROR !!!!!!!!!!!!!');
                console.log(LOGGING_CATEGORY, 'There is a problem accessing your Amazon S3 bucket.');
                console.log(LOGGING_CATEGORY, JSON.stringify(err));
            }
        });
    };

    engine.config = function(config){
        internal.config = config;

        AWS.config.update({
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            region: config.region
        });

        internal.s3 = new AWS.S3();
        internal.validateBucket(config.bucket);

        return this;
    };

    engine.createDirectory = function(){
        //Amazon does not have logical directories. We are implementing this method just to conform to contract.
        var deferred = q.defer();
        deferred.resolve({message: 'Success'});
        return deferred.promise;
    };

    engine.removeDirectory = function(){
        //Amazon does not have logical directories. We are implementing this method just to conform to contract.
        var deferred = q.defer();
        deferred.resolve({message: 'Success'});
        return deferred.promise;
    };

    engine.rename = function(params){
        var deferred = q.defer();

        function copy(next){
            internal.copyObject(params.nodeid, params.original, params.nodeid, params.updated)
                .then(function(){
                    next();
                })
                .fail(function(err){
                    next(err);
                });
        }

        function del(next){
            internal.deleteObject(params.nodeid, params.original)
                .then(function(){
                    next(null);
                })
                .fail(function(err){
                    next(err);
                });
        }

        function done(err){
            if(err){
                if(err.statusCode === 404){
                    deferred.reject(createError(404));
                }
                else {
                    deferred.reject(err);
                }
            }
            else {
                deferred.resolve({message: 'Success'});
            }
        }

        async.waterfall([copy, del],done);

        return deferred.promise;
    };

    engine.move = function(params){
        var deferred = q.defer();

        internal.copyObject(params.nodeid, params.filename, params.newnodeid, params.filename)
            .fail(function(err){
                deferred.reject(err);
            })
            .then(function(){
                internal.deleteObject(params.nodeid, params.filename)
                    .then(function(){
                        deferred.resolve({message: 'Success'});
                    })
                    .fail(function(err){
                        deferred.reject(err);
                    });
            });

        return deferred.promise;
    };

    engine.copy = function(params){
        var deferred = q.defer();

        internal.copyObject(params.nodeid, params.filename, params.newnodeid, params.filename)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function(err){
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.delete = function(params){
        var deferred = q.defer();

        internal.deleteObject(params.nodeid, params.filename)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function (err) {
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.deleteAll = function(params){
        var deferred = q.defer();

        function getAllKeys(next){
            var keyCollection = [];

            function buildKeyObject(obj, cb){
                keyCollection.push({
                    Key: obj.Key
                });

                cb();
            }

            internal.listObjects(params.nodeid, null)
                .fail(function(err){
                    next(err);
                })
                .then(function(data){
                    async.each(data[0], buildKeyObject, function(err){
                        next(err, keyCollection);
                    });
                });
        }

        function deleteKeys(keys, next){

            if(keys.length > 0){
                var opts = {
                    Bucket: internal.config.bucket,
                    Delete: { Objects: keys }
                };

                internal.s3.deleteObjects(opts,  function (err) {
                    next(err);
                });
            }
            else {
                next();
            }
        }

        function done(err){
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve({message: 'Success'});
            }
        }

        async.waterfall([getAllKeys, deleteKeys], done);

        return deferred.promise;
    };

    engine.save = function(params){
        var deferred = q.defer();

        internal.putObject(params.nodeid, params.filename, params.path)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function (err) {
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.list = function(params){
        var deferred = q.defer();

        internal.listObjects(params.nodeid, null)
            .fail(function(err){
                deferred.reject(err);
            })
            .then(function(data){
                var results = [];

                async.each(data[0],
                    function(item, next){
                        if(item.Size > 0){
                            results[results.length] = {
                                url: internal.constructUrl(item.Key),
                                size: item.Size,
                                lastmodified: item.LastModified
                            };
                        }
                        next();
                    },function(){
                        deferred.resolve(
                            sort(results, 'url')
                        );
                    }
                );
            });

        return deferred.promise;
    };

    engine.find = function(params){
        var deferred = q.defer();

        internal.getObject(params.nodeid, params.filename)
            .then(function(file){
                var results = {};

                if(file.ContentLength > 0){
                    results = {
                        url: internal.constructUrl(internal.buildKey(params.nodeid, params.filename)),
                        size: file.ContentLength,
                        lastmodified: file.LastModified
                    };
                }

                deferred.resolve(results);
            },
            function(err){
                deferred.reject(err);
            });

        return deferred.promise;
    };

    return engine;
})();
<commit_msg>touch up build key method and pull only files from specified node<commit_after>module.exports = (function(){
    'use strict';

    var engine = {},
        AWS = require('aws-sdk'),
        createError = require('../../utils/error'),
        sort = require('../sort'),
        async = require('async'),
        q = require('q'),
        fs = require('fs'),
        path = require('path'),
        url = require('url'),
        mime = require('mime'),
        internal = {},
        LOGGING_CATEGORY = 'AWS-ASSET-MANAGER';

    internal.buildKey = function(nodeid, filename) {
        return (internal.config.assetsDir ? internal.config.assetsDir + '/' : '') + nodeid + (filename ? '/' + filename : '');
    };

    internal.constructUrl = function(fileKey){
        return url.resolve(internal.config.urlbase, path.join(internal.config.bucket,fileKey));
    };

    internal.putObject = function(nodeid, filename, path){
        var self = this,
            deferred = q.defer();

        fs.stat(path, function(err, info) {
            var stream = fs.createReadStream(path);

            self.s3.putObject({
                Bucket: internal.config.bucket,
                ACL: 'public-read',
                Key: internal.buildKey(nodeid, filename),
                ContentLength: info.size,
                ContentType : mime.lookup(path),
                Body: stream
            }, function (err, data) {
                if(err){
                    deferred.reject(err);
                }
                else {
                    deferred.resolve(data);
                }
            });
        });

        return deferred.promise;
    };

    internal.copyObject = function(sourceNodeId, sourceName, destNodeId, destName){
        var deferred = q.defer();

        this.s3.copyObject({
            Bucket: internal.config.bucket,
            ACL: 'public-read',
            CopySource: internal.buildKey(sourceNodeId, sourceName),
            Key: internal.buildKey(destNodeId, destName)
        }, function (err, data) {
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve(data);
            }
        });

        return deferred.promise;
    };

    internal.deleteObject = function(nodeid, filename){
        var deferred = q.defer();

        this.s3.deleteObject({
            Bucket: internal.config.bucket,
            Key: internal.buildKey(nodeid, filename)
        }, function (err, data) {
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve(data);
            }
        });

        return deferred.promise;
    };

    internal.listObjects = function(nodeid){
        var allKeys = [],
            deferred = q.defer();

        if (nodeid) {
            this.s3.listObjects({
                Bucket: internal.config.bucket,
                Prefix: internal.buildKey(nodeid)
            }, function(err, data) {
                if (err) {
                    deferred.reject(err);
                } else {
                    allKeys.push(data.Contents);
                    deferred.resolve(allKeys);
                }
            });
        } else {
            // Cannot add assets to root node, and do not want to return all results for entire bucket, so show empty
            deferred.resolve([[]]);
        }
        return deferred.promise;
    };

    internal.getObject = function(nodeid, filename) {
        var deferred = q.defer();

        this.s3.getObject({
            Bucket: internal.config.bucket,
            Key: internal.buildKey(nodeid, filename)
        }, function(err, data) {
                if (err) {
                    if(err.statusCode === 404){
                        deferred.reject(createError(404));
                    }
                    else {
                        deferred.reject(err);
                    }
                    return;
                }
            deferred.resolve(data);
        });

        return deferred.promise;
    };

    internal.validateBucket = function(bucket){
        this.s3.headBucket({Bucket: bucket}, function (err) {
            if(err) {
                console.log(LOGGING_CATEGORY, '!!!!!!!!!!! ERROR !!!!!!!!!!!!!');
                console.log(LOGGING_CATEGORY, 'There is a problem accessing your Amazon S3 bucket.');
                console.log(LOGGING_CATEGORY, JSON.stringify(err));
            }
        });
    };

    engine.config = function(config){
        internal.config = config;

        AWS.config.update({
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            region: config.region
        });

        internal.s3 = new AWS.S3();
        internal.validateBucket(config.bucket);

        return this;
    };

    engine.createDirectory = function(){
        //Amazon does not have logical directories. We are implementing this method just to conform to contract.
        var deferred = q.defer();
        deferred.resolve({message: 'Success'});
        return deferred.promise;
    };

    engine.removeDirectory = function(){
        //Amazon does not have logical directories. We are implementing this method just to conform to contract.
        var deferred = q.defer();
        deferred.resolve({message: 'Success'});
        return deferred.promise;
    };

    engine.rename = function(params){
        var deferred = q.defer();

        function copy(next){
            internal.copyObject(params.nodeid, params.original, params.nodeid, params.updated)
                .then(function(){
                    next();
                })
                .fail(function(err){
                    next(err);
                });
        }

        function del(next){
            internal.deleteObject(params.nodeid, params.original)
                .then(function(){
                    next(null);
                })
                .fail(function(err){
                    next(err);
                });
        }

        function done(err){
            if(err){
                if(err.statusCode === 404){
                    deferred.reject(createError(404));
                }
                else {
                    deferred.reject(err);
                }
            }
            else {
                deferred.resolve({message: 'Success'});
            }
        }

        async.waterfall([copy, del],done);

        return deferred.promise;
    };

    engine.move = function(params){
        var deferred = q.defer();

        internal.copyObject(params.nodeid, params.filename, params.newnodeid, params.filename)
            .fail(function(err){
                deferred.reject(err);
            })
            .then(function(){
                internal.deleteObject(params.nodeid, params.filename)
                    .then(function(){
                        deferred.resolve({message: 'Success'});
                    })
                    .fail(function(err){
                        deferred.reject(err);
                    });
            });

        return deferred.promise;
    };

    engine.copy = function(params){
        var deferred = q.defer();

        internal.copyObject(params.nodeid, params.filename, params.newnodeid, params.filename)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function(err){
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.delete = function(params){
        var deferred = q.defer();

        internal.deleteObject(params.nodeid, params.filename)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function (err) {
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.deleteAll = function(params){
        var deferred = q.defer();

        function getAllKeys(next){
            var keyCollection = [];

            function buildKeyObject(obj, cb){
                keyCollection.push({
                    Key: obj.Key
                });

                cb();
            }

            internal.listObjects(params.nodeid, null)
                .fail(function(err){
                    next(err);
                })
                .then(function(data){
                    async.each(data[0], buildKeyObject, function(err){
                        next(err, keyCollection);
                    });
                });
        }

        function deleteKeys(keys, next){

            if(keys.length > 0){
                var opts = {
                    Bucket: internal.config.bucket,
                    Delete: { Objects: keys }
                };

                internal.s3.deleteObjects(opts,  function (err) {
                    next(err);
                });
            }
            else {
                next();
            }
        }

        function done(err){
            if(err){
                deferred.reject(err);
            }
            else {
                deferred.resolve({message: 'Success'});
            }
        }

        async.waterfall([getAllKeys, deleteKeys], done);

        return deferred.promise;
    };

    engine.save = function(params){
        var deferred = q.defer();

        internal.putObject(params.nodeid, params.filename, params.path)
            .then(function(){
                deferred.resolve({message: 'Success'});
            })
            .fail(function (err) {
                deferred.reject(err);
            });

        return deferred.promise;
    };

    engine.list = function(params){
        var deferred = q.defer();

        internal.listObjects(params.nodeid, null)
            .fail(function(err){
                deferred.reject(err);
            })
            .then(function(data){
                var results = [];

                async.each(data[0],
                    function(item, next){
                        if(item.Size > 0){
                            results[results.length] = {
                                url: internal.constructUrl(item.Key),
                                size: item.Size,
                                lastmodified: item.LastModified
                            };
                        }
                        next();
                    },function(){
                        deferred.resolve(
                            sort(results, 'url')
                        );
                    }
                );
            });

        return deferred.promise;
    };

    engine.find = function(params){
        var deferred = q.defer();

        internal.getObject(params.nodeid, params.filename)
            .then(function(file){
                var results = {};

                if(file.ContentLength > 0){
                    results = {
                        url: internal.constructUrl(internal.buildKey(params.nodeid, params.filename)),
                        size: file.ContentLength,
                        lastmodified: file.LastModified
                    };
                }

                deferred.resolve(results);
            },
            function(err){
                deferred.reject(err);
            });

        return deferred.promise;
    };

    return engine;
})();
<|endoftext|>


<commit_before>'use babel';

import path from 'path';
import fs from 'fs';
import url from 'url';
import { BufferedNodeProcess, CompositeDisposable, Disposable } from 'atom';
import { remote } from 'electron';
import JSON5 from 'json5';
import stripAnsi from 'strip-ansi';

const packagePath = atom.packages.resolvePackagePath('atom-live-server');
const liveServer = path.join(packagePath, '/node_modules/live-server/live-server.js');

let serverProcess;
let disposeMenu;
let noBrowser;
let console = global.console;

function addStartMenu() {
  disposeMenu = atom.menu.add(
    [{
      label: 'Packages',
      submenu : [{
        label: 'atom-live-server',
        submenu : [{
          label: 'Start server',
          command: `atom-live-server:startServer`
        }]
      }]
    }]
  );
}

function usingDefaultConsole() {
  return console == global.console;
}

function safeStatus(status) {
  if(!usingDefaultConsole()) console.setStatus(status);
}

export default {
  subscriptions: null,

  activate(state) {
    this.subscriptions = new CompositeDisposable();

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'atom-live-server:start-3000': () => this.startServer(3000),
      'atom-live-server:start-4000': () => this.startServer(4000),
      'atom-live-server:start-5000': () => this.startServer(5000),
      'atom-live-server:start-8000': () => this.startServer(8000),
      'atom-live-server:start-9000': () => this.startServer(9000),
      'atom-live-server:startServer': () => this.startServer(),
      'atom-live-server:stopServer': () => this.stopServer()
    }));

    addStartMenu();
  },

  deactivate() {
    this.stopServer();
    console.dispose();
    this.subscriptions.dispose();
  },

  consumeConsole(createConsole) {
    let mod = this;
    console = createConsole({
      id: 'atom-live-server',
      name: 'Live Server',
      start() { mod.startServer(); },
      stop() { mod.stopServer(); }
    });
    return new Disposable(() => { console = null; });
  },

  startServer(port = 3000) {
    if (serverProcess) {
      return;
    }

    safeStatus('starting');

    const targetPath = atom.project.getPaths()[0];

    if (!targetPath) {
      atom.notifications.addWarning('[Live Server] You haven\'t opened a Project, you must open one.')
      return;
    }

    noBrowser = false;
    const args = [];
    const stdout = output => {
      if (stripAnsi(output).indexOf('Serving ') === 0) {
        const strippedOutput = stripAnsi(output);
        const serverUrl = strippedOutput.split(' at ')[1];
        const port = url.parse(serverUrl).port;
        const disposeStartMenu = disposeMenu;
        disposeMenu = atom.menu.add(
          [{
            label: 'Packages',
            submenu : [{
              label: 'atom-live-server',
              submenu : [{
                label: strippedOutput.replace('Serving ', 'Stop ').replace(/\r?\n|\r/g, ''),
                command: `atom-live-server:stopServer`
              }]
            }]
          }]
        );

        disposeStartMenu.dispose();
        safeStatus('running');

        if (noBrowser) {
          atom.notifications.addSuccess(`[Live Server] Live server started at ${serverUrl}.`);
        }
      }

      if (usingDefaultConsole()) {
        console.log(`[Live Server] ${strippedOutput}`);
      } else {
        console.append({text: `[Live Server] ${output}`, level: 'log', format: 'ansi'});
      }

    };

    const exit = code => {
      console.info(`[Live Server] Exited with code ${code}`);
      this.stopServer();
    }

    fs.open(path.join(targetPath, '.atom-live-server.json'), 'r', (err, fd) => {
      if (!err) {
        const userConfig = JSON5.parse(fs.readFileSync(fd, 'utf8'));

        Object.keys(userConfig).forEach(key => {
          if (key === 'no-browser') {
            if (userConfig[key] === true) {
              args.push(`--${key}`);
              noBrowser = true;
            }
          }
          else if (key === 'root') {
              args.unshift(`${userConfig[key]}`)
            }
          else {
              args.push(`--${key}=${userConfig[key]}`);
          }
        });
      }

      if (!args.length) {
        args.push(`--port=${port}`);
      }

      serverProcess = new BufferedNodeProcess({
        command: liveServer,
        args,
        stdout,
        exit,
        options: {
          cwd: targetPath
        }
      });

      console.info(`[Live Server] live-server ${args.join(' ')}`);
    });
  },

  stopServer() {
    try {
      serverProcess.kill();
    } catch (e) {
      console.error(e);
    }

    serverProcess = null;
    const disposeStopMenu = disposeMenu;
    addStartMenu();
    disposeStopMenu && disposeStopMenu.dispose();
    atom.notifications.addSuccess('[Live Server] Live server is stopped.');
    console.info('[Live Server] Live server is stopped.')
    safeStatus('stopped');
  }
};
<commit_msg>fix strippedOutput not defined<commit_after>'use babel';

import path from 'path';
import fs from 'fs';
import url from 'url';
import { BufferedNodeProcess, CompositeDisposable, Disposable } from 'atom';
import { remote } from 'electron';
import JSON5 from 'json5';
import stripAnsi from 'strip-ansi';

const packagePath = atom.packages.resolvePackagePath('atom-live-server');
const liveServer = path.join(packagePath, '/node_modules/live-server/live-server.js');

let serverProcess;
let disposeMenu;
let noBrowser;
let console = global.console;

function addStartMenu() {
  disposeMenu = atom.menu.add(
    [{
      label: 'Packages',
      submenu : [{
        label: 'atom-live-server',
        submenu : [{
          label: 'Start server',
          command: `atom-live-server:startServer`
        }]
      }]
    }]
  );
}

function usingDefaultConsole() {
  return console == global.console;
}

function safeStatus(status) {
  if(!usingDefaultConsole()) console.setStatus(status);
}

export default {
  subscriptions: null,

  activate(state) {
    this.subscriptions = new CompositeDisposable();

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'atom-live-server:start-3000': () => this.startServer(3000),
      'atom-live-server:start-4000': () => this.startServer(4000),
      'atom-live-server:start-5000': () => this.startServer(5000),
      'atom-live-server:start-8000': () => this.startServer(8000),
      'atom-live-server:start-9000': () => this.startServer(9000),
      'atom-live-server:startServer': () => this.startServer(),
      'atom-live-server:stopServer': () => this.stopServer()
    }));

    addStartMenu();
  },

  deactivate() {
    this.stopServer();
    console.dispose();
    this.subscriptions.dispose();
  },

  consumeConsole(createConsole) {
    let mod = this;
    console = createConsole({
      id: 'atom-live-server',
      name: 'Live Server',
      start() { mod.startServer(); },
      stop() { mod.stopServer(); }
    });
    return new Disposable(() => { console = null; });
  },

  startServer(port = 3000) {
    if (serverProcess) {
      return;
    }

    safeStatus('starting');

    const targetPath = atom.project.getPaths()[0];

    if (!targetPath) {
      atom.notifications.addWarning('[Live Server] You haven\'t opened a Project, you must open one.')
      return;
    }

    noBrowser = false;
    const args = [];
    const stdout = output => {
      const strippedOutput = stripAnsi(output);

      if (strippedOutput.indexOf('Serving ') === 0) {
        const serverUrl = strippedOutput.split(' at ')[1];
        const port = url.parse(serverUrl).port;
        const disposeStartMenu = disposeMenu;
        disposeMenu = atom.menu.add(
          [{
            label: 'Packages',
            submenu : [{
              label: 'atom-live-server',
              submenu : [{
                label: strippedOutput.replace('Serving ', 'Stop ').replace(/\r?\n|\r/g, ''),
                command: `atom-live-server:stopServer`
              }]
            }]
          }]
        );

        disposeStartMenu.dispose();
        safeStatus('running');

        if (noBrowser) {
          atom.notifications.addSuccess(`[Live Server] Live server started at ${serverUrl}.`);
        }
      }

      if (usingDefaultConsole()) {
        console.log(`[Live Server] ${strippedOutput}`);
      } else {
        console.append({text: `[Live Server] ${output}`, level: 'log', format: 'ansi'});
      }

    };

    const exit = code => {
      console.info(`[Live Server] Exited with code ${code}`);
      this.stopServer();
    }

    fs.open(path.join(targetPath, '.atom-live-server.json'), 'r', (err, fd) => {
      if (!err) {
        const userConfig = JSON5.parse(fs.readFileSync(fd, 'utf8'));

        Object.keys(userConfig).forEach(key => {
          if (key === 'no-browser') {
            if (userConfig[key] === true) {
              args.push(`--${key}`);
              noBrowser = true;
            }
          }
          else if (key === 'root') {
              args.unshift(`${userConfig[key]}`)
            }
          else {
              args.push(`--${key}=${userConfig[key]}`);
          }
        });
      }

      if (!args.length) {
        args.push(`--port=${port}`);
      }

      serverProcess = new BufferedNodeProcess({
        command: liveServer,
        args,
        stdout,
        exit,
        options: {
          cwd: targetPath
        }
      });

      console.info(`[Live Server] live-server ${args.join(' ')}`);
    });
  },

  stopServer() {
    try {
      serverProcess.kill();
    } catch (e) {
      console.error(e);
    }

    serverProcess = null;
    const disposeStopMenu = disposeMenu;
    addStartMenu();
    disposeStopMenu && disposeStopMenu.dispose();
    atom.notifications.addSuccess('[Live Server] Live server is stopped.');
    console.info('[Live Server] Live server is stopped.')
    safeStatus('stopped');
  }
};
<|endoftext|>