<commit_before>/**
* @fileOverview Produces line chart
* @todo fix zoom when reached min or max zoom
* @todo add minimum number and maximum number of display points..used in zoom
*/

class DataVisualizer
{
    /**
     * @class DataVisualizer
     * @classdesc DataVisualizer is a wrapper class for line-chart in chart.js.
     *
     * @param {string}    id -                                  ID of canvas that chart should be rendered on.
     * @param {Objects[]} visualizerConfig -                    The configuration for y-axes data.
     * @param {string}    visualizerConfig[].buttonId -         The ID of toggle button corresponding to y-axes data.
     * @param {Integer[]} visualizerConfig[].data -             Array with data to be displayed. Refresh chart must be called when data arrays are updated.When array is updated to display, call refresh chart.
     * @param {integer}   visualizerConfig[].datasetIndex -     Index attribute set on buttonId.
     * @param {integer}   visualizerConfig[].color -            Color of data points.
     * @param {string}    visualizerConfig[].name -             Name of data to be used as label.
     * @param {string}    visualizerConfig[].units -            Units used for data (ie meters).
     * @param {string}    visualizerConfig[].fill -             Determines whether this data should be represented as area or line chart.
     * @param {integer}   defaultNumDisplayPoints -             Number of data points to display on the graph by default.
     */
    constructor(id, visualizerConfig, defaultNumDisplayPoints)
    {
        /**
         * Number of total packets added to chart. Only recalculated during chart refresh.
         *
         * @private
         * @name    DataVisualizer#numPackets
         * @type    Integer
         * @default 0
         */
        this.numPackets = 0;

        /**
         * Number of data points to display on line chart.
         *
         * @private
         * @name    DataVisualizer#numDisplayPoints
         * @type    Integer
         */
        this.numDisplayPoints = defaultNumDisplayPoints;

        /**
         * Default number of points to display on zoom reset.
         *
         * @private
         * @name    DataVisualizer#defaultNumDisplayPoints
         * @type    Integer
         */
        this.defaultNumDisplayPoints = defaultNumDisplayPoints;

        /**
         * If data is zoomed or panned, we will stop drawing new incoming datapoints.
         *
         * @private
         * @name    DataVisualizer#zoomed
         * @type    Bool
         * @default false
         */
         this.zoomed = false;

        /**
         * If data is zoomed or panned, we will stop drawing new incoming datapoints.
         *
         * @private
         * @name    DataVisualizer#panned
         * @type    Bool
         * @default false
         */
         this.panned = false;

        /**
         * The higher the number the slower the pan speed. Note it only changes
         * the speed of a flick scroll.
         *
         * @private
         * @name    DataVisualizer#panSpeed
         * @type    Integer
         * @default 10
         */
         this.panSpeed = 10;

        /**
         * The higher the number the faster zoom buttons and wheel zoom will occur.
         *
         * @private
         * @name    DataVisualizer#zoomSpeed
         * @type    Integer
         * @default 2
         */
         this.zoomSpeed = 2;

        /**
         * Index of first datapoint to be drawn.
         *
         * @private
         * @name    DataVisualizer#startIndex
         * @type    Integer
         */
         this.startIndex = 0;

        /**
         * Index of last datapoint to be drawn.
         *
         * @private
         * @name    DataVisualizer#startIndex
         * @type    Integer
         */
         this.endIndex = 0;

        /**
         * Chart object to be used by chartjs for chart manipulation>
         *
         * @private
         * @name    DataVisualizer#chart
         * @type    Object
         */
        this.chart;

        /**
         * Data will hold all of the data that has been pushed to the graph,
         * whereas the charts datasets will only hold data to be displayed.
         *
         * @private
         * @name DataVisualizer#data
         * @type Array
         */
         this.data = [];

        /**
         * Resets zoom to default number of data points  and pans to the end
         * of the graph.
         *
         * @method  resetZoom
         * @name    DataVisualizer#resetZoom
         */
        this.resetZoom = function()
        {
            this.zoomed = false;
            this.panned = false;
            this.numDisplayPoints = this.defaultNumDisplayPoints;
            this.startIndex = this.numPackets - this.numDisplayPoints;

            this.refreshChart();

        }.bind(this)

        /**
         * Touch and scroll event handler used to pan the graph.
         *
         * @method  pan
         * @name    DataVisualizer#pan
         *
         * @param {event} e -               Scroll or touch event. If null then it was from an
         *.                                 on click action. Use panDirection value below if null.
         * @param {string} panDirection -   "left" if pan left, "right" if pan right
         */
        this.pan = function(e, panDirection)
        {
            // used for calculating how far we should pan
            var deltaX = 0;

            // "static" variable used to hold previous touch position
            this.pan.startX;

            this.panned = true;

            if (e == null)
            {
                if (panDirection == "right")
                {
                    deltaX += (this.numDisplayPoints / 2) * this.panSpeed;
                }
                else
                {
                    deltaX -= (this.numDisplayPoints / 2) * this.panSpeed;
                }
            }
            // in case of start of touch we shouldn't move at all, just need to grab touch position
            else if (e.type == "touchstart")
            {
                this.pan.startX = e.touches[0].clientX;
            }

            // calculate how far to pan based on how far fingers have scrolled since last touchmove
            else if (e.type == "touchmove")
            {
                // only allow 2 finger pan
                if (e.changedTouches.length > 0)
                {
                    deltaX = this.pan.startX - e.changedTouches[0].clientX;
                    this.pan.startX = e.changedTouches[0].clientX;
                }
            }

            // for wheel and scroll events
            else
            {
                // to fix issue where no scroll happens at all due to rounding of decimal values < |1|
                if (e.deltaX < 0)
                {
                    deltaX = e.deltaX - this.panSpeed;
                }
                else
                {
                    deltaX = e.deltaX + this.panSpeed;
                }
            }

            this.startIndex += (deltaX / this.panSpeed);
            if (this.startIndex < 0) {
                this.startIndex = 0;
            }
            if ((this.startIndex + this.numDisplayPoints) > this.numPackets) {
                this.startIndex = this.numPackets - this.numDisplayPoints;
            }

            // rounding both indexes as they will be used to index into arrays and need to be integers
            this.startIndex = Math.round(this.startIndex);
            this.endIndex = Math.round(this.startIndex + this.numDisplayPoints);

            // redrawing chart
            this.refreshChart();

            // preventing a page scroll
            if (e != null) {
                e.preventDefault();
            }

        }.bind(this);

        /**
         * Zooms in on graph. Can be attached to the onClick method of a zoom in
         * button to perform a zoom on the graph for each click.
         *
         * @method  zoomIn
         * @name    DataVisualizer#zoomIn
         */
        this.zoomIn = function()
        {
            this.zoomed = true;
            /** @todo add zoom speed */
            this.numDisplayPoints -= this.zoomSpeed;

            /** @todo add min number/max number display points */
            this.numDisplayPoints = (this.numDisplayPoints < 5) ? 5 : this.numDisplayPoints;

            this.startIndex += this.zoomSpeed / 2;
            this.endIndex = this.startIndex + this.numDisplayPoints - this.zoomSpeed;

            this.refreshChart();

        }.bind(this)

        /**
         * Zooms out of graph. Can be attached to the onClick method of a zoom out
         * button to perform a zoom on the graph for each click.
         *
         * @method  zoomOut
         * @name    DataVisualizer#zoomOut
         */
        this.zoomOut = function()
        {
            this.zoomed = true;
            /** @todo add zoom speed */
            this.numDisplayPoints += this.zoomSpeed;

            /** @todo add min number/max number display points */
            this.numDisplayPoints = (this.numDisplayPoints > 100) ? 100 : this.numDisplayPoints;

            this.startIndex -= this.zoomSpeed / 2;
            this.endIndex = this.startIndex + this.numDisplayPoints - this.zoomSpeed;

            this.refreshChart();

        }.bind(this)

        /**
         * Event handler for mousewheel event that will allow zoom on mousewheel.
         *
         * @private
         * @method  zoom
         * @name    DataVisualizer#zoom
         *
         * @param {Object} e -        Mousewheel event.
         * @param {string} e.deltaY - Amount mousewheel has moved in the vertical direction.
        */
        this.zoom = function(e) {
          console.log(e.deltaY);
          if (e.deltaY < 0) {
            this.zoomIn();
          }
          else {
            this.zoomOut();
          }

          e.preventDefault();
        }.bind(this)

        // set scroll and touch event listeners on canvas to add pan and zoom capabilities
        document.getElementById(id).addEventListener('wheel', this.zoom);
        document.getElementById(id).addEventListener('scroll', this.pan);
        document.getElementById(id).addEventListener('touchstart', this.pan);
        document.getElementById(id).addEventListener('touchmove', this.pan);

        /**
         * Displays or hides the data corresponding to the selected button. Requires that initToggleButtons has been called.
         *
         * @method  toggleData
         * @name    DataVisualizer#toggleData
         *
         * @param {Object} button - Button element corresponding to data to be toggled.
         */
        this.toggleData = function(button)
        {
            var dataSetIndex = button.getAttribute('data-data-set-index');
            var dataSet = this.chart.config.data.datasets[dataSetIndex];
            var yAxis = this.chart.config.options.scales.yAxes[dataSetIndex];

            button.classList.remove("altitude-color");

            // toggling data and axis visibility
            dataSet.hidden = !dataSet.hidden;
            yAxis.display = !yAxis.display;

            this.chart.update();

        }.bind(this)

        /**
         * Adds the specified data to each dataset. There should be 1 value for
         * each dataset in the graph.
         *
         * @method  addDataPoint
         * @name    DataVisualizer#addDataPoint
         *
         * @param {Objects[]} data - Array with 1 value for each dataset.
         *                           If a visible dataset, the value should be an integer.
         */
        this.addDataPoint = function(data)
        {
            var i;
            var datasets = this.chart.config.data.datasets;

            for (i = 0; i < datasets.length; i++)
            {
                // pushing incoming data into overall data array
                this.data[i].push(data[i]);
            }

            this.refreshChart();

        }.bind(this)

        /**
         * Adds the specified data to each dataset. There should be 1 value for
         * each dataset in the graph.
         *
         * @method  addDataPoint
         * @name    DataVisualizer#addDataPoint
         *
         * @param {Objects[]} data - Array with 1 value for each dataset.
         *                           If a visible dataset, the value should be an integer.
         */
        this.refreshChart = function()
        {
            var i, j;
            var datasets    = this.chart.config.data.datasets;

            this.numPackets = (this.zoomed == true) ? this.numPackets : this.data[0].length;

            if (!this.zoomed && !this.panned) {
                this.startIndex  = (this.numPackets > this.numDisplayPoints) ? (this.numPackets - this.numDisplayPoints) : 0;
                this.endIndex    = (this.numPackets > this.numDisplayPoints) ? (this.startIndex + this.numDisplayPoints) : this.numPackets;
            }

            // pushing data from overall array to display data array
            for (i = 0; i < datasets.length; i++)
            {
                datasets[i].data.length = 0;

                for (j = this.startIndex; j < this.endIndex; j++) {
                    datasets[i].data.push(this.data[i][j]);
                }
            }

            packetIndex.length = 0;
            for (i = this.startIndex; i < this.endIndex; i++)
            {
                packetIndex.push(i);
            }

            this.chart.update();

        }.bind(this)

        /**
         * Initializes the graph using the parameters passed in through the visualizerConfig objects.
         * Also initializes the data array.
         *
         * @method  initGraph
         * @name    DataVisualizer#initGraph
         *
         * @private
         * @param {Objects[]} visualizerConfig                - The configuration for y-axes data.
         * @param {string}    visualizerConfig[].buttonId     - The ID of toggle button corresponding to y-axes data.
         * @param {integer}   visualizerConfig[].datasetIndex - Index attribute set on buttonId.
         * @param {integer}   visualizerConfig[].color        - Color of data points.
         * @param {string}    visualizerConfig[].name         - Name of data to be used as label.
         * @param {string}    visualizerConfig[].units        - Units used for data (ie meters).
         * @param {string}    visualizerConfig[].fill         - Determines whether this data should be represented as area or line chart.
         */
        this.initGraph = function(visualizerConfig)
        {
            for (var i = 0; i < visualizerConfig.length; i++)
            {
                this.data.push(visualizerConfig[i].data);

                // Configuring the data set options
                var dataConfig = {
                    label: visualizerConfig[i].name,
                    borderColor: visualizerConfig[i].color,
                    data: [],
                    backgroundColor: Samples.utils.transparentize(visualizerConfig[i].color, 0.9),
                    fill: visualizerConfig[i].fill,
                    yAxisID: visualizerConfig[i].buttonId
                };

                // Configuring the axes options
                var axesConfig = {
                    id: visualizerConfig[i].buttonId,
                    display: true,
                    position: (i % 2) ? "left" : "right",
                    scaleLabel: {
                        display: false,
                        labelString: visualizerConfig[i].units
                    },
                    ticks: {
                        callback:
                        (function(units) {
                            return function(label, index, labels) {
                                if (index == 0) {
                                    return units;
                                }
                                return Math.round(label);
                            }
                        })(visualizerConfig[i].units)
                    }
                };

                // push configuration to config array
                dataSetsConfig.push(dataConfig);
                yAxesConfig.push(axesConfig);
            }

            // setting up config variable for chart
            config.options.scales.yaxes = yAxesConfig;
            config.data.datasets = dataSetsConfig;

        }.bind(this)

        /**
         * Initializes toggle buttons to reference correct dataset.
         *
         * @method  initToggleButtons
         * @name    DataVisualizer#initToggleButtons
         *
         * @private
         * @param {Objects[]} visualizerConfig                - The configuration for y-axes data.
         * @param {string}    visualizerConfig[].buttonId     - The ID of toggle button corresponding to y-axes data.
         * @param {integer}   visualizerConfig[].datasetIndex - Index attribute set on buttonId.
         */
        function initToggleButtons(visualizerConfig)
        {
            var button;

            for (var i = 0; i < visualizerConfig.length; i++)
            {
                button = document.getElementById(visualizerConfig[i].buttonId);
                button.setAttribute('data-data-set-index', visualizerConfig[i].datasetIndex);
            }
        }

        // initialize graph configuration
        this.initGraph(visualizerConfig);

        // initializing toggle buttons
        initToggleButtons(visualizerConfig);

        // creating and configuring chart
        var ctx = document.getElementById(id).getContext("2d");
        this.chart = new Chart(ctx, config);
        Chart.defaults.global.defaultFontColor = "#ebebeb";
        Chart.defaults.global.defaultFontFamily = "'Lato','Helvetica Neue','Helvetica','Arial',sans-serif";
    }
}

<commit_msg>Added min/max num display points member variables<commit_after>/**
* @fileOverview Produces line chart
* @todo fix zoom when reached min or max zoom
* @todo add minimum number and maximum number of display points..used in zoom
*/

class DataVisualizer
{
    /**
     * @class DataVisualizer
     * @classdesc DataVisualizer is a wrapper class for line-chart in chart.js.
     *
     * @param {string}    id -                                  ID of canvas that chart should be rendered on.
     * @param {Objects[]} visualizerConfig -                    The configuration for y-axes data.
     * @param {string}    visualizerConfig[].buttonId -         The ID of toggle button corresponding to y-axes data.
     * @param {Integer[]} visualizerConfig[].data -             Array with data to be displayed. Refresh chart must be called when data arrays are updated.When array is updated to display, call refresh chart.
     * @param {integer}   visualizerConfig[].datasetIndex -     Index attribute set on buttonId.
     * @param {integer}   visualizerConfig[].color -            Color of data points.
     * @param {string}    visualizerConfig[].name -             Name of data to be used as label.
     * @param {string}    visualizerConfig[].units -            Units used for data (ie meters).
     * @param {string}    visualizerConfig[].fill -             Determines whether this data should be represented as area or line chart.
     * @param {integer}   defaultNumDisplayPoints -             Number of data points to display on the graph by default.
     */
    constructor(id, visualizerConfig, defaultNumDisplayPoints)
    {
        /**
         * Number of total packets added to chart. Only recalculated during chart refresh.
         *
         * @private
         * @name    DataVisualizer#numPackets
         * @type    Integer
         * @default 0
         */
        this.numPackets = 0;

        /**
         * Number of data points to display on line chart.
         *
         * @private
         * @name    DataVisualizer#numDisplayPoints
         * @type    Integer
         */
        this.numDisplayPoints = defaultNumDisplayPoints;

        /**
         * Default number of points to display on zoom reset.
         *
         * @private
         * @name    DataVisualizer#defaultNumDisplayPoints
         * @type    Integer
         */
        this.defaultNumDisplayPoints = defaultNumDisplayPoints;

        /**
         * Minimum number of points to display on graph.
         *
         * @private
         * @name    DataVisualizer#minNumDisplayPoints
         * @type    Integer
         */
        this.minNumDisplayPoints = 5;

        /**
         * Maximum number of points to display on graph.
         *
         * @private
         * @name    DataVisualizer#maxNumDisplayPoints
         * @type    Integer
         */
        this.maxNumDisplayPoints = 100;

        /**
         * If data is zoomed or panned, we will stop drawing new incoming datapoints.
         *
         * @private
         * @name    DataVisualizer#zoomed
         * @type    Bool
         * @default false
         */
         this.zoomed = false;

        /**
         * If data is zoomed or panned, we will stop drawing new incoming datapoints.
         *
         * @private
         * @name    DataVisualizer#panned
         * @type    Bool
         * @default false
         */
         this.panned = false;

        /**
         * The higher the number the slower the pan speed. Note it only changes
         * the speed of a flick scroll.
         *
         * @private
         * @name    DataVisualizer#panSpeed
         * @type    Integer
         * @default 10
         */
         this.panSpeed = 10;

        /**
         * The higher the number the faster zoom buttons and wheel zoom will occur.
         *
         * @private
         * @name    DataVisualizer#zoomSpeed
         * @type    Integer
         * @default 2
         */
         this.zoomSpeed = 2;

        /**
         * Index of first datapoint to be drawn.
         *
         * @private
         * @name    DataVisualizer#startIndex
         * @type    Integer
         */
         this.startIndex = 0;

        /**
         * Index of last datapoint to be drawn.
         *
         * @private
         * @name    DataVisualizer#startIndex
         * @type    Integer
         */
         this.endIndex = 0;

        /**
         * Chart object to be used by chartjs for chart manipulation>
         *
         * @private
         * @name    DataVisualizer#chart
         * @type    Object
         */
        this.chart;

        /**
         * Data will hold all of the data that has been pushed to the graph,
         * whereas the charts datasets will only hold data to be displayed.
         *
         * @private
         * @name DataVisualizer#data
         * @type Array
         */
         this.data = [];

        /**
         * Resets zoom to default number of data points  and pans to the end
         * of the graph.
         *
         * @method  resetZoom
         * @name    DataVisualizer#resetZoom
         */
        this.resetZoom = function()
        {
            this.zoomed = false;
            this.panned = false;
            this.numDisplayPoints = this.defaultNumDisplayPoints;
            this.startIndex = this.numPackets - this.numDisplayPoints;

            this.refreshChart();

        }.bind(this)

        /**
         * Touch and scroll event handler used to pan the graph.
         *
         * @method  pan
         * @name    DataVisualizer#pan
         *
         * @param {event} e -               Scroll or touch event. If null then it was from an
         *.                                 on click action. Use panDirection value below if null.
         * @param {string} panDirection -   "left" if pan left, "right" if pan right
         */
        this.pan = function(e, panDirection)
        {
            // used for calculating how far we should pan
            var deltaX = 0;

            // "static" variable used to hold previous touch position
            this.pan.startX;

            this.panned = true;

            if (e == null)
            {
                if (panDirection == "right")
                {
                    deltaX += (this.numDisplayPoints / 2) * this.panSpeed;
                }
                else
                {
                    deltaX -= (this.numDisplayPoints / 2) * this.panSpeed;
                }
            }
            // in case of start of touch we shouldn't move at all, just need to grab touch position
            else if (e.type == "touchstart")
            {
                this.pan.startX = e.touches[0].clientX;
            }

            // calculate how far to pan based on how far fingers have scrolled since last touchmove
            else if (e.type == "touchmove")
            {
                // only allow 2 finger pan
                if (e.changedTouches.length > 0)
                {
                    deltaX = this.pan.startX - e.changedTouches[0].clientX;
                    this.pan.startX = e.changedTouches[0].clientX;
                }
            }

            // for wheel and scroll events
            else
            {
                // to fix issue where no scroll happens at all due to rounding of decimal values < |1|
                if (e.deltaX < 0)
                {
                    deltaX = e.deltaX - this.panSpeed;
                }
                else
                {
                    deltaX = e.deltaX + this.panSpeed;
                }
            }

            this.startIndex += (deltaX / this.panSpeed);
            if (this.startIndex < 0) {
                this.startIndex = 0;
            }
            if ((this.startIndex + this.numDisplayPoints) > this.numPackets) {
                this.startIndex = this.numPackets - this.numDisplayPoints;
            }

            // rounding both indexes as they will be used to index into arrays and need to be integers
            this.startIndex = Math.round(this.startIndex);
            this.endIndex = Math.round(this.startIndex + this.numDisplayPoints);

            // redrawing chart
            this.refreshChart();

            // preventing a page scroll
            if (e != null) {
                e.preventDefault();
            }

        }.bind(this);

        /**
         * Zooms in on graph. Can be attached to the onClick method of a zoom in
         * button to perform a zoom on the graph for each click.
         *
         * @method  zoomIn
         * @name    DataVisualizer#zoomIn
         */
        this.zoomIn = function()
        {
            this.zoomed = true;
            this.numDisplayPoints -= this.zoomSpeed;

            this.numDisplayPoints = (this.numDisplayPoints < this.minNumDisplayPoints) ? this.minNumDisplayPoints : this.numDisplayPoints;

            this.startIndex += this.zoomSpeed / 2;
            this.endIndex = this.startIndex + this.numDisplayPoints - this.zoomSpeed;

            this.refreshChart();

        }.bind(this)

        /**
         * Zooms out of graph. Can be attached to the onClick method of a zoom out
         * button to perform a zoom on the graph for each click.
         *
         * @method  zoomOut
         * @name    DataVisualizer#zoomOut
         */
        this.zoomOut = function()
        {
            this.zoomed = true;

            // zooming out by adding more data points to the graph. Only allowing
            // a certain number of data points or else the graph gets too messy.
            this.numDisplayPoints += this.zoomSpeed;
            this.numDisplayPoints = (this.numDisplayPoints > this.maxNumDisplayPoints) ? this.maxNumDisplayPoints : this.numDisplayPoints;

            // calculating the start and end indexes of data to be drawn. if we
            // would draw off the end of the graph, then only zoom out left instead.
            this.startIndex -= this.zoomSpeed / 2;
            if ((this.startIndex + this.numDisplayPoints) < this.numPackets)
            {
              this.endIndex = this.startIndex + this.numDisplayPoints - this.zoomSpeed;
            }

            if (this.startIndex < 0) {
              this.startIndex = 0;
            }

            this.refreshChart();

        }.bind(this)

        /**
         * Event handler for mousewheel event that will allow zoom on mousewheel.
         *
         * @private
         * @method  zoom
         * @name    DataVisualizer#zoom
         *
         * @param {Object} e -        Mousewheel event.
         * @param {string} e.deltaY - Amount mousewheel has moved in the vertical direction.
        */
        this.zoom = function(e) {
          if (e.deltaY < 0) {
            this.zoomIn();
          }
          else {
            this.zoomOut();
          }

          e.preventDefault();
        }.bind(this)

        // set scroll and touch event listeners on canvas to add pan and zoom capabilities
        document.getElementById(id).addEventListener('wheel', this.zoom);
        document.getElementById(id).addEventListener('scroll', this.pan);
        document.getElementById(id).addEventListener('touchstart', this.pan);
        document.getElementById(id).addEventListener('touchmove', this.pan);

        /**
         * Displays or hides the data corresponding to the selected button. Requires that initToggleButtons has been called.
         *
         * @method  toggleData
         * @name    DataVisualizer#toggleData
         *
         * @param {Object} button - Button element corresponding to data to be toggled.
         */
        this.toggleData = function(button)
        {
            var dataSetIndex = button.getAttribute('data-data-set-index');
            var dataSet = this.chart.config.data.datasets[dataSetIndex];
            var yAxis = this.chart.config.options.scales.yAxes[dataSetIndex];

            button.classList.remove("altitude-color");

            // toggling data and axis visibility
            dataSet.hidden = !dataSet.hidden;
            yAxis.display = !yAxis.display;

            this.chart.update();

        }.bind(this)

        /**
         * Adds the specified data to each dataset. There should be 1 value for
         * each dataset in the graph.
         *
         * @method  addDataPoint
         * @name    DataVisualizer#addDataPoint
         *
         * @param {Objects[]} data - Array with 1 value for each dataset.
         *                           If a visible dataset, the value should be an integer.
         */
        this.addDataPoint = function(data)
        {
            var i;
            var datasets = this.chart.config.data.datasets;

            for (i = 0; i < datasets.length; i++)
            {
                // pushing incoming data into overall data array
                this.data[i].push(data[i]);
            }

            this.refreshChart();

        }.bind(this)

        /**
         * Adds the specified data to each dataset. There should be 1 value for
         * each dataset in the graph.
         *
         * @method  addDataPoint
         * @name    DataVisualizer#addDataPoint
         *
         * @param {Objects[]} data - Array with 1 value for each dataset.
         *                           If a visible dataset, the value should be an integer.
         */
        this.refreshChart = function()
        {
            var i, j;
            var datasets    = this.chart.config.data.datasets;

            this.numPackets = (this.zoomed == true) ? this.numPackets : this.data[0].length;

            if (!this.zoomed && !this.panned) {
                this.startIndex  = (this.numPackets > this.numDisplayPoints) ? (this.numPackets - this.numDisplayPoints) : 0;
                this.endIndex    = (this.numPackets > this.numDisplayPoints) ? (this.startIndex + this.numDisplayPoints) : this.numPackets;
            }

            // pushing data from overall array to display data array
            for (i = 0; i < datasets.length; i++)
            {
                datasets[i].data.length = 0;

                for (j = this.startIndex; j < this.endIndex; j++) {
                    datasets[i].data.push(this.data[i][j]);
                }
            }

            packetIndex.length = 0;
            for (i = this.startIndex; i < this.endIndex; i++)
            {
                packetIndex.push(i);
            }

            this.chart.update();

        }.bind(this)

        /**
         * Initializes the graph using the parameters passed in through the visualizerConfig objects.
         * Also initializes the data array.
         *
         * @method  initGraph
         * @name    DataVisualizer#initGraph
         *
         * @private
         * @param {Objects[]} visualizerConfig                - The configuration for y-axes data.
         * @param {string}    visualizerConfig[].buttonId     - The ID of toggle button corresponding to y-axes data.
         * @param {integer}   visualizerConfig[].datasetIndex - Index attribute set on buttonId.
         * @param {integer}   visualizerConfig[].color        - Color of data points.
         * @param {string}    visualizerConfig[].name         - Name of data to be used as label.
         * @param {string}    visualizerConfig[].units        - Units used for data (ie meters).
         * @param {string}    visualizerConfig[].fill         - Determines whether this data should be represented as area or line chart.
         */
        this.initGraph = function(visualizerConfig)
        {
            for (var i = 0; i < visualizerConfig.length; i++)
            {
                this.data.push(visualizerConfig[i].data);

                // Configuring the data set options
                var dataConfig = {
                    label: visualizerConfig[i].name,
                    borderColor: visualizerConfig[i].color,
                    data: [],
                    backgroundColor: Samples.utils.transparentize(visualizerConfig[i].color, 0.9),
                    fill: visualizerConfig[i].fill,
                    yAxisID: visualizerConfig[i].buttonId
                };

                // Configuring the axes options
                var axesConfig = {
                    id: visualizerConfig[i].buttonId,
                    display: true,
                    position: (i % 2) ? "left" : "right",
                    scaleLabel: {
                        display: false,
                        labelString: visualizerConfig[i].units
                    },
                    ticks: {
                        callback:
                        (function(units) {
                            return function(label, index, labels) {
                                if (index == 0) {
                                    return units;
                                }
                                return Math.round(label);
                            }
                        })(visualizerConfig[i].units)
                    }
                };

                // push configuration to config array
                dataSetsConfig.push(dataConfig);
                yAxesConfig.push(axesConfig);
            }

            // setting up config variable for chart
            config.options.scales.yaxes = yAxesConfig;
            config.data.datasets = dataSetsConfig;

        }.bind(this)

        /**
         * Initializes toggle buttons to reference correct dataset.
         *
         * @method  initToggleButtons
         * @name    DataVisualizer#initToggleButtons
         *
         * @private
         * @param {Objects[]} visualizerConfig                - The configuration for y-axes data.
         * @param {string}    visualizerConfig[].buttonId     - The ID of toggle button corresponding to y-axes data.
         * @param {integer}   visualizerConfig[].datasetIndex - Index attribute set on buttonId.
         */
        function initToggleButtons(visualizerConfig)
        {
            var button;

            for (var i = 0; i < visualizerConfig.length; i++)
            {
                button = document.getElementById(visualizerConfig[i].buttonId);
                button.setAttribute('data-data-set-index', visualizerConfig[i].datasetIndex);
            }
        }

        // initialize graph configuration
        this.initGraph(visualizerConfig);

        // initializing toggle buttons
        initToggleButtons(visualizerConfig);

        // creating and configuring chart
        var ctx = document.getElementById(id).getContext("2d");
        this.chart = new Chart(ctx, config);
        Chart.defaults.global.defaultFontColor = "#ebebeb";
        Chart.defaults.global.defaultFontFamily = "'Lato','Helvetica Neue','Helvetica','Arial',sans-serif";
    }
}

<|endoftext|>


<commit_before>class Controller {
  constructor(facade) {
    this.facade = facade;
  }

  create(req, res, next) {
    this.facade.create(req.body)
      .then(doc => res.status(201).json(doc))
      .catch(err => next(err));
  }

  find(req, res, next) {
    return this.facade.find(req.query)
      .then(collection => res.status(200).json(collection))
      .catch(err => next(err));
  }

  findOne(req, res, next) {
    return this.facade.findOne(req.query)
      .then(doc => res.status(200).json(doc))
      .catch(err => next(err));
  }

  findById(req, res, next) {
    return this.facade.findById(req.params.id)
      .then((doc) => {
        if (!doc) { return res.sendStatus(404); }
        return res.status(200).json(doc);
      })
      .catch(err => next(err));
  }

  update(req, res, next) {
    this.facade.update({ _id: req.params.id }, req.body, { new: true })
      .then((results) => {
        if (results.n < 1) { return res.sendStatus(404); }
        if (results.nModified < 1) { return res.sendStatus(304); }
        res.sendStatus(204);
      })
      .catch(err => next(err));
  }

  remove(req, res, next) {
    this.facade.remove({ _id: req.params.id })
      .then((doc) => {
        if (!doc) { return res.sendStatus(404); }
        return res.sendStatus(204);
      })
      .catch(err => next(err));
  }
}

module.exports = Controller;
<commit_msg>Remove new attribute in update query<commit_after>class Controller {
  constructor(facade) {
    this.facade = facade;
  }

  create(req, res, next) {
    this.facade.create(req.body)
      .then(doc => res.status(201).json(doc))
      .catch(err => next(err));
  }

  find(req, res, next) {
    return this.facade.find(req.query)
      .then(collection => res.status(200).json(collection))
      .catch(err => next(err));
  }

  findOne(req, res, next) {
    return this.facade.findOne(req.query)
      .then(doc => res.status(200).json(doc))
      .catch(err => next(err));
  }

  findById(req, res, next) {
    return this.facade.findById(req.params.id)
      .then((doc) => {
        if (!doc) { return res.sendStatus(404); }
        return res.status(200).json(doc);
      })
      .catch(err => next(err));
  }

  update(req, res, next) {
    this.facade.update({ _id: req.params.id }, req.body)
      .then((results) => {
        if (results.n < 1) { return res.sendStatus(404); }
        if (results.nModified < 1) { return res.sendStatus(304); }
        res.sendStatus(204);
      })
      .catch(err => next(err));
  }

  remove(req, res, next) {
    this.facade.remove({ _id: req.params.id })
      .then((doc) => {
        if (!doc) { return res.sendStatus(404); }
        return res.sendStatus(204);
      })
      .catch(err => next(err));
  }
}

module.exports = Controller;
<|endoftext|>


<commit_before>({
    baseUrl: 'lib',
    include: ['sd'],
    optimize: 'none',
    name: 'vendor/almond',
    wrap: {
        startFile: 'lib/build/start.frag.js',
        endFile: 'lib/build/end.frag.js'
    },
    out: 'build/sd.nakid.js',
})
<commit_msg>re-enable minification<commit_after>({
    baseUrl: 'lib',
    include: ['sd'],
//    optimize: 'none',
    name: 'vendor/almond',
    wrap: {
        startFile: 'lib/build/start.frag.js',
        endFile: 'lib/build/end.frag.js'
    },
    out: 'build/sd.nakid.js',
})
<|endoftext|>


<commit_before>import utils from 'osg/utils';
import { vec3 } from 'osg/glMatrix';
import { mat4 } from 'osg/glMatrix';
import Manipulator from 'osgGA/Manipulator';
import OrbitManipulatorDeviceOrientationController from 'osgGA/OrbitManipulatorDeviceOrientationController';
import OrbitManipulatorGamePadController from 'osgGA/OrbitManipulatorGamePadController';
import OrbitManipulatorHammerController from 'osgGA/OrbitManipulatorHammerController';
import OrbitManipulatorStandardMouseKeyboardController from 'osgGA/OrbitManipulatorStandardMouseKeyboardController';
import OrbitManipulatorWebVRController from 'osgGA/OrbitManipulatorWebVRController';
import DelayInterpolator from 'osgUtil/DelayInterpolator';
import Groups from 'osgViewer/input/InputConstants';

/**
 *  OrbitManipulator
 *  @class
 */
var OrbitManipulator = function(options) {
    Manipulator.call(this, options);
    this._homePosition = vec3.create();
    this._frustum = {};
    this.init();
};

OrbitManipulator.AvailableControllerList = [
    'StandardMouseKeyboard',
    'GamePad',
    'Hammer',
    'DeviceOrientation',
    'WebVR'
];

OrbitManipulator.ControllerList = [
    'StandardMouseKeyboard',
    'GamePad',
    'Hammer',
    'DeviceOrientation',
    'WebVR'
];

var TWO_PI = 2 * Math.PI;
var lowerOrEqual = function(val, limit) {
    return val < limit + 0.00001;
};

/** @lends OrbitManipulator.prototype */
utils.createPrototypeObject(
    OrbitManipulator,
    utils.objectInherit(Manipulator.prototype, {
        init: function() {
            this._distance = 25.0;
            this._target = vec3.create();
            this._upz = vec3.fromValues(0.0, 0.0, 1.0);
            vec3.init(this._target);

            var rot1 = mat4.fromRotation(mat4.create(), -Math.PI, this._upz);
            var rot2 = mat4.fromRotation(
                mat4.create(),
                Math.PI / 10.0,
                vec3.fromValues(1.0, 0.0, 0.0)
            );
            this._rotation = mat4.create();
            mat4.mul(this._rotation, rot1, rot2);
            this._time = 0.0;

            this._vrMatrix = mat4.create();

            this._rotate = new DelayInterpolator(2);
            this._pan = new DelayInterpolator(2);
            this._zoom = new DelayInterpolator(1);

            this._minSpeed = 1e-4; // set a limit to pan/zoom speed
            this._scaleMouseMotion = 1.0;

            this._inverseMatrix = mat4.create();

            // distance at which we start pushing the target (so that we can still zoom)
            // with a very low _limitZoomIn, it's like a fps manipulator as long as you don't unzoom
            this._autoPushTarget = true;

            // pitch range [-PI/2, PI/2]
            this._limitPitchUp = Math.PI * 0.5 * 0.9;
            this._limitPitchDown = -this._limitPitchUp;

            // yaw range [-PI, PI]
            this._limitYawLeft = -Math.PI;
            this._limitYawRight = -this._limitYawLeft;

            this._limitZoomIn = 1e-4;
            this._limitZoomOut = Infinity;

            this._constrainYaw = false;
            this._constrainPitch = false;
            this._constrainYaw = false;
            this._constrainZoom = false;

            // instance of controller
            var self = this;

            OrbitManipulator.ControllerList.forEach(function(value) {
                if (OrbitManipulator[value] !== undefined) {
                    if (self._controllerList[value]) {
                        self._controllerList[value].init();
                    } else {
                        self._controllerList[value] = new OrbitManipulator[value](self);
                    }
                }
            });
        },
        setLimitPitchUp: function(up) {
            this._limitPitchUp = up;
        },
        setLimitPitchDown: function(down) {
            this._limitPitchDown = down;
        },
        setLimitYawLeft: function(left) {
            this._limitYawLeft = left;
            this._constrainYaw = true;
        },
        setLimitYawRight: function(right) {
            this._limitYawRight = right;
            this._constrainYaw = true;
        },
        setLimitZoomOut: function(zoomOut) {
            this._limitZoomOut = zoomOut;
            this._constrainZoom = true;
        },
        setLimitZoomIn: function(zoomIn) {
            this._limitZoomIn = zoomIn;
            this._constrainZoom = true;
        },

        setConstrainPitch: function(limit) {
            this._constrainPitch = limit;
            this._previousPitch = undefined;
        },

        isConstrainPitch: function() {
            return this._constrainPitch;
        },

        setConstrainYaw: function(constrain) {
            this._constrainYaw = constrain;
            this._previousYaw = undefined;
        },

        isConstrainYaw: function() {
            return this._constrainYaw;
        },

        setConstrainZoom: function(limit) {
            this._constrainZoom = limit;
        },

        isConstrainZoom: function() {
            return this._constrainZoom;
        },

        setDelay: function(dt) {
            this._rotate.setDelay(dt);
            this._pan.setDelay(dt);
            this._zoom.setDelay(dt);
        },
        reset: function() {
            this.init();
        },
        setTarget: function(target) {
            vec3.copy(this._target, target);
            var eyePos = vec3.create();
            this.getEyePosition(eyePos);
            this._distance = vec3.distance(target, eyePos);
        },
        setEyePosition: (function() {
            var f = vec3.create();
            var s = vec3.create();
            var u = vec3.create();
            return function(eye) {
                var result = this._rotation;
                var center = this._target;

                vec3.sub(f, eye, center);
                vec3.normalize(f, f);

                vec3.cross(s, f, this._upz);
                vec3.normalize(s, s);

                vec3.cross(u, s, f);
                vec3.normalize(u, u);

                // s[0], f[0], u[0], 0.0,
                // s[1], f[1], u[1], 0.0,
                // s[2], f[2], u[2], 0.0,
                // 0,    0,    0,     1.0
                result[0] = s[0];
                result[1] = f[0];
                result[2] = u[0];
                result[3] = 0.0;
                result[4] = s[1];
                result[5] = f[1];
                result[6] = u[1];
                result[7] = 0.0;
                result[8] = s[2];
                result[9] = f[2];
                result[10] = u[2];
                result[11] = 0.0;
                result[12] = 0;
                result[13] = 0;
                result[14] = 0;
                result[15] = 1.0;

                this._distance = vec3.distance(center, eye);
            };
        })(),

        setEnable: function(enabled) {
            this.getInputManager().setEnable(Groups.ORBIT_MANIPULATOR, enabled);
        },

        computeHomePosition: function(boundStrategy) {
            var bs = this.getHomeBoundingSphere(boundStrategy);
            if (!bs || !bs.valid()) return;

            this.setDistance(this.getHomeDistance(bs));
            this.setTarget(bs.center());
        },

        getHomePosition: function() {
            if (this._node !== undefined) {
                var target = this._target;
                var distance = this.getDistance();

                this.computeEyePosition(target, distance, this._homePosition);
            }
            return this._homePosition;
        },

        setMinSpeed: function(s) {
            this._minSpeed = s;
        },
        getMinSpeed: function() {
            return this._minSpeed;
        },

        setDistance: function(d) {
            this._distance = d;
        },
        getDistance: function() {
            return this._distance;
        },

        getSpeedFactor: function() {
            return Math.max(this._distance, this._minSpeed);
        },
        computePan: (function() {
            var inv = mat4.create();
            var x = vec3.create();
            var y = vec3.create();
            return function(dx, dy) {
                var proj = this._camera.getProjectionMatrix();
                // modulate panning speed with verticalFov value
                // if it's an orthographic we don't change the panning speed
                // TODO : manipulators in osgjs don't support well true orthographic camera anyway because they
                // manage the view matrix (and you need to edit the projection matrix to 'zoom' for true ortho camera)
                var vFov = proj[15] === 1 ? 1.0 : 2.0 / proj[5];
                var speed = this.getSpeedFactor() * vFov;
                dy *= speed;
                dx *= speed;

                mat4.invert(inv, this._rotation);
                x[0] = inv[0];
                x[1] = inv[1];
                x[2] = inv[2];
                vec3.normalize(x, x);

                y[0] = inv[8];
                y[1] = inv[9];
                y[2] = inv[10];
                vec3.normalize(y, y);

                vec3.scale(x, x, -dx);
                vec3.scale(y, y, dy);
                vec3.add(this._target, this._target, x);
                vec3.add(this._target, this._target, y);
            };
        })(),
        computeRotation: (function() {
            var rightDir = vec3.fromValues(1.0, 0.0, 0.0);

            return function(dx, dy) {
                var prevPitch = Math.atan(-this._rotation[6] / this._rotation[5]);
                if (isNaN(prevPitch)) {
                    prevPitch = 0.0;
                }
                var pitch = this._computePitch(prevPitch, dy);

                var deltaYaw = dx / 10.0;
                var previousYaw = Math.atan2(this._rotation[4], this._rotation[0]);
                var yaw = this._computeYaw(previousYaw, deltaYaw);
                mat4.fromRotation(this._rotation, -pitch, rightDir);
                mat4.rotate(this._rotation, this._rotation, -yaw, this._upz);
            };
        })(),

        _computePitch: function(prevPitch, dy) {
            var pitch = prevPitch + dy / 10.0;
            return Math.min(Math.max(pitch, this._limitPitchDown), this._limitPitchUp);
        },

        _computeYaw: function(previousYaw, deltaYaw) {
            var yaw = previousYaw + deltaYaw;
            var left = this._limitYawLeft;
            var right = this._limitYawRight;

            if (this._constrainYaw) {
                if (right < left) {
                    if (yaw > Math.PI) {
                        previousYaw -= TWO_PI;
                        yaw -= TWO_PI;
                    }
                    if (yaw < -Math.PI) {
                        previousYaw += TWO_PI;
                        yaw += TWO_PI;
                    }
                }

                if (deltaYaw === 0) {
                    var isOutsideLimit = false;
                    if (left > right) isOutsideLimit = yaw < left && yaw > right;
                    else isOutsideLimit = yaw < left || yaw > right;
                    if (isOutsideLimit)
                        yaw = Math.abs(yaw - left) > Math.abs(yaw - right) ? right : left;
                }

                if (deltaYaw > 0.0 && lowerOrEqual(previousYaw, right) && yaw > right) {
                    yaw = right;
                } else if (deltaYaw < 0.0 && lowerOrEqual(left, previousYaw) && yaw < left) {
                    yaw = left;
                }
            }
            return yaw;
        },

        computeZoom: function(dz) {
            this.zoom(dz);
        },

        setAutoPushTarget: function(bool) {
            this._autoPushTarget = bool;
        },

        zoom: (function() {
            var dir = vec3.create();
            return function(ratio) {
                var newValue = this._distance + this.getSpeedFactor() * (ratio - 1.0);

                if (this._autoPushTarget && newValue < this._limitZoomIn) {
                    // push the target instead of zooming on it
                    vec3.sub(dir, this._target, this.getEyePosition(dir));
                    vec3.normalize(dir, dir);
                    vec3.scale(dir, dir, this._limitZoomIn - newValue);
                    vec3.add(this._target, this._target, dir);
                }

                if (this._constrainZoom) {
                    this._distance = Math.max(
                        this._limitZoomIn,
                        Math.min(this._limitZoomOut, newValue)
                    );
                }
            };
        })(),

        getRotateInterpolator: function() {
            return this._rotate;
        },
        getPanInterpolator: function() {
            return this._pan;
        },
        getZoomInterpolator: function() {
            return this._zoom;
        },
        getTarget: function(target) {
            return vec3.copy(target, this._target);
        },
        getEyePosition: function(eye) {
            this.computeEyePosition(this._target, this._distance, eye);
            return eye;
        },

        computeEyePosition: (function() {
            var tmpDist = vec3.create();
            var tmpInverse = mat4.create();
            return function(target, distance, eye) {
                mat4.invert(tmpInverse, this._rotation);
                tmpDist[1] = distance;
                vec3.transformMat4(eye, tmpDist, tmpInverse);
                vec3.add(eye, target, eye);
            };
        })(),

        update: (function() {
            var eye = vec3.create();
            return function(nv) {
                var dt = nv.getFrameStamp().getDeltaTime();

                var delta;
                var mouseFactor = 0.1;
                delta = this._rotate.update(dt);
                this.computeRotation(
                    -delta[0] * mouseFactor * this._scaleMouseMotion,
                    -delta[1] * mouseFactor * this._scaleMouseMotion
                );

                var panFactor = 0.002;
                delta = this._pan.update(dt);
                this.computePan(-delta[0] * panFactor, -delta[1] * panFactor);

                delta = this._zoom.update(dt);
                this.computeZoom(1.0 + delta[0] / 10.0);

                var target = this._target;
                var distance = this._distance;

                /* 1. Works but bypass other manipulators */
                // mat4.copy( this._inverseMatrix , this._vrMatrix );

                /* 2. Works but gets broken by other manipulators */
                mat4.invert(this._inverseMatrix, this._rotation);
                mat4.mul(this._inverseMatrix, this._vrMatrix, this._inverseMatrix);

                /* 3. Doesnt' work */
                // mat4.mul( this._vrMatrix,  this._vrMatrix, this._rotation );
                // mat4.invert( this._inverseMatrix, this._vrMatrix );

                vec3.set(eye, 0.0, distance, 0.0);
                vec3.transformMat4(eye, eye, this._inverseMatrix);

                mat4.lookAt(this._inverseMatrix, vec3.add(eye, target, eye), target, this._upz);
            };
        })(),

        setPoseVR: function(q /*, pos*/) {
            mat4.fromQuat(this._vrMatrix, q);
            // this._vrMatrix[ 12 ] = pos[ 0 ];
            // this._vrMatrix[ 13 ] = pos[ 1 ];
            // this._vrMatrix[ 14 ] = pos[ 2 ];
        }
    }),
    'osgGA',
    'OrbitManipulator'
);

OrbitManipulator.DeviceOrientation = OrbitManipulatorDeviceOrientationController;
OrbitManipulator.GamePad = OrbitManipulatorGamePadController;
OrbitManipulator.Hammer = OrbitManipulatorHammerController;
OrbitManipulator.WebVR = OrbitManipulatorWebVRController;
OrbitManipulator.StandardMouseKeyboard = OrbitManipulatorStandardMouseKeyboardController;

export default OrbitManipulator;
<commit_msg>Fixes zoom for orbit manipulator<commit_after>import utils from 'osg/utils';
import { vec3 } from 'osg/glMatrix';
import { mat4 } from 'osg/glMatrix';
import Manipulator from 'osgGA/Manipulator';
import OrbitManipulatorDeviceOrientationController from 'osgGA/OrbitManipulatorDeviceOrientationController';
import OrbitManipulatorGamePadController from 'osgGA/OrbitManipulatorGamePadController';
import OrbitManipulatorHammerController from 'osgGA/OrbitManipulatorHammerController';
import OrbitManipulatorStandardMouseKeyboardController from 'osgGA/OrbitManipulatorStandardMouseKeyboardController';
import OrbitManipulatorWebVRController from 'osgGA/OrbitManipulatorWebVRController';
import DelayInterpolator from 'osgUtil/DelayInterpolator';
import Groups from 'osgViewer/input/InputConstants';

/**
 *  OrbitManipulator
 *  @class
 */
var OrbitManipulator = function(options) {
    Manipulator.call(this, options);
    this._homePosition = vec3.create();
    this._frustum = {};
    this.init();
};

OrbitManipulator.AvailableControllerList = [
    'StandardMouseKeyboard',
    'GamePad',
    'Hammer',
    'DeviceOrientation',
    'WebVR'
];

OrbitManipulator.ControllerList = [
    'StandardMouseKeyboard',
    'GamePad',
    'Hammer',
    'DeviceOrientation',
    'WebVR'
];

var TWO_PI = 2 * Math.PI;
var lowerOrEqual = function(val, limit) {
    return val < limit + 0.00001;
};

/** @lends OrbitManipulator.prototype */
utils.createPrototypeObject(
    OrbitManipulator,
    utils.objectInherit(Manipulator.prototype, {
        init: function() {
            this._distance = 25.0;
            this._target = vec3.create();
            this._upz = vec3.fromValues(0.0, 0.0, 1.0);
            vec3.init(this._target);

            var rot1 = mat4.fromRotation(mat4.create(), -Math.PI, this._upz);
            var rot2 = mat4.fromRotation(
                mat4.create(),
                Math.PI / 10.0,
                vec3.fromValues(1.0, 0.0, 0.0)
            );
            this._rotation = mat4.create();
            mat4.mul(this._rotation, rot1, rot2);
            this._time = 0.0;

            this._vrMatrix = mat4.create();

            this._rotate = new DelayInterpolator(2);
            this._pan = new DelayInterpolator(2);
            this._zoom = new DelayInterpolator(1);

            this._minSpeed = 1e-4; // set a limit to pan/zoom speed
            this._scaleMouseMotion = 1.0;

            this._inverseMatrix = mat4.create();

            // distance at which we start pushing the target (so that we can still zoom)
            // with a very low _limitZoomIn, it's like a fps manipulator as long as you don't unzoom
            this._autoPushTarget = true;

            // pitch range [-PI/2, PI/2]
            this._limitPitchUp = Math.PI * 0.5 * 0.9;
            this._limitPitchDown = -this._limitPitchUp;

            // yaw range [-PI, PI]
            this._limitYawLeft = -Math.PI;
            this._limitYawRight = -this._limitYawLeft;

            this._limitZoomIn = 1e-4;
            this._limitZoomOut = Infinity;

            this._constrainYaw = false;
            this._constrainPitch = false;
            this._constrainYaw = false;
            this._constrainZoom = false;

            // instance of controller
            var self = this;

            OrbitManipulator.ControllerList.forEach(function(value) {
                if (OrbitManipulator[value] !== undefined) {
                    if (self._controllerList[value]) {
                        self._controllerList[value].init();
                    } else {
                        self._controllerList[value] = new OrbitManipulator[value](self);
                    }
                }
            });
        },
        setLimitPitchUp: function(up) {
            this._limitPitchUp = up;
        },
        setLimitPitchDown: function(down) {
            this._limitPitchDown = down;
        },
        setLimitYawLeft: function(left) {
            this._limitYawLeft = left;
            this._constrainYaw = true;
        },
        setLimitYawRight: function(right) {
            this._limitYawRight = right;
            this._constrainYaw = true;
        },
        setLimitZoomOut: function(zoomOut) {
            this._limitZoomOut = zoomOut;
            this._constrainZoom = true;
        },
        setLimitZoomIn: function(zoomIn) {
            this._limitZoomIn = zoomIn;
            this._constrainZoom = true;
        },

        setConstrainPitch: function(limit) {
            this._constrainPitch = limit;
            this._previousPitch = undefined;
        },

        isConstrainPitch: function() {
            return this._constrainPitch;
        },

        setConstrainYaw: function(constrain) {
            this._constrainYaw = constrain;
            this._previousYaw = undefined;
        },

        isConstrainYaw: function() {
            return this._constrainYaw;
        },

        setConstrainZoom: function(limit) {
            this._constrainZoom = limit;
        },

        isConstrainZoom: function() {
            return this._constrainZoom;
        },

        setDelay: function(dt) {
            this._rotate.setDelay(dt);
            this._pan.setDelay(dt);
            this._zoom.setDelay(dt);
        },
        reset: function() {
            this.init();
        },
        setTarget: function(target) {
            vec3.copy(this._target, target);
            var eyePos = vec3.create();
            this.getEyePosition(eyePos);
            this._distance = vec3.distance(target, eyePos);
        },
        setEyePosition: (function() {
            var f = vec3.create();
            var s = vec3.create();
            var u = vec3.create();
            return function(eye) {
                var result = this._rotation;
                var center = this._target;

                vec3.sub(f, eye, center);
                vec3.normalize(f, f);

                vec3.cross(s, f, this._upz);
                vec3.normalize(s, s);

                vec3.cross(u, s, f);
                vec3.normalize(u, u);

                // s[0], f[0], u[0], 0.0,
                // s[1], f[1], u[1], 0.0,
                // s[2], f[2], u[2], 0.0,
                // 0,    0,    0,     1.0
                result[0] = s[0];
                result[1] = f[0];
                result[2] = u[0];
                result[3] = 0.0;
                result[4] = s[1];
                result[5] = f[1];
                result[6] = u[1];
                result[7] = 0.0;
                result[8] = s[2];
                result[9] = f[2];
                result[10] = u[2];
                result[11] = 0.0;
                result[12] = 0;
                result[13] = 0;
                result[14] = 0;
                result[15] = 1.0;

                this._distance = vec3.distance(center, eye);
            };
        })(),

        setEnable: function(enabled) {
            this.getInputManager().setEnable(Groups.ORBIT_MANIPULATOR, enabled);
        },

        computeHomePosition: function(boundStrategy) {
            var bs = this.getHomeBoundingSphere(boundStrategy);
            if (!bs || !bs.valid()) return;

            this.setDistance(this.getHomeDistance(bs));
            this.setTarget(bs.center());
        },

        getHomePosition: function() {
            if (this._node !== undefined) {
                var target = this._target;
                var distance = this.getDistance();

                this.computeEyePosition(target, distance, this._homePosition);
            }
            return this._homePosition;
        },

        setMinSpeed: function(s) {
            this._minSpeed = s;
        },
        getMinSpeed: function() {
            return this._minSpeed;
        },

        setDistance: function(d) {
            this._distance = d;
        },
        getDistance: function() {
            return this._distance;
        },

        getSpeedFactor: function() {
            return Math.max(this._distance, this._minSpeed);
        },
        computePan: (function() {
            var inv = mat4.create();
            var x = vec3.create();
            var y = vec3.create();
            return function(dx, dy) {
                var proj = this._camera.getProjectionMatrix();
                // modulate panning speed with verticalFov value
                // if it's an orthographic we don't change the panning speed
                // TODO : manipulators in osgjs don't support well true orthographic camera anyway because they
                // manage the view matrix (and you need to edit the projection matrix to 'zoom' for true ortho camera)
                var vFov = proj[15] === 1 ? 1.0 : 2.0 / proj[5];
                var speed = this.getSpeedFactor() * vFov;
                dy *= speed;
                dx *= speed;

                mat4.invert(inv, this._rotation);
                x[0] = inv[0];
                x[1] = inv[1];
                x[2] = inv[2];
                vec3.normalize(x, x);

                y[0] = inv[8];
                y[1] = inv[9];
                y[2] = inv[10];
                vec3.normalize(y, y);

                vec3.scale(x, x, -dx);
                vec3.scale(y, y, dy);
                vec3.add(this._target, this._target, x);
                vec3.add(this._target, this._target, y);
            };
        })(),
        computeRotation: (function() {
            var rightDir = vec3.fromValues(1.0, 0.0, 0.0);

            return function(dx, dy) {
                var prevPitch = Math.atan(-this._rotation[6] / this._rotation[5]);
                if (isNaN(prevPitch)) {
                    prevPitch = 0.0;
                }
                var pitch = this._computePitch(prevPitch, dy);

                var deltaYaw = dx / 10.0;
                var previousYaw = Math.atan2(this._rotation[4], this._rotation[0]);
                var yaw = this._computeYaw(previousYaw, deltaYaw);
                mat4.fromRotation(this._rotation, -pitch, rightDir);
                mat4.rotate(this._rotation, this._rotation, -yaw, this._upz);
            };
        })(),

        _computePitch: function(prevPitch, dy) {
            var pitch = prevPitch + dy / 10.0;
            return Math.min(Math.max(pitch, this._limitPitchDown), this._limitPitchUp);
        },

        _computeYaw: function(previousYaw, deltaYaw) {
            var yaw = previousYaw + deltaYaw;
            var left = this._limitYawLeft;
            var right = this._limitYawRight;

            if (this._constrainYaw) {
                if (right < left) {
                    if (yaw > Math.PI) {
                        previousYaw -= TWO_PI;
                        yaw -= TWO_PI;
                    }
                    if (yaw < -Math.PI) {
                        previousYaw += TWO_PI;
                        yaw += TWO_PI;
                    }
                }

                if (deltaYaw === 0) {
                    var isOutsideLimit = false;
                    if (left > right) isOutsideLimit = yaw < left && yaw > right;
                    else isOutsideLimit = yaw < left || yaw > right;
                    if (isOutsideLimit)
                        yaw = Math.abs(yaw - left) > Math.abs(yaw - right) ? right : left;
                }

                if (deltaYaw > 0.0 && lowerOrEqual(previousYaw, right) && yaw > right) {
                    yaw = right;
                } else if (deltaYaw < 0.0 && lowerOrEqual(left, previousYaw) && yaw < left) {
                    yaw = left;
                }
            }
            return yaw;
        },

        computeZoom: function(dz) {
            this.zoom(dz);
        },

        setAutoPushTarget: function(bool) {
            this._autoPushTarget = bool;
        },

        zoom: (function() {
            var dir = vec3.create();
            return function(ratio) {
                var newValue = this._distance + this.getSpeedFactor() * (ratio - 1.0);

                if (this._autoPushTarget && newValue < this._limitZoomIn) {
                    // push the target instead of zooming on it
                    vec3.sub(dir, this._target, this.getEyePosition(dir));
                    vec3.normalize(dir, dir);
                    vec3.scale(dir, dir, this._limitZoomIn - newValue);
                    vec3.add(this._target, this._target, dir);
                }
                this._distance = newValue;
                if (this._constrainZoom) {
                    this._distance = Math.max(
                        this._limitZoomIn,
                        Math.min(this._limitZoomOut, newValue)
                    );
                }
            };
        })(),

        getRotateInterpolator: function() {
            return this._rotate;
        },
        getPanInterpolator: function() {
            return this._pan;
        },
        getZoomInterpolator: function() {
            return this._zoom;
        },
        getTarget: function(target) {
            return vec3.copy(target, this._target);
        },
        getEyePosition: function(eye) {
            this.computeEyePosition(this._target, this._distance, eye);
            return eye;
        },

        computeEyePosition: (function() {
            var tmpDist = vec3.create();
            var tmpInverse = mat4.create();
            return function(target, distance, eye) {
                mat4.invert(tmpInverse, this._rotation);
                tmpDist[1] = distance;
                vec3.transformMat4(eye, tmpDist, tmpInverse);
                vec3.add(eye, target, eye);
            };
        })(),

        update: (function() {
            var eye = vec3.create();
            return function(nv) {
                var dt = nv.getFrameStamp().getDeltaTime();

                var delta;
                var mouseFactor = 0.1;
                delta = this._rotate.update(dt);
                this.computeRotation(
                    -delta[0] * mouseFactor * this._scaleMouseMotion,
                    -delta[1] * mouseFactor * this._scaleMouseMotion
                );

                var panFactor = 0.002;
                delta = this._pan.update(dt);
                this.computePan(-delta[0] * panFactor, -delta[1] * panFactor);

                delta = this._zoom.update(dt);
                this.computeZoom(1.0 + delta[0] / 10.0);

                var target = this._target;
                var distance = this._distance;

                /* 1. Works but bypass other manipulators */
                // mat4.copy( this._inverseMatrix , this._vrMatrix );

                /* 2. Works but gets broken by other manipulators */
                mat4.invert(this._inverseMatrix, this._rotation);
                mat4.mul(this._inverseMatrix, this._vrMatrix, this._inverseMatrix);

                /* 3. Doesnt' work */
                // mat4.mul( this._vrMatrix,  this._vrMatrix, this._rotation );
                // mat4.invert( this._inverseMatrix, this._vrMatrix );

                vec3.set(eye, 0.0, distance, 0.0);
                vec3.transformMat4(eye, eye, this._inverseMatrix);

                mat4.lookAt(this._inverseMatrix, vec3.add(eye, target, eye), target, this._upz);
            };
        })(),

        setPoseVR: function(q /*, pos*/) {
            mat4.fromQuat(this._vrMatrix, q);
            // this._vrMatrix[ 12 ] = pos[ 0 ];
            // this._vrMatrix[ 13 ] = pos[ 1 ];
            // this._vrMatrix[ 14 ] = pos[ 2 ];
        }
    }),
    'osgGA',
    'OrbitManipulator'
);

OrbitManipulator.DeviceOrientation = OrbitManipulatorDeviceOrientationController;
OrbitManipulator.GamePad = OrbitManipulatorGamePadController;
OrbitManipulator.Hammer = OrbitManipulatorHammerController;
OrbitManipulator.WebVR = OrbitManipulatorWebVRController;
OrbitManipulator.StandardMouseKeyboard = OrbitManipulatorStandardMouseKeyboardController;

export default OrbitManipulator;
<|endoftext|>


<commit_before>export default [
  {
    id: 't4br',
    style: 'position: absolute; top: 82%; left: 12%;',
  },
  {
    id: 't4tr',
    style: 'position: absolute; top: 79%; left: 8%;',
  },
  {
    id: 't3br',
    style: 'position: absolute; top: 89%; left: 21.6%;',
  },
  {
    id: 't2br',
    style: 'position: absolute; top: 88%; left: 45%;',
  },
  {
    id: 't1br',
    style: 'position: absolute; top: 88%; left: 80%;',
  },
  {
    id: 't3mr',
    style: 'position: absolute; top: 75%; left: 16.1%;',
  },
  {
    id: 't2mr',
    style: 'position: absolute; top: 67%; left: 23%;',
  },
  {
    id: 't1mr',
    style: 'position: absolute; top: 56%; left: 38%;',
  },
  {
    id: 't3tr',
    style: 'position: absolute; top: 70%; left: 2.8%;',
  },
  {
    id: 't2tr',
    style: 'position: absolute; top: 52%; left: 5%;',
  },
  {
    id: 't1tr',
    style: 'position: absolute; top: 35%; left: 5%;',
  },
  {
    id: 'brbr',
    style: 'position: absolute; top: 90.3%; left: 19%;',
  },
  {
    id: 'bmbr',
    style: 'position: absolute; top: 86.3%; left: 19%;',
  },
  {
    id: 'brmr',
    style: 'position: absolute; top: 74.5%; left: 12.5%;',
  },
  {
    id: 'bmmr',
    style: 'position: absolute; top: 77%; left: 16%;',
  },
  {
    id: 'brtr',
    style: 'position: absolute; top: 72.5%; left: 1.3%;',
  },
  {
    id: 'bmtr',
    style: 'position: absolute; top: 72.5%; left: 5%;',
  },
  {
    id: 't4bd',
    style: 'position: absolute; top: 16%; left: 84%;',
  },
  {
    id: 't4td',
    style: 'position: absolute; top: 13%; left: 81%;',
  },
  {
    id: 't3bd',
    style: 'position: absolute; top: 27.6%; left: 91.6%;',
  },
  {
    id: 't2bd',
    style: 'position: absolute; top: 45%; left: 92%;',
  },
  {
    id: 't1bd',
    style: 'position: absolute; top: 60%; left: 92%;',
  },
  {
    id: 't3md',
    style: 'position: absolute; top: 22%; left: 75%;',
  },
  {
    id: 't2md',
    style: 'position: absolute; top: 34%; left: 63%;',
  },
  {
    id: 't1md',
    style: 'position: absolute; top: 45%; left: 53%;',
  },
  {
    id: 't3td',
    style: 'position: absolute; top: 6%; left: 70%;',
  },
  {
    id: 't2td',
    style: 'position: absolute; top: 5%; left: 47%;',
  },
  {
    id: 't1td',
    style: 'position: absolute; top: 5%; left: 13%;',
  },
  {
    id: 'brbd',
    style: 'position: absolute; top: 24%; left: 90.3%;',
  },
  {
    id: 'bmbd',
    style: 'position: absolute; top: 24%; left: 93.9%;',
  },
  {
    id: 'brmd',
    style: 'position: absolute; top: 18%; left: 76%;',
  },
  {
    id: 'bmmd',
    style: 'position: absolute; top: 21%; left: 79%;',
  },
  {
    id: 'brtd',
    style: 'position: absolute; top: 7.5%; left: 74%;',
  },
  {
    id: 'bmtd',
    style: 'position: absolute; top: 4%; left: 74%;',
  },
  {
    id: 'ar',
    style: 'position: absolute; top: 83%; left: 5%;',
  },
  {
    id: 'ad',
    style: 'position: absolute; top: 9%; left: 84%;',
  }];
<commit_msg>Update buildingData.js<commit_after>export default [
  {
    id: 't4br',
    style: 'position: absolute; top: 82%; left: 12%;',
  },
  {
    id: 't4tr',
    style: 'position: absolute; top: 79%; left: 8%;',
  },
  {
    id: 't3br',
    style: 'position: absolute; top: 89%; left: 21.6%;',
  },
  {
    id: 't2br',
    style: 'position: absolute; top: 88%; left: 45%;',
  },
  {
    id: 't1br',
    style: 'position: absolute; top: 88%; left: 80%;',
  },
  {
    id: 't3mr',
    style: 'position: absolute; top: 75%; left: 16.1%;',
  },
  {
    id: 't2mr',
    style: 'position: absolute; top: 67%; left: 23%;',
  },
  {
    id: 't1mr',
    style: 'position: absolute; top: 56%; left: 38%;',
  },
  {
    id: 't3tr',
    style: 'position: absolute; top: 70%; left: 2.8%;',
  },
  {
    id: 't2tr',
    style: 'position: absolute; top: 52%; left: 5%;',
  },
  {
    id: 't1tr',
    style: 'position: absolute; top: 35%; left: 5%;',
  },
  {
    id: 'brbr',
    style: 'position: absolute; top: 86.3%; left: 19%;',
  },
  {
    id: 'bmbr',
    style: 'position: absolute; top: 90.3%; left: 19%;',
  },
  {
    id: 'brmr',
    style: 'position: absolute; top: 74.5%; left: 12.5%;',
  },
  {
    id: 'bmmr',
    style: 'position: absolute; top: 77%; left: 16%;',
  },
  {
    id: 'brtr',
    style: 'position: absolute; top: 72.5%; left: 1.3%;',
  },
  {
    id: 'bmtr',
    style: 'position: absolute; top: 72.5%; left: 5%;',
  },
  {
    id: 't4bd',
    style: 'position: absolute; top: 16%; left: 84%;',
  },
  {
    id: 't4td',
    style: 'position: absolute; top: 13%; left: 81%;',
  },
  {
    id: 't3bd',
    style: 'position: absolute; top: 27.6%; left: 91.6%;',
  },
  {
    id: 't2bd',
    style: 'position: absolute; top: 45%; left: 92%;',
  },
  {
    id: 't1bd',
    style: 'position: absolute; top: 60%; left: 92%;',
  },
  {
    id: 't3md',
    style: 'position: absolute; top: 22%; left: 75%;',
  },
  {
    id: 't2md',
    style: 'position: absolute; top: 34%; left: 63%;',
  },
  {
    id: 't1md',
    style: 'position: absolute; top: 45%; left: 53%;',
  },
  {
    id: 't3td',
    style: 'position: absolute; top: 6%; left: 70%;',
  },
  {
    id: 't2td',
    style: 'position: absolute; top: 5%; left: 47%;',
  },
  {
    id: 't1td',
    style: 'position: absolute; top: 5%; left: 13%;',
  },
  {
    id: 'brbd',
    style: 'position: absolute; top: 24%; left: 90.3%;',
  },
  {
    id: 'bmbd',
    style: 'position: absolute; top: 24%; left: 93.9%;',
  },
  {
    id: 'brmd',
    style: 'position: absolute; top: 18%; left: 76%;',
  },
  {
    id: 'bmmd',
    style: 'position: absolute; top: 21%; left: 79%;',
  },
  {
    id: 'brtd',
    style: 'position: absolute; top: 4%; left: 74%;',
  },
  {
    id: 'bmtd',
    style: 'position: absolute; top: 7.5%; left: 74%;',
  },
  {
    id: 'ar',
    style: 'position: absolute; top: 83%; left: 5%;',
  },
  {
    id: 'ad',
    style: 'position: absolute; top: 9%; left: 84%;',
  }];
<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var webpack = require('webpack');
var gulpMux = require('gulp-mux');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var HtmlwebpackPlugin = require('html-webpack-plugin');
var autoprefixer = require('autoprefixer');

var target = process.env.TARGET || 'app';
var port = process.env.PORT || 5000;
var host = process.env.HOST || 'localhost';
var mode = process.env.MODE || 'dev';
var clientFolder = require('./.yo-rc.json')['generator-mcfly-ng2'].clientFolder;
var distFolder = path.join('dist', target, mode);
var suffix = gulpMux.targets.targetToSuffix(target);

var pluginsProd = mode === 'prod' ? [
    //new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
        minimize: true,
        mangle: true,
        output: {
            comments: false
        },
        compress: {
            warnings: false
        }
    })
] : [];

module.exports = {
    devtool: 'source-map', //'eval-source-map',
    debug: true,
    cache: true,
    context: path.resolve(path.join(clientFolder, 'scripts', target)), // the base directory for resolving the entry option
    entry: {
        'vendor': './vendor', // clientFolder + '/scripts/' + target  + '/vendor', // path.resolve(path.join('.', clientFolder, 'scripts', target, 'vendor')),
        'bundle': './bootstrap' //clientFolder + '/scripts/' + target  + '/bootstrap',  // path.resolve(path.join('.', clientFolder, 'scripts', target, 'bootstrap'))
    },

    output: {
        path: path.resolve(distFolder),

        filename: '[name].js',
        sourceMapFilename: '[name].js.map',
        chunkFilename: '[id].chunk.js',
        devtoolModuleFilenameTemplate: function(info) {
            //return 'scripts/app' + info.resourcePath.replace(__dirname, '../..').replace(/~/g, '/node_modules/');
            //return info.resourcePath.replace(clientFolder + '/' + 'scripts', '').replace(/~/g, '/node_modules/');
        },
        devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]'
    },

    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.html', '.scss', '.sass']
    },
    postcss: function() {
        return [autoprefixer];
    },
    module: {
        preLoaders: [{
            test: /\.ts$/,
            loader: 'tslint-loader'
        }],
        loaders: [{
                test: /\.ts$/,
                loader: 'ts',
                exclude: [/\.(e2e|spec|test)\.ts$/, /node_modules\/(?!(ng2-.+))/]
            },
            // Support for ngux files
            {
                test: /\.ngux$/,
                loader: 'html-loader!ngux-loader?subdir=ngux'
            },
            // Support for *.json files.
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            // Support for CSS as raw text in client folder
            {
                test: /\.css$/,
                loader: 'css-loader!postcss-loader',
                include: [new RegExp(clientFolder)]
            },
            // Support for CSS as injected style in node_module folder
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader!postcss-loader',
                include: [/node_modules/]
            },
            // Support for SCSS as raw text in client folder
            {
                test: /\.scss$/,
                loader: 'css-loader!postcss-loader!sass-loader?sourceMap',
                cacheable: true,
                include: [new RegExp(clientFolder)]
            },
            // Support for SCSS as inject style in node_module folder
            {
                test: /\.scss$/,
                loader: 'style-loader!css-loader!postcss-loader!sass-loader?sourceMap',
                cacheable: true,
                include: [/node_modules/]
            },
            // Support for SCSS as raw text in client folder
            {
                test: /\.sass$/,
                // Passing indentedSyntax query param to node-sass
                loader: 'css-loader!postcss-loader!sass-loader?indentedSyntax&sourceMap',
                cacheable: true,
                include: [new RegExp(clientFolder)]
            },
            // Support for SCSS as inject style in node_module folder
            {
                test: /\.sass$/,
                // Passing indentedSyntax query param to node-sass
                loader: 'style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax&sourceMap',
                cacheable: true,
                include: [/node_modules/]
            },
            // support for .html as raw text
            {
                test: /\.html$/,
                loader: 'html-loader'
            }, {
                test: /\.png$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.jpg$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.gif$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.woff$/,
                loader: 'url-loader?name=fonts/[hash].[ext]&prefix=font/&limit=5000'
            }, {
                test: /\.woff2$/,
                loader: 'url-loader?name=fonts/[hash].[ext]&prefix=font/&limit=5000'
            }, {
                test: /\.eot$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }, {
                test: /\.ttf$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }, {
                test: /\.svg$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }
        ],
        //noParse: [/.+zone\.js\/dist\/.+/, /.+angular2\/bundles\/.+/]
        noParse: [
            /zone\.js\/dist\/zone-microtask\.js/,
            /zone\.js\/dist\/long-stack-trace-zone\.js/,
            /zone\.js\/dist\/jasmine-patch\.js/,
            /es6-shim/,
            /reflect-metadata/,
            /web-animations/,
            /.+angular2\/bundles\/.+/
        ]
    },
    tslint: {
        emitErrors: false,
        failOnHint: false
    },
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        progress: true,
        // Display only errors to reduce the amount of output.
        stats: 'errors-only',
        // Parse host and port from env so this is easy to customize.
        host: host,
        port: port
    },
    plugins: [
        // make sure we can import the chunks on node or fuse
        new webpack.BannerPlugin(
            'if (typeof window === "undefined") {window = global;}\n' +
            'if (typeof window["webpackJsonp"]) {webpackJsonp = window.webpackJsonp;}\n', {
                raw: true,
                entryOnly: true
            }),
        new CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.js',
            minChunks: Infinity
        }),
        new CommonsChunkPlugin({
            name: 'common',
            filename: 'common.js',
            minChunks: 2,
            chunks: ['bundle', 'vendor']
        }),
        new HtmlwebpackPlugin({
            title: 'App - ' + target,
            template: clientFolder + '/index' + suffix + '.html',
            inject: 'body'
        })
    ].concat(pluginsProd)
};
<commit_msg>fix(app): Fix ts-loader extension files<commit_after>'use strict';
var path = require('path');
var webpack = require('webpack');
var gulpMux = require('gulp-mux');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var HtmlwebpackPlugin = require('html-webpack-plugin');
var autoprefixer = require('autoprefixer');

var target = process.env.TARGET || 'app';
var port = process.env.PORT || 5000;
var host = process.env.HOST || 'localhost';
var mode = process.env.MODE || 'dev';
var clientFolder = require('./.yo-rc.json')['generator-mcfly-ng2'].clientFolder;
var distFolder = path.join('dist', target, mode);
var suffix = gulpMux.targets.targetToSuffix(target);

var pluginsProd = mode === 'prod' ? [
    //new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
        minimize: true,
        mangle: true,
        output: {
            comments: false
        },
        compress: {
            warnings: false
        }
    })
] : [];

module.exports = {
    devtool: 'source-map', //'eval-source-map',
    debug: true,
    cache: true,
    context: path.resolve(path.join(clientFolder, 'scripts', target)), // the base directory for resolving the entry option
    entry: {
        'vendor': './vendor', // clientFolder + '/scripts/' + target  + '/vendor', // path.resolve(path.join('.', clientFolder, 'scripts', target, 'vendor')),
        'bundle': './bootstrap' //clientFolder + '/scripts/' + target  + '/bootstrap',  // path.resolve(path.join('.', clientFolder, 'scripts', target, 'bootstrap'))
    },

    output: {
        path: path.resolve(distFolder),

        filename: '[name].js',
        sourceMapFilename: '[name].js.map',
        chunkFilename: '[id].chunk.js',
        devtoolModuleFilenameTemplate: function(info) {
            //return 'scripts/app' + info.resourcePath.replace(__dirname, '../..').replace(/~/g, '/node_modules/');
            //return info.resourcePath.replace(clientFolder + '/' + 'scripts', '').replace(/~/g, '/node_modules/');
        },
        devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]'
    },

    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.html', '.scss', '.sass']
    },
    postcss: function() {
        return [autoprefixer];
    },
    module: {
        preLoaders: [{
            test: /\.ts$/,
            loader: 'tslint-loader'
        }],
        loaders: [{
                test: /\.ts$/,
                loader: 'ts',
                exclude: [/\.(e2e|test)\.ts$/, /node_modules\/(?!(ng2-.+))/]
            },
            // Support for ngux files
            {
                test: /\.ngux$/,
                loader: 'html-loader!ngux-loader?subdir=ngux'
            },
            // Support for *.json files.
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            // Support for CSS as raw text in client folder
            {
                test: /\.css$/,
                loader: 'css-loader!postcss-loader',
                include: [new RegExp(clientFolder)]
            },
            // Support for CSS as injected style in node_module folder
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader!postcss-loader',
                include: [/node_modules/]
            },
            // Support for SCSS as raw text in client folder
            {
                test: /\.scss$/,
                loader: 'css-loader!postcss-loader!sass-loader?sourceMap',
                cacheable: true,
                include: [new RegExp(clientFolder)]
            },
            // Support for SCSS as inject style in node_module folder
            {
                test: /\.scss$/,
                loader: 'style-loader!css-loader!postcss-loader!sass-loader?sourceMap',
                cacheable: true,
                include: [/node_modules/]
            },
            // Support for SCSS as raw text in client folder
            {
                test: /\.sass$/,
                // Passing indentedSyntax query param to node-sass
                loader: 'css-loader!postcss-loader!sass-loader?indentedSyntax&sourceMap',
                cacheable: true,
                include: [new RegExp(clientFolder)]
            },
            // Support for SCSS as inject style in node_module folder
            {
                test: /\.sass$/,
                // Passing indentedSyntax query param to node-sass
                loader: 'style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax&sourceMap',
                cacheable: true,
                include: [/node_modules/]
            },
            // support for .html as raw text
            {
                test: /\.html$/,
                loader: 'html-loader'
            }, {
                test: /\.png$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.jpg$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.gif$/,
                loader: 'url-loader?name=images/[hash].[ext]&prefix=img/&limit=5000'
            }, {
                test: /\.woff$/,
                loader: 'url-loader?name=fonts/[hash].[ext]&prefix=font/&limit=5000'
            }, {
                test: /\.woff2$/,
                loader: 'url-loader?name=fonts/[hash].[ext]&prefix=font/&limit=5000'
            }, {
                test: /\.eot$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }, {
                test: /\.ttf$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }, {
                test: /\.svg$/,
                loader: 'file-loader?name=fonts/[hash].[ext]&prefix=font/'
            }
        ],
        //noParse: [/.+zone\.js\/dist\/.+/, /.+angular2\/bundles\/.+/]
        noParse: [
            /zone\.js\/dist\/zone-microtask\.js/,
            /zone\.js\/dist\/long-stack-trace-zone\.js/,
            /zone\.js\/dist\/jasmine-patch\.js/,
            /es6-shim/,
            /reflect-metadata/,
            /web-animations/,
            /.+angular2\/bundles\/.+/
        ]
    },
    tslint: {
        emitErrors: false,
        failOnHint: false
    },
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        progress: true,
        // Display only errors to reduce the amount of output.
        stats: 'errors-only',
        // Parse host and port from env so this is easy to customize.
        host: host,
        port: port
    },
    plugins: [
        // make sure we can import the chunks on node or fuse
        new webpack.BannerPlugin(
            'if (typeof window === "undefined") {window = global;}\n' +
            'if (typeof window["webpackJsonp"]) {webpackJsonp = window.webpackJsonp;}\n', {
                raw: true,
                entryOnly: true
            }),
        new CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.js',
            minChunks: Infinity
        }),
        new CommonsChunkPlugin({
            name: 'common',
            filename: 'common.js',
            minChunks: 2,
            chunks: ['bundle', 'vendor']
        }),
        new HtmlwebpackPlugin({
            title: 'App - ' + target,
            template: clientFolder + '/index' + suffix + '.html',
            inject: 'body'
        })
    ].concat(pluginsProd)
};
<|endoftext|>


<commit_before>"use strict";

var Backbone = require('backbone');
var $ = require('jquery');
Backbone.$ = $;
var geocoder = new google.maps.Geocoder();

module.exports = Backbone.View.extend({
  tagName: 'div',
  id: 'map-canvas',

  initialize: function(options){
    this.businesses = options.businesses;
    var mapOptions = {
      zoom: this.model.get('zoom'),
    };
    var map = new google.maps.Map(this.el, mapOptions);

    this.businesses.forEach(function(business){
      geocoder.geocode( { 'address': business.get('address')},
        function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            var marker = new google.maps.Marker({
              map: map,
              position: results[0].geometry.location
            });
          } else {
            console.log("Geocode was not successful for the following reason: " + status);
          }
        });
    });

    this.getDirections(map);
    this.render();
  },

  getDirections: function(map){
    var directionsService = new google.maps.DirectionsService();
    var directionsDisplay = new google.maps.DirectionsRenderer();
    directionsDisplay.setMap(map);

    var request = {
      origin: this.model.get('start'),
      destination: this.model.get('end'),
      travelMode: google.maps.DirectionsTravelMode.WALKING
    };

    directionsService.route(request, function(response, status) {
      if (status === google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });

    this.render();
  },

  render: function(){
    $('#backbone').replaceWith(this.$el);
    return this;
  },
});
<commit_msg>Make geocoder a local variable instead of global<commit_after>"use strict";

var Backbone = require('backbone');
var $ = require('jquery');
Backbone.$ = $;

module.exports = Backbone.View.extend({
  tagName: 'div',
  id: 'map-canvas',

  initialize: function(options){
    this.businesses = options.businesses;
    var mapOptions = {
      zoom: this.model.get('zoom'),
    };

    var geocoder = new google.maps.Geocoder();
    var map = new google.maps.Map(this.el, mapOptions);

    this.businesses.forEach(function(business){
      geocoder.geocode( { 'address': business.get('address')},
        function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            var marker = new google.maps.Marker({
              map: map,
              position: results[0].geometry.location
            });
          } else {
            console.log("Geocode was not successful for the following reason: " + status);
          }
        });
    });

    this.getDirections(map);
    this.render();
  },

  getDirections: function(map){
    var directionsService = new google.maps.DirectionsService();
    var directionsDisplay = new google.maps.DirectionsRenderer();
    directionsDisplay.setMap(map);

    var request = {
      origin: this.model.get('start'),
      destination: this.model.get('end'),
      travelMode: google.maps.DirectionsTravelMode.WALKING
    };

    directionsService.route(request, function(response, status) {
      if (status === google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });

    this.render();
  },

  render: function(){
    $('#backbone').replaceWith(this.$el);
    return this;
  },
});
<|endoftext|>