<commit_before>// Contain everything within the cat object
var cat = {};

// the whole app needs to know when jsPlumb is ready because only then can we draw connections
cat.jsplumb_ready = false;

jsPlumb.bind('ready', function() {
    jsPlumb.Defaults.Container = $('#field');

    cat.jsplumb_ready = true;
    $(document).trigger('jsplumb-ready');

    // TODO this is for dragging/sorting possibility
    /* some combination of this might work -- laggy/buggy though
     * ALSO: how to do it on mobile?
    $('#sensors').sortable();
    $('#actuators').sortable();
    jsPlumb.draggable($('.sensor'), {containment: '#sensors'});
    jsPlumb.draggable($('.actuator'), {containment: '#actuators'});
    */
});

// TODO remove when done debugging
function toggle_debug_log() {
    $('#debug-log').toggleClass('hide');
}

// websocket server
cat.server_url = 'ws://localhost:8001';
// for Galileo
// cat.server_url = 'ws://cat/';

// parameterize events
cat.tap = 'mousedown';

// cat.app is the angular app
cat.app = angular.module('ConnectAnything', []);

cat.app.filter('sensors', function() {
    return function(pins) {
        return _.filter(pins, function(pin) {
            return pin.is_input && pin.is_visible;
        });
    }
});
cat.app.filter('actuators', function() {
    return function(pins) {
        return  _.filter(pins, function(pin) {
            return !pin.is_input && pin.is_visible;
        });
    }
});

// The controller for the whole app. Also handles talking to the server.
// Eventually probably want to refactor
cat.app.controller('PinsCtrl', ['$scope', function($scope, server) {

    var $document = $(document);

    // TODO take this out when done debugging
    window.$scope = $scope;

    $scope.activated_sensor = null;
    $scope.settings_pin = null;
    $scope.pins = {};
    $scope.connections = [];

    // good resource: http://clintberry.com/2013/angular-js-websocket-service/
    var ws = new WebSocket(cat.server_url);
    // for Galileo
    //var ws = new WebSocket(cat.server_url, 'hardware-state-protocol');
    ws.onopen = function() {
        console.log('socket opened');
    };

    //TODO remove when done debugging
    var $debug_log = $('#debug-log');

    ws.onmessage = function(msg) {
        //TODO remove when done debugging
        $debug_log.html(msg.data);
        var data = JSON.parse(msg.data);
        console.log('websocket data', data);

        var new_pins = cat.my_pin_format(data.pins, data.connections);

        cat.clear_all_connections();
        $scope.$apply(function() {
            $scope.pins = new_pins;
            $scope.connections = data.connections;
        });
    };

    $scope.sync_pins = function() {
        ws.send(JSON.stringify({
            status: 'OK',
            pins: cat.server_pin_format($scope.pins),
        }));
    };

    var connect = function(sensor, actuator) {
        ws.send(JSON.stringify({
            status: 'OK',
            connections: [{source: sensor, target: actuator}],
        }));
        $scope.connections.push({
            source: sensor,
            target: actuator,
        });
        $scope.pins[sensor].is_connected = true;
        $scope.pins[actuator].is_connected = true;
    };

    var disconnect = function(sensor, actuator) {
        ws.send(JSON.stringify({
            status: 'OK',
            connections: [{source: sensor, target: actuator}],
        }));
        $scope.connections = _.filter($scope.connections, function(c) {
            return !(c.source === sensor && c.target === actuator);
        });
        cat.clear_connection(sensor, actuator);
    };

    $scope.toggle_activated = function(sensor) {
        $scope.$apply(function() {
            if ($scope.activated_sensor === sensor) {
                $scope.activated_sensor = null;
            } else {
                $scope.activated_sensor = sensor;
            }
        });
    };

    $scope.connect_or_disconnect = function(actuator) {
        $scope.$apply(function() {
            if ($scope.activated_sensor === null) {
                return;
            }
            var sensor = $scope.activated_sensor;
            var existing_connection = _.filter($scope.connections, function(c) {
                return c.source === sensor && c.target === actuator;
            });
            if (existing_connection.length === 0) {
                connect(sensor, actuator);
            } else {
                var msg = 'Do you want to delete the ' + $scope.pins[sensor].name + ' - ' + $scope.pins[actuator].name + ' connection?';
                if (confirm(msg)) {
                    disconnect(sensor, actuator);
                }
            }
            $scope.activated_sensor = null;
        });
    };

    $scope.show_settings_for = function(pin) {
        $scope.$apply(function() {
            $scope.settings_pin = pin;
        });
    };

    $scope.close_settings = function() {
        $scope.$apply(function() {
            $scope.settings_pin = null;
        });
    };
}]);

// sensor and actuator directives both inherit from cat.pin_base
cat.pin_base = function(click_callback_maker) {

    return function($scope, $el, attrs) {
        var $endpoint = $el.find('.endpoint');
        var $box = $el.find('.pin-box');

        $endpoint.on(cat.tap, click_callback_maker($scope, $el, attrs));
        $box.on(cat.tap, function(e) {
            $scope.show_settings_for(attrs.id);

        });

        $el.on('$destroy', function() {
            $endpoint.off(cat.tap);
            $box.off(cat.tap);
        });

    }
};

cat.app.directive('sensor', function($document) {
// TODO can I just do this with ng-click?
    var sensor_callback_maker = function($scope, $el, attrs) {
        return function(e) {
            $scope.toggle_activated(attrs.id);
        }
    };

    return {link: cat.pin_base(sensor_callback_maker)};
});

cat.app.directive('actuator', function($document) {

    var actuator_callback_maker = function($scope, $el, attrs) {
        return function(e) {
            $scope.connect_or_disconnect(attrs.id);
        }
    };

    return {link: cat.pin_base(actuator_callback_maker)};
});

cat.app.directive('connection', function($document) {
    function link($scope, $el, attrs) {

        var $sensor, $actuator, connection, msg;
        $sensor = $actuator = connection = msg = null;

        function find_my_pins() {
            $sensor = $('#'+attrs.sensorId);
            $actuator = $('#'+attrs.actuatorId);
            if ($sensor.length === 0 || $actuator.length === 0) {
                setTimeout(find_my_pins, 10);
            } else {
                render();
            }
        }

        function render() {
            connection = jsPlumb.connect({
                source: attrs.sensorId,
                target: attrs.actuatorId,
                connector: ['Bezier', {curviness: 70}],
                cssClass: 'connection pins-'+attrs.sensorId+'-'+attrs.actuatorId,
                endpoint: 'Blank',
                endpointClass: 'endpoint pins-'+attrs.sensorId+'-'+attrs.actuatorId,
                anchors: ['Right', 'Left'],
                paintStyle: {
                    lineWidth: 15,
                    strokeStyle: 'rgb(232, 189, 0)',
                    outlineWidth: 2,
                    outlineColor: 'antiquewhite',
                },
                endpointStyle: {
                    fillStyle: '#a7b04b',
                },
                hoverPaintStyle: {
                    strokeStyle: 'rgb(250, 250, 60)',
                },
            });
        }

        find_my_pins();
    }

    return {
        link: link,
    };
});

cat.clear_all_connections = function() {
    $('._jsPlumb_endpoint').remove();
    $('._jsPlumb_connector').remove();
};

cat.clear_connection = function(sensor, actuator) {
    $('.connection.pins-'+sensor+'-'+actuator).remove();
};

// translate between client side and server side format for pins
cat.my_pin_format = function(server_pins, server_connections) {
    var pins = {};

    _.each(server_pins, function(pin, id) {
        var name = id;
        if (pin.is_analog && !pin.is_input)   // analog out:
            name = '~' + id;                  // ex. '~3'
        if (pin.is_analog && pin.is_input)    // analog in:
            name = 'A' + (parseInt(id) - 14); // 14 = A0, 15 = A1, etc

        pins[id] = _.extend({
            id: id,
            name: name,
            is_connected: false,
        }, pin);
        pins[id].value *= 100;
    });

    _.each(server_connections, function(c) {
        pins[c.source].is_connected = true;
        pins[c.target].is_connected = true;
    });

    return pins;
};

cat.server_pin_format = function(my_pins) {
    var pins = {};

    _.each(my_pins, function(pin, id) {
        pins[id] = {
            label: pin.label,
            value: pin.value / 100,
            is_visible: pin.is_visible,
            is_analog: pin.is_analog,
            is_input: pin.is_input,
            sensitivity: pin.sensitivity,
            is_inverted: pin.is_inverted,
        };
    });

    return pins;
};
<commit_msg>opening settings for pin deactivates all pins<commit_after>// Contain everything within the cat object
var cat = {};

// the whole app needs to know when jsPlumb is ready because only then can we draw connections
cat.jsplumb_ready = false;

jsPlumb.bind('ready', function() {
    jsPlumb.Defaults.Container = $('#field');

    cat.jsplumb_ready = true;
    $(document).trigger('jsplumb-ready');

    // TODO this is for dragging/sorting possibility
    /* some combination of this might work -- laggy/buggy though
     * ALSO: how to do it on mobile?
    $('#sensors').sortable();
    $('#actuators').sortable();
    jsPlumb.draggable($('.sensor'), {containment: '#sensors'});
    jsPlumb.draggable($('.actuator'), {containment: '#actuators'});
    */
});

// TODO remove when done debugging
function toggle_debug_log() {
    $('#debug-log').toggleClass('hide');
}

// websocket server
cat.server_url = 'ws://localhost:8001';
// for Galileo
// cat.server_url = 'ws://cat/';

// parameterize events
cat.tap = 'mousedown';

// cat.app is the angular app
cat.app = angular.module('ConnectAnything', []);

cat.app.filter('sensors', function() {
    return function(pins) {
        return _.filter(pins, function(pin) {
            return pin.is_input && pin.is_visible;
        });
    }
});
cat.app.filter('actuators', function() {
    return function(pins) {
        return  _.filter(pins, function(pin) {
            return !pin.is_input && pin.is_visible;
        });
    }
});

// The controller for the whole app. Also handles talking to the server.
// Eventually probably want to refactor
cat.app.controller('PinsCtrl', ['$scope', function($scope, server) {

    var $document = $(document);

    // TODO take this out when done debugging
    window.$scope = $scope;

    $scope.activated_sensor = null;
    $scope.settings_pin = null;
    $scope.pins = {};
    $scope.connections = [];

    // good resource: http://clintberry.com/2013/angular-js-websocket-service/
    var ws = new WebSocket(cat.server_url);
    // for Galileo
    //var ws = new WebSocket(cat.server_url, 'hardware-state-protocol');
    ws.onopen = function() {
        console.log('socket opened');
    };

    //TODO remove when done debugging
    var $debug_log = $('#debug-log');

    ws.onmessage = function(msg) {
        //TODO remove when done debugging
        $debug_log.html(msg.data);
        var data = JSON.parse(msg.data);
        console.log('websocket data', data);

        var new_pins = cat.my_pin_format(data.pins, data.connections);

        cat.clear_all_connections();
        $scope.$apply(function() {
            $scope.pins = new_pins;
            $scope.connections = data.connections;
        });
    };

    $scope.sync_pins = function() {
        ws.send(JSON.stringify({
            status: 'OK',
            pins: cat.server_pin_format($scope.pins),
        }));
    };

    var connect = function(sensor, actuator) {
        ws.send(JSON.stringify({
            status: 'OK',
            connections: [{source: sensor, target: actuator}],
        }));
        $scope.connections.push({
            source: sensor,
            target: actuator,
        });
        $scope.pins[sensor].is_connected = true;
        $scope.pins[actuator].is_connected = true;
    };

    var disconnect = function(sensor, actuator) {
        ws.send(JSON.stringify({
            status: 'OK',
            connections: [{source: sensor, target: actuator}],
        }));
        $scope.connections = _.filter($scope.connections, function(c) {
            return !(c.source === sensor && c.target === actuator);
        });
        cat.clear_connection(sensor, actuator);
    };

    $scope.toggle_activated = function(sensor) {
        $scope.$apply(function() {
            if ($scope.activated_sensor === sensor) {
                $scope.activated_sensor = null;
            } else {
                $scope.activated_sensor = sensor;
            }
        });
    };

    $scope.connect_or_disconnect = function(actuator) {
        $scope.$apply(function() {
            if ($scope.activated_sensor === null) {
                return;
            }
            var sensor = $scope.activated_sensor;
            var existing_connection = _.filter($scope.connections, function(c) {
                return c.source === sensor && c.target === actuator;
            });
            if (existing_connection.length === 0) {
                connect(sensor, actuator);
            } else {
                var msg = 'Do you want to delete the ' + $scope.pins[sensor].name + ' - ' + $scope.pins[actuator].name + ' connection?';
                if (confirm(msg)) {
                    disconnect(sensor, actuator);
                }
            }
            $scope.activated_sensor = null;
        });
    };

    $scope.show_settings_for = function(pin) {
        $scope.$apply(function() {
            $scope.activated_pin = null;
            $scope.settings_pin = pin;
        });
    };

    $scope.close_settings = function() {
        $scope.$apply(function() {
            $scope.settings_pin = null;
        });
    };
}]);

// sensor and actuator directives both inherit from cat.pin_base
cat.pin_base = function(click_callback_maker) {

    return function($scope, $el, attrs) {
        var $endpoint = $el.find('.endpoint');
        var $box = $el.find('.pin-box');

        $endpoint.on(cat.tap, click_callback_maker($scope, $el, attrs));
        $box.on(cat.tap, function(e) {
            $scope.show_settings_for(attrs.id);

        });

        $el.on('$destroy', function() {
            $endpoint.off(cat.tap);
            $box.off(cat.tap);
        });

    }
};

cat.app.directive('sensor', function($document) {
// TODO can I just do this with ng-click?
    var sensor_callback_maker = function($scope, $el, attrs) {
        return function(e) {
            $scope.toggle_activated(attrs.id);
        }
    };

    return {link: cat.pin_base(sensor_callback_maker)};
});

cat.app.directive('actuator', function($document) {

    var actuator_callback_maker = function($scope, $el, attrs) {
        return function(e) {
            $scope.connect_or_disconnect(attrs.id);
        }
    };

    return {link: cat.pin_base(actuator_callback_maker)};
});

cat.app.directive('connection', function($document) {
    function link($scope, $el, attrs) {

        var $sensor, $actuator, connection, msg;
        $sensor = $actuator = connection = msg = null;

        function find_my_pins() {
            $sensor = $('#'+attrs.sensorId);
            $actuator = $('#'+attrs.actuatorId);
            if ($sensor.length === 0 || $actuator.length === 0) {
                setTimeout(find_my_pins, 10);
            } else {
                render();
            }
        }

        function render() {
            connection = jsPlumb.connect({
                source: attrs.sensorId,
                target: attrs.actuatorId,
                connector: ['Bezier', {curviness: 70}],
                cssClass: 'connection pins-'+attrs.sensorId+'-'+attrs.actuatorId,
                endpoint: 'Blank',
                endpointClass: 'endpoint pins-'+attrs.sensorId+'-'+attrs.actuatorId,
                anchors: ['Right', 'Left'],
                paintStyle: {
                    lineWidth: 15,
                    strokeStyle: 'rgb(232, 189, 0)',
                    outlineWidth: 2,
                    outlineColor: 'antiquewhite',
                },
                endpointStyle: {
                    fillStyle: '#a7b04b',
                },
                hoverPaintStyle: {
                    strokeStyle: 'rgb(250, 250, 60)',
                },
            });
        }

        find_my_pins();
    }

    return {
        link: link,
    };
});

cat.clear_all_connections = function() {
    $('._jsPlumb_endpoint').remove();
    $('._jsPlumb_connector').remove();
};

cat.clear_connection = function(sensor, actuator) {
    $('.connection.pins-'+sensor+'-'+actuator).remove();
};

// translate between client side and server side format for pins
cat.my_pin_format = function(server_pins, server_connections) {
    var pins = {};

    _.each(server_pins, function(pin, id) {
        var name = id;
        if (pin.is_analog && !pin.is_input)   // analog out:
            name = '~' + id;                  // ex. '~3'
        if (pin.is_analog && pin.is_input)    // analog in:
            name = 'A' + (parseInt(id) - 14); // 14 = A0, 15 = A1, etc

        pins[id] = _.extend({
            id: id,
            name: name,
            is_connected: false,
        }, pin);
        pins[id].value *= 100;
    });

    _.each(server_connections, function(c) {
        pins[c.source].is_connected = true;
        pins[c.target].is_connected = true;
    });

    return pins;
};

cat.server_pin_format = function(my_pins) {
    var pins = {};

    _.each(my_pins, function(pin, id) {
        pins[id] = {
            label: pin.label,
            value: pin.value / 100,
            is_visible: pin.is_visible,
            is_analog: pin.is_analog,
            is_input: pin.is_input,
            sensitivity: pin.sensitivity,
            is_inverted: pin.is_inverted,
        };
    });

    return pins;
};
<|endoftext|>


<commit_before>class NegotiationController {

  constructor() {
    const $ = document.querySelector.bind(document);

    // avoid traversing the DOM many times
    this._amount = $('#amount')
    this._date = $('#date')
    this._value = $('#value')

    this._negotiationsList = new NegotiationList();
    this._negotiatioView = new NegotiationView()
  }

  add(event) {
    event.preventDefault();

    const negotiation = this._createNegotiation();

    this._negotiationsList.add(negotiation);
    this._negotiatioView.update(negotiation)
    this._cleanForm();
  }

  _cleanForm() {
    this._amount.value = 1;
    this._date.value = '';
    this._value.value = 0.0

    this._date.focus();
  }

  _createNegotiation() {
    return new Negotiation(
      DateHelper.stringToDate(this._date.value),
      this._amount.value,
      this._value.value
    );
  }
}
<commit_msg>add message in negotiatiocontroller<commit_after>class NegotiationController {

  constructor() {
    const $ = document.querySelector.bind(document);

    // avoid traversing the DOM many times
    this._amount = $('#amount')
    this._date = $('#date')
    this._value = $('#value')

    this._negotiationsList = new NegotiationList();
    this._negotiatioView = new NegotiationView();
    this._message = new Message();
  }

  add(event) {
    event.preventDefault();

    const negotiation = this._createNegotiation();

    this._negotiationsList.add(negotiation);
    this._negotiatioView.update(negotiation)
    this._message.text = 'Negotiation saves successfully';
    this._cleanForm();
  }

  _cleanForm() {
    this._amount.value = 1;
    this._date.value = '';
    this._value.value = 0.0

    this._date.focus();
  }

  _createNegotiation() {
    return new Negotiation(
      DateHelper.stringToDate(this._date.value),
      this._amount.value,
      this._value.value
    );
  }
}
<|endoftext|>


<commit_before>import Express from 'express';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import path from 'path';

// Webpack Requirements
import webpack from 'webpack';
import config from '../webpack.config.dev';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

// Initialize the Express App
const app = new Express();

if (process.env.NODE_ENV !== 'production') {
  const compiler = webpack(config);
  app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
  app.use(webpackHotMiddleware(compiler));
}

// React And Redux Setup
import { configureStore } from '../shared/redux/store/configureStore';
import { Provider } from 'react-redux';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import Helmet from 'react-helmet';

// Import required modules
import routes from '../shared/routes';
import { fetchComponentData } from './util/fetchData';
import apiRoutes from './api.routes';
import serverConfig from './config';

// MongoDB Connection
mongoose.connect(serverConfig.mongoURL, (error) => {
  if (error) {
    console.error('Please make sure Mongodb is installed and running!'); // eslint-disable-line no-console
    throw error;
  }
});

// Apply body Parser and server public assets and routes
app.use(bodyParser.json({ limit: '20mb' }));
app.use(bodyParser.urlencoded({ limit: '20mb', extended: false }));
app.use(Express.static(path.resolve(__dirname, '../static')));
app.use('/api', apiRoutes);
//app.use('/api', shipment);
//app.use('/api', shipmentTemplate);

// Render Initial HTML
const renderFullPage = (html, initialState) => {
  const bootstrapPath = 'css/bootstrap.min.css';
  const cssPath = process.env.NODE_ENV === 'production' ? '/css/app.min.css' : '/css/app.css';
  const fontAwesomePath = '/font-awesome-4.6.3/css/font-awesome.min.css';
  const head = Helmet.rewind();

  return `
    <!doctype html>

        ${head.base.toString()}
        ${head.title.toString()}
        ${head.meta.toString()}
        ${head.link.toString()}
        ${head.script.toString()}

        <link href="https://fonts.googleapis.com/css?family=Asap:700|Roboto:700" rel="stylesheet">
        <link rel="stylesheet" href=${bootstrapPath} />
        <link rel="stylesheet" href=${cssPath} />
        <link rel="stylesheet" href=${fontAwesomePath} />
        <link href='https://fonts.googleapis.com/css?family=Lato:400,300,700' rel='stylesheet' type='text/css'/>

${html}

  `;
};

const renderError = err => {
  const softTab = '    ';
  const errTrace = process.env.NODE_ENV !== 'production' ?
    `:<br><br><pre style="color:red">${softTab}${err.stack.replace(/\n/g, `
${softTab}`)}</pre>` : '';
  return renderFullPage(`Server Error${errTrace}`, {});
};

// Server Side Rendering based on routes matched by React-router.
app.use((req, res, next) => {
  match({ routes, location: req.url }, (err, redirectLocation, renderProps) => {
    if (err) {
      return res.status(500).end(renderError(err));
    }

    if (redirectLocation) {
      return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
    }

    if (!renderProps) {
      return next();
    }

      /**
       * Updated to hold "shipments"
       */
    const initialState = {
        deptLinks: {},
        currDept: undefined,
        templates: [],
        currTemplate: undefined,
        shipments: [],
        currShipment: undefined,
        query: {},
    };

    const store = configureStore(initialState);

    return fetchComponentData(store, renderProps.components, renderProps.params)
      .then(() => {
        const initialView = renderToString(
          <Provider store={store}>
            <RouterContext {...renderProps} />
          </Provider>
        );
        const finalState = store.getState();

        res.status(200).end(renderFullPage(initialView, finalState));
      })
      .catch((err) => next(err));
  });
});

// start app
app.listen(serverConfig.port, (error) => {
  if (!error) {
    console.log(`MERN is running on port: ${serverConfig.port}! Build something amazing!`); // eslint-disable-line
  }
});

export default app;
<commit_msg>Font fix<commit_after>import Express from 'express';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import path from 'path';

// Webpack Requirements
import webpack from 'webpack';
import config from '../webpack.config.dev';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

// Initialize the Express App
const app = new Express();

if (process.env.NODE_ENV !== 'production') {
  const compiler = webpack(config);
  app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
  app.use(webpackHotMiddleware(compiler));
}

// React And Redux Setup
import { configureStore } from '../shared/redux/store/configureStore';
import { Provider } from 'react-redux';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import Helmet from 'react-helmet';

// Import required modules
import routes from '../shared/routes';
import { fetchComponentData } from './util/fetchData';
import apiRoutes from './api.routes';
import serverConfig from './config';

// MongoDB Connection
mongoose.connect(serverConfig.mongoURL, (error) => {
  if (error) {
    console.error('Please make sure Mongodb is installed and running!'); // eslint-disable-line no-console
    throw error;
  }
});

// Apply body Parser and server public assets and routes
app.use(bodyParser.json({ limit: '20mb' }));
app.use(bodyParser.urlencoded({ limit: '20mb', extended: false }));
app.use(Express.static(path.resolve(__dirname, '../static')));
app.use('/api', apiRoutes);
//app.use('/api', shipment);
//app.use('/api', shipmentTemplate);

// Render Initial HTML
const renderFullPage = (html, initialState) => {
  const bootstrapPath = 'css/bootstrap.min.css';
  const cssPath = process.env.NODE_ENV === 'production' ? '/css/app.min.css' : '/css/app.css';
  const fontAwesomePath = '/font-awesome-4.6.3/css/font-awesome.min.css';
  const head = Helmet.rewind();

  return `
    <!doctype html>

        ${head.base.toString()}
        ${head.title.toString()}
        ${head.meta.toString()}
        ${head.link.toString()}
        ${head.script.toString()}

        <link href="https://fonts.googleapis.com/css?family=Asap:700|Roboto:700" rel="stylesheet">
        <link rel="stylesheet" href=${bootstrapPath} />
        <link rel="stylesheet" href=${cssPath} />
        <link rel="stylesheet" href=${fontAwesomePath} />

${html}

  `;
};

const renderError = err => {
  const softTab = '    ';
  const errTrace = process.env.NODE_ENV !== 'production' ?
    `:<br><br><pre style="color:red">${softTab}${err.stack.replace(/\n/g, `
${softTab}`)}</pre>` : '';
  return renderFullPage(`Server Error${errTrace}`, {});
};

// Server Side Rendering based on routes matched by React-router.
app.use((req, res, next) => {
  match({ routes, location: req.url }, (err, redirectLocation, renderProps) => {
    if (err) {
      return res.status(500).end(renderError(err));
    }

    if (redirectLocation) {
      return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
    }

    if (!renderProps) {
      return next();
    }

      /**
       * Updated to hold "shipments"
       */
    const initialState = {
        deptLinks: {},
        currDept: undefined,
        templates: [],
        currTemplate: undefined,
        shipments: [],
        currShipment: undefined,
        query: {},
    };

    const store = configureStore(initialState);

    return fetchComponentData(store, renderProps.components, renderProps.params)
      .then(() => {
        const initialView = renderToString(
          <Provider store={store}>
            <RouterContext {...renderProps} />
          </Provider>
        );
        const finalState = store.getState();

        res.status(200).end(renderFullPage(initialView, finalState));
      })
      .catch((err) => next(err));
  });
});

// start app
app.listen(serverConfig.port, (error) => {
  if (!error) {
    console.log(`MERN is running on port: ${serverConfig.port}! Build something amazing!`); // eslint-disable-line
  }
});

export default app;
<|endoftext|>


<commit_before>export { init, testCorrectness, disposeResources };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
import * as Pool_Asserter from "../util/Pool_Asserter.js";
import * as ValueDesc from "../Unpacker/ValueDesc.js";
import * as BatchIdCalculator from "./BatchIdCalculator.js";
import * as Stage from "../Conv/Stage.js";
import * as Stage_Reference from "./Ref/Stage_Reference.js";
import * as Stage_TestParams from "./Ref/Stage_TestParams.js";
import * as ImageSourceBag from "./Ref/ImageSourceBag.js";
import * as NumberImage from "./Ref/NumberImage.js";

/**
 * Test CNN Stage.
 *
 * @see {@link https://www.measurethat.net/Benchmarks/Show/15055/90/colorfulcakechen-cnn-block-a4bc81be0a8974ea17d20da05fdf}
 */

/**
 * A test set.
 */
class HeightWidthDepth {

  /**
   * @param {number} height            image height
   * @param {number} width             image width
   * @param {number} depth             image channel count
   */
  constructor( height, width, depth ) {

    this.disposeResources();

    this.height = height;
    this.width = width;
    this.depth = depth;

    this.valueCount = height * width * depth;
  }

  disposeResources() {
    if ( this.dataTensor3dArray ) {
      tf.dispose( this.dataTensor3dArray );
      this.dataTensor3dArray = null;
    }

    this.block_PerformanceTest_release();
  }

  block_PerformanceTest_init() {

    // Release dataTensor3d too. Because perofrmance testing uses larger different input image from correctness testing.
    this.disposeResources();

    // Larger input image for performance testing.
    let inputTensorCount = 1;
    this.testPerformance_NumberImageArray = Recyclable.OwnerArray.Pool.get_or_create_by( inputTensorCount );
    this.dataTensor3dArray = tf.tidy( () => {
      let inputScaleBoundsArray = ActivationEscaping.ScaleBoundsArray.Pool.get_or_create_by( this.depth );

      let dataTensor3dArray = new Array( inputTensorCount );

      let shape = [ this.height, this.width, this.depth ];
      let elementCount = tf.util.sizeFromShape( shape );

      for ( let i = 0; i < dataTensor3dArray.length; ++i ) {
        let numberBegin = ( i * elementCount );
        let numberEnd = numberBegin + elementCount;

        let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.Pool.get_or_create_by(
          this.height, this.width, this.depth, undefined,
          inputScaleBoundsArray, null, BoundsArraySet.InputsOutputs, Weights.Base.ValueBounds );

        for ( let j = 0; j < elementCount; ++j ) {
          image.dataArray[ j ] = numberBegin + j;
        }

        dataTensor3dArray[ i ] = tf.tensor( image.dataArray, shape );
      }

      inputScaleBoundsArray.disposeResources_and_recycleToPool();
      inputScaleBoundsArray = null;

      return dataTensor3dArray;
    });

    let stepCountRequested = 10;
    let nSqueezeExcitationChannelCountDivisor = 4;

    // sourceHeight, sourceWidth, sourceChannelCount,
    // nConvStageTypeId,
    // blockCountRequested,
    // bPointwise1,
    // depthwiseFilterHeight, depthwiseFilterWidth,
    // bPointwise2ActivatedAtStageEnd,
    // nSqueezeExcitationChannelCountDivisor,
    // nActivationId,
    // bKeepInputTensor
    //
    // The stage performance testing should:
    //   - ( bKeepInputTensor == true ). Otherwise, the this.dataTensor3d will be destroyed.
    //

    if ( this.testCaseMap )
      this.testCaseMap.clear();
    else
      this.testCaseMap = new Map();

    // Test Case 1: (MobileNetV1, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV1_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V1,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 2: (MobileNetV1_padValid, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV1_padValid_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V1_PAD_VALID,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 3: (MobileNetV2_Thin, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV2_Thin_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V2_THIN,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 4: (MobileNetV2, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV2_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V2,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 5: (ShuffleNetV2, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleV2_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 6: (ShuffleNetV2_byPointwise22, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleV2_byPointwise22_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_POINTWISE22,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 7: (ShuffleNetV2_byMobileNetV1, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleNetV2_byMobileNetV1_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_MOBILE_NET_V1,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 8: (ShuffleNetV2_byMobileNetV1_padValid, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleNetV2_byMobileNetV1_padValid_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_MOBILE_NET_V1_PAD_VALID,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Create the different Stage objects for performance testing.
    for ( let name_testCase of this.testCaseMap.entries() ) {
      let name = name_testCase[ 0 ];
      let testCase = name_testCase[ 1 ];
      if ( !testCase.stage ) {
        testCase.stage = Stage_Reference.Base.Stage_create( testCase.testParams );
      }

      console.log( `Stage.${name}: tensorWeightCount = { Extracted: ${testCase.block.tensorWeightCountExtracted}, `
        + `Total: ${testCase.block.tensorWeightCountTotal} }` );
    }

  }

  block_PerformanceTest_release() {
    if ( this.testCaseMap ) {
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        if ( testCase.stage ) {
          testCase.stage.disposeResources_and_recycleToPool();
        }
      }
      this.testCaseMap.clear();
    }

    if ( this.testPerformance_NumberImageArray ) {
      this.testPerformance_NumberImageArray.disposeResources_and_recycleToPool();
      this.testPerformance_NumberImageArray = null;
    }
  }

  /** Test apply by Xxx */
  testStage_ByName( testCaseName ) {
    let testCase = this.testCaseMap.get( testCaseName );
    let block = testCase.block;
    let outputTensor3d = block.apply( this.dataTensor3dArray[ 0 ] );
    tf.dispose( outputTensor3d );
  }

  /** Testing whether the results of different implementation are the same. */
  * testCorrectness() {

    tf.tidy( () => {

      let memoryInfo_testCorrectness_before = tf.memory(); // Test memory leakage of imageSourceBag.

      {
        // Note: imageSourceBag should not be created outside tidy() because tidy() will dispose tensors
        //       dynamically created in them.
        let imageSourceBag = new ImageSourceBag.Base();

        let testParams = new Stage_TestParams.Base();
        let testParamsGenerator = testParams.ParamsGenerator();
        let testReference = new Stage_Reference.Base();

        let batchIdCalculator = new BatchIdCalculator.Base( 50 * 1000 );

        try {
          for ( testParams of testParamsGenerator ) {
            batchIdCalculator.checkAndDisplay( testParams.id );
            testReference.testCorrectness( imageSourceBag, testParams );
          }

        } catch ( e ) {
          let backendName = tf.getBackend();
          console.log( `jsPerf_Stage.js: testCorrectness(): backendName=${backendName}, `
            + `Stage testParams.id == ${testParams.id}` );
          throw e;
        }

        imageSourceBag.disposeResources();
      }

      let memoryInfo_testCorrectness_after = tf.memory();

      if ( memoryInfo_testCorrectness_after.numTensors != memoryInfo_testCorrectness_before.numTensors )
        throw Error( `testCorrectness() memory leak. `
          + `result tensor count (${memoryInfo_testCorrectness_after.numTensors}) `
          + `should be (${memoryInfo_testCorrectness_before.numTensors} `
          + `` );
    });

    // After correctness testing done, create all Stage for performance testing.
    this.block_PerformanceTest_init();
  }

}

function init() {
  //console.log("jsPerf_Stage.js, init()");

  disposeResources();

  let depth = 4;

  // Using mobile phone's resolution ( 1080 * 2160 ) will crash the computer.
  // Using ( 1 / 10 ) of computer screen ( 1080 * 1920 ).
  globalThis.testSet_108x192x4 = new HeightWidthDepth( 108, 192, depth ); // height, width, depth

  globalThis.testSet_All = [
    globalThis.testSet_108x192x4
  ];
}

function testCorrectness() {
  for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
    let testSet = globalThis.testSet_All[ i ];
    testSet.testCorrectness();
  }
}

function disposeResources() {
  if ( globalThis.testSet_All ) {
    for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
      let testSet = globalThis.testSet_All[ i ];
      if ( testSet )
        testSet.disposeResources();
    }

    globalThis.testSet_All = null;
  }

  globalThis.testSet_108x192x4
    = null;
}
<commit_msg>Update jsPerf_Stage.js<commit_after>export { init, testCorrectness, disposeResources };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
import * as Pool_Asserter from "../util/Pool_Asserter.js";
import * as ValueDesc from "../Unpacker/ValueDesc.js";
import * as BatchIdCalculator from "./BatchIdCalculator.js";
import * as Stage from "../Conv/Stage.js";
import * as Stage_Reference from "./Ref/Stage_Reference.js";
import * as Stage_TestParams from "./Ref/Stage_TestParams.js";
import * as ImageSourceBag from "./Ref/ImageSourceBag.js";
import * as NumberImage from "./Ref/NumberImage.js";

/**
 * Test CNN Stage.
 *
 * @see {@link https://www.measurethat.net/Benchmarks/Show/15055/90/colorfulcakechen-cnn-block-a4bc81be0a8974ea17d20da05fdf}
 */

/**
 * A test set.
 */
class HeightWidthDepth {

  /**
   * @param {number} height            image height
   * @param {number} width             image width
   * @param {number} depth             image channel count
   */
  constructor( height, width, depth ) {

    this.disposeResources();

    this.height = height;
    this.width = width;
    this.depth = depth;

    this.valueCount = height * width * depth;
  }

  disposeResources() {
    if ( this.dataTensor3dArray ) {
      tf.dispose( this.dataTensor3dArray );
      this.dataTensor3dArray = null;
    }

    this.block_PerformanceTest_release();
  }

  block_PerformanceTest_init() {

    // Release dataTensor3d too. Because perofrmance testing uses larger different input image from correctness testing.
    this.disposeResources();

    // Larger input image for performance testing.
    let inputTensorCount = 1;
    this.testPerformance_NumberImageArray = Recyclable.OwnerArray.Pool.get_or_create_by( inputTensorCount );
    this.dataTensor3dArray = tf.tidy( () => {
      let inputScaleBoundsArray = ActivationEscaping.ScaleBoundsArray.Pool.get_or_create_by( this.depth );

      let dataTensor3dArray = new Array( inputTensorCount );

      let shape = [ this.height, this.width, this.depth ];
      let elementCount = tf.util.sizeFromShape( shape );

      for ( let i = 0; i < dataTensor3dArray.length; ++i ) {
        let numberBegin = ( i * elementCount );
        let numberEnd = numberBegin + elementCount;

        let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.Pool.get_or_create_by(
          this.height, this.width, this.depth, undefined,
          inputScaleBoundsArray, null, BoundsArraySet.InputsOutputs, Weights.Base.ValueBounds );

        for ( let j = 0; j < elementCount; ++j ) {
          image.dataArray[ j ] = numberBegin + j;
        }

        dataTensor3dArray[ i ] = tf.tensor( image.dataArray, shape );
      }

      inputScaleBoundsArray.disposeResources_and_recycleToPool();
      inputScaleBoundsArray = null;

      return dataTensor3dArray;
    });

    let stepCountRequested = 10;
    let nSqueezeExcitationChannelCountDivisor = 4;

    // sourceHeight, sourceWidth, sourceChannelCount,
    // nConvStageTypeId,
    // blockCountRequested,
    // bPointwise1,
    // depthwiseFilterHeight, depthwiseFilterWidth,
    // bPointwise2ActivatedAtStageEnd,
    // nSqueezeExcitationChannelCountDivisor,
    // nActivationId,
    // bKeepInputTensor
    //
    // The stage performance testing should:
    //   - ( bKeepInputTensor == true ). Otherwise, the this.dataTensor3d will be destroyed.
    //

    if ( this.testCaseMap )
      this.testCaseMap.clear();
    else
      this.testCaseMap = new Map();

    // Test Case 1: (MobileNetV1, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV1_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V1,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 2: (MobileNetV1_padValid, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV1_padValid_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V1_PAD_VALID,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 3: (MobileNetV2_Thin, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV2_Thin_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V2_THIN,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 4: (MobileNetV2, ( bPointwise1 == true ))
    this.testCaseMap.set( "MobileNetV2_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.MOBILE_NET_V2,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 5: (ShuffleNetV2, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleV2_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 6: (ShuffleNetV2_byPointwise22, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleV2_byPointwise22_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_POINTWISE22,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 7: (ShuffleNetV2_byMobileNetV1, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleNetV2_byMobileNetV1_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_MOBILE_NET_V1,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Test Case 8: (ShuffleNetV2_byMobileNetV1_padValid, ( bPointwise1 == true ))
    this.testCaseMap.set( "ShuffleNetV2_byMobileNetV1_padValid_bPointwise1_true", { testParams:
      ( new Stage_TestParams.Base() ).set_By_ParamsScattered(
        this.height, this.width, this.depth,
        ValueDesc.ConvStageType.Singleton.Ids.SHUFFLE_NET_V2_BY_MOBILE_NET_V1_PAD_VALID,
        stepCountRequested, true,
        3, 3, true, nSqueezeExcitationChannelCountDivisor, ValueDesc.ActivationFunction.Singleton.Ids.CLIP_BY_VALUE_N3_P3,
        true
      ) } );

    // Create the different Stage objects for performance testing.
    for ( let name_testCase of this.testCaseMap.entries() ) {
      let name = name_testCase[ 0 ];
      let testCase = name_testCase[ 1 ];
      if ( !testCase.stage ) {
        testCase.stage = Stage_Reference.Base.Stage_create( testCase.testParams );
      }

      console.log( `Stage.${name}: tensorWeightCount = { Extracted: ${testCase.block.tensorWeightCountExtracted}, `
        + `Total: ${testCase.block.tensorWeightCountTotal} }` );
    }

  }

  block_PerformanceTest_release() {
    if ( this.testCaseMap ) {
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        if ( testCase.stage ) {
          testCase.stage.disposeResources_and_recycleToPool();
        }
      }
      this.testCaseMap.clear();
    }

    if ( this.testPerformance_NumberImageArray ) {
      this.testPerformance_NumberImageArray.disposeResources_and_recycleToPool();
      this.testPerformance_NumberImageArray = null;
    }
  }

  /** Test apply by Xxx */
  testStage_ByName( testCaseName ) {
    let testCase = this.testCaseMap.get( testCaseName );
    let block = testCase.block;
    let outputTensor3d = block.apply( this.dataTensor3dArray[ 0 ] );
    tf.dispose( outputTensor3d );
  }

  /** Testing whether the results of different implementation are the same. */
  * testCorrectness() {

    {
      let pool_all_issuedCount_before = Pool.All.issuedCount;

      //Pool_Asserter.assert_Pool_issuedCount_same_after_as_before( "jsPerf_Stage.HeightWidthDepth.testCorrectness()", () => {
      //}, this );

      yield;

      {
        let memoryInfo_testCorrectness_before = tf.memory(); // Test memory leakage of imageSourceBag.

        {
          // Note: imageSourceBag should not be created outside tidy() because tidy() will dispose tensors
          //       dynamically created in them.
          let imageSourceBag = ImageSourceBag.Base.Pool.get_or_create_by();

          let testParams = Stage_TestParams.Base.Pool.get_or_create_by();
          let testParamsGenerator = testParams.ParamsGenerator();
          let testReference = Stage_Reference.Base.Pool.get_or_create_by();

          let batchIdCalculator = new BatchIdCalculator.Base( 50 * 1000 );

          try {
            for ( testParams of testParamsGenerator ) {
              let bDisplayed = batchIdCalculator.checkAndDisplay( testParams.id );
              if ( bDisplayed )
                yield; // Since just entering a new batch section, take a break so that memory garbage collector could be activated to work.

              testReference.testCorrectness( imageSourceBag, testParams );
            }

          } catch ( e ) {
            let backendName = tf.getBackend();
            let msg = `jsPerf_Stage.js: testCorrectness(): backendName=${backendName}, `
              + `Stage, (yieldCount == ${testParams.yieldCount}), testParams.id == ${testParams.id}`;

            console.log( msg );
            alert( `${msg}\n${e}` );

            //debugger;
            throw e;
          }

          batchIdCalculator.checkAndDisplay( testParams.id );

          testReference.disposeResources_and_recycleToPool(); testReference = null;
          testParams.disposeResources_and_recycleToPool(); testParams = null;
          imageSourceBag.disposeResources_and_recycleToPool(); imageSourceBag = null;
        }

        let memoryInfo_testCorrectness_after = tf.memory();

        if ( memoryInfo_testCorrectness_after.numTensors != memoryInfo_testCorrectness_before.numTensors )
          throw Error( `testCorrectness() memory leak. `
            + `result tensor count (${memoryInfo_testCorrectness_after.numTensors}) `
            + `should be (${memoryInfo_testCorrectness_before.numTensors} `
            + `` );
      }

      Pool_Asserter.assert_Pool_issuedCount( "jsPerf_Block.HeightWidthDepth.testCorrectness()", pool_all_issuedCount_before );
      yield;
    }

    try {
      // After correctness testing done, create all Stage for performance testing.
      this.block_PerformanceTest_init();
    } catch ( e ) {
      debugger;
      throw e;
    }
  }

}

function init() {
  //console.log("jsPerf_Stage.js, init()");

  disposeResources();

  let depth = 4;

  // Using mobile phone's resolution ( 1080 * 2160 ) will crash the computer.
  // Using ( 1 / 10 ) of computer screen ( 1080 * 1920 ).
  globalThis.testSet_108x192x4 = new HeightWidthDepth( 108, 192, depth ); // height, width, depth

  globalThis.testSet_All = [
    globalThis.testSet_108x192x4
  ];
}

function* testCorrectness() {
  for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
    let testSet = globalThis.testSet_All[ i ];
    yield* testSet.testCorrectness();
  }
}

function disposeResources() {
  if ( globalThis.testSet_All ) {
    for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
      let testSet = globalThis.testSet_All[ i ];
      if ( testSet )
        testSet.disposeResources();
    }

    globalThis.testSet_All = null;
  }

  globalThis.testSet_108x192x4
    = null;
}
<|endoftext|>


<commit_before>Parse.Cloud.define("newNotifications", function(request, response) {
	console.log("newNotifications: " + JSON.stringify(request.params));
	var userId = Parse.User.current();
	var query = new Parse.Query('Notification');
	query.equalTo("to", userId);
	query.greaterThan("createdAt", new Date(request.params.lastTime.iso));
	query.limit = 1;
	query.find({
		success: function(results) {
			if (results.length > 0) {
				response.success(true)
			}
			else {
				// now count logged views if there are no notifications
				var query = new Parse.Query('Log');
				query.equalTo("to", userId);
				query.greaterThan("createdAt", new Date(request.params.lastTime.iso));
				query.limit = 1;
				query.find({
					success: function(logResults) {
						console.log("Notification test: user=" + request.user + " status=" + logResults.length);
						response.success(logResults.length > 0);
					},
					error: function(error) {
						console.error(error);
						response.error(error);
					}
				});
			}
		},
		error: function(error) {
			console.error(error);
			response.error(error);
		}
	});
});
<commit_msg>Notification logging<commit_after>Parse.Cloud.define("newNotifications", function(request, response) {
	console.log("newNotifications: " + JSON.stringify(request.params));
	var userId = Parse.User.current();
	var query = new Parse.Query('Notification');
	query.equalTo("to", userId);
	query.greaterThan("createdAt", new Date(request.params.lastTime.iso));
	query.limit = 1;
	query.find({
		success: function(results) {
			if (results.length > 0) {
				console.log("Notification Log test: user=" + request.user + " status=" + results.length);
				response.success(true)
			}
			else {
				// now count logged views if there are no notifications
				var query = new Parse.Query('Log');
				query.equalTo("to", userId);
				query.greaterThan("createdAt", new Date(request.params.lastTime.iso));
				query.limit = 1;
				query.find({
					success: function(logResults) {
						console.log("Notification Log test: user=" + request.user + " status=" + logResults.length);
						response.success(logResults.length > 0);
					},
					error: function(error) {
						console.error(error);
						response.error(error);
					}
				});
			}
		},
		error: function(error) {
			console.error(error);
			response.error(error);
		}
	});
});
<|endoftext|>


<commit_before>function Diagram() {

  // constants

  var MSECS_INA_MIN = 60 * 1000;
  var MSECS_INA_HOUR = 60 * MSECS_INA_MIN;
  var MSECS_INA_DAY = 24 * MSECS_INA_HOUR;
  var MIN_RADIUS = 2;
  var MAX_RADIUS = 20;
  var DATE_FACTOR = 0.1;
  var SIZE_FACTOR = 0;
  var CATEGORY_FACTOR = 0.3;
  var COLLISION_FACTOR = 0.01;
  var CHARGE = -50;
  var LINK_STRENGHT = 0.5;

  // factors

  var dateFactor = 0;
  var categoryFactor = 0; //CATEGORY_FACTOR;

  // padding and margin vaues

  var padding = {top: 10, right: 10, bottom: 10, left: 10};
  var margin = {top: 10, right: 10, bottom: 20, left: 10};

  // svg region

  var svgWidth;
  var svgHeight;

  // margin region

  var marginWidth;
  var marginHeight;

  // primary content area

  var width;
  var height;

  // create scales and axes

  var x = d3.time.scale();
  var y = d3.scale.pow().exponent(.5);
  var area = d3.scale.pow().exponent(.1).range([MAX_RADIUS, MIN_RADIUS]);
  var xAxis = d3.svg.axis();
  var yAxis = d3.svg.axis().orient("right");
  var color = d3.scale.category10();

  // standard diagram elements

  var svg;
  var marginArea;
  var dataArea;
  var defs;

  // layers

  var linkLayer;
  var nodeLayer;
  var tagLayer;

  // the article index

  var articleIndex = {};
  var articles = [];
  var links = [];
  var force = d3.layout.force()
    .charge(CHARGE)
    .linkStrength(LINK_STRENGHT);

  var catGroups;

  // when document ready, initialize the chart

  $(document).ready(function() {
    initialize();
  });

  // perform all chart initialization

  function initialize() {

    // construct svg, defs, and outer and inner work areas

    svg = d3.select("#chart").append("svg");
    defs = svg.append("defs");
    marginArea = svg.append("g").classed("marginArea", true);
    dataArea = svg.append("g").classed("dataArea", true);
    linkLayer = dataArea.append("g");
    nodeLayer = dataArea.append("g");
    tagLayer = dataArea.append("g");

    // size the chart

    size();

    // load the data

    load();
  }

  function load() {

    d3.json("/api/posts", function(data) {

      d3.tsv("/static/data/en.txt", function(words) {
        wordFrequency = {};
        words.forEach(function(word) {
          wordFrequency[word.word] = word.cnt;
        });

        console.log("data", data);
        var dict = [
          "cat",
          "dog",
          "bat",
          "boy",
          "frog",
          "apple",
          "banana",
          "orange",
          "bear",
        ];
        var catGen = d3.scale.linear().domain([0, 1]).rangeRound([0, dict.length - 1]);

        // extract the article data

        Object.keys(data).forEach(function(key) {
          var article = data[key];
          article.date = new Date(article.time * 1000);
          article.category = dict[catGen(Math.random())];
//          article.category = article.tags.length > 0 ? article.tags[0] : "misc.";
          article.size = article.post_content.length;
          articles.push(article);
          articleIndex[article.postid] = article;
        });

        var docFilter = function(d) {return d.post_title != "The Archives"};
        articles.filter(docFilter).forEach(function(article) {
          article.internal_links.forEach(function(link) {
            var tokens = link.split("/");
            if (tokens.length > 0) {
              var id = tokens[tokens.length - 1];
              var mention = articleIndex[id];
              if (mention) {
                links.push({source: article, target: mention});
              }
            }
          });
        });

        // links = [];

        // var ra = d3.scale.linear().rangeRound([0, articleIndex.length - 1]);
        // for (var i = 0; i < 30; ++i) {
        //   var a1 = articleIndex[ra(Math.random())];
        //   var a2 = articleIndex[ra(Math.random())];
        //   if (a1 != a2) {
        //     links.push({source: a1, target: a2});
        //   }
        // }

        construct();
        update();
        force.start();
      });
    });
  }

  // establish all chart size related elements

  function size() {

    var context = this;

    // establish metrics

    svgWidth = $("#chart").width();
    svgHeight =  $("#chart").height();
    marginWidth = svgWidth - padding.left - padding.right;
    marginHeight = svgHeight - padding.top - padding.bottom;
    width = marginWidth  - margin.left - margin.right;
    height = marginHeight - margin.top - margin.bottom;

    // update elements

    x.range([MAX_RADIUS, width - MAX_RADIUS]);
    y.range([MAX_RADIUS, height - MAX_RADIUS]);
    svg.attr("width", svgWidth).attr("height", svgHeight);
    marginArea.attr("transform", "translate(" + padding.left + "," + padding.top + ")");
    dataArea.attr("transform", "translate(" + (padding.left + margin.left) + "," + (padding.top + margin.top) + ")");

    xAxis.scale(x);
    yAxis.scale(y);
    force.size([width, height]);
  }

  // construt ontime chart specific elements

  function construct() {
    x.domain(d3.extent(articles, function(d) {return d.date}));
    y.domain(d3.extent(articles, function(d) {return d.size}));
    area.domain(d3.extent(articles, function(d) {return d.size}));

    dataArea.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .on("click", function(d) {
        dateFactor = (dateFactor) ? 0 : DATE_FACTOR;
        force.resume();
      })
      .call(xAxis);

    // dataArea.append("g")
    //   .attr("class", "y axis")
    //   .attr("transform", "translate(" + width + ",0)")
    //   .call(yAxis);

    force.nodes(articles);
    force.links(links);

    catGroups = d3.nest()
      .key(function(d) {return d.category;})
      .map(articles, d3.map);

    console.log("catGroups", catGroups);
  };

  function update() {

    linkLayer.selectAll("line.link")
      .data(links)
      .enter()
      .append("line")
      .classed("link", true)
      .on("click", function(d) {
        var ls = force.linkStrength();
        console.log("ls", ls);
        force.linkStrength(ls ? 0 : LINK_STRENGHT);
        force.start();
      });

    var enters = nodeLayer.selectAll("g.article")
      .data(articles)
      .enter()
      .append("g");

    enters
      .append("title")
      .text(function(d) {return d.post_title});

    enters
      .classed("article", true)
      .attr("fill", function(d) {
        return color(d.category)
      })
      .append("circle")
      .attr("r", function(d) {d.radius = area(d.size); return d.radius});

    var categoryData = Object.keys(catGroups).map(function(name) {
      return {name: name}
    });

    tagLayer.selectAll("text.category")
      .data(categoryData)
      .enter()
      .append("text")
      .classed("category", true)
      .attr("text-anchor", "middle")
      .text(function(d) {return d.name})
      .on("click", function(d) {
        categoryFactor = categoryFactor ? 0 : CATEGORY_FACTOR;
        force.resume();
      });

    force.on("tick", function(e) {

      var CLUSTER = true;
      var COLLISION = true;

      if (CLUSTER) {
        var k = categoryFactor * e.alpha;
        categoryData.forEach(function(category) {
          var members = catGroups[category.name];
          var cx = 0;
          var cy = 0;
          members.forEach(function(member) {
            cx += member.x;
            cy += member.y;
          });

          category.x = cx / members.length;
          category.y = cy / members.length;

          members.forEach(function(member) {
            var clx = member.x + k * (category.x - member.x);
            var cly = member.y + k * (category.y - member.y);
            member.x = x(member.date) * dateFactor + clx * (1 - dateFactor);
            member.y = y(member.size) * SIZE_FACTOR + cly * (1 - SIZE_FACTOR);
          });
        });
      }

      if (COLLISION) {
        var q = d3.geom.quadtree(articles);

        var i = 0;
        var n = articles.length;

        while (++i < n) {
          q.visit(collide(articles[i]));
        }
      }

      d3.selectAll("text.category")
        .attr("x", function(d) {return d.x})
        .attr("y", function(d) {return d.y});

      d3.selectAll("g.article")
        .attr("transform", function(d) {
          var xt = d.x;
          var yt = d.y;
          return "translate(" + xt + ", " + yt + ")";
        });

      d3.selectAll("line.link")
        .attr("x1", function(d) {return d.source.x})
        .attr("y1", function(d) {return d.source.y})
        .attr("x2", function(d) {return d.target.x})
        .attr("y2", function(d) {return d.target.y});
    });
  }

  function collide(node) {
    var r = node.radius;
    var nx1 = node.x - r;
    var nx2 = node.x + r;
    var ny1 = node.y - r;
    var ny2 = node.y + r;

    return function(quad, x1, y1, x2, y2) {
      if (quad.point && (quad.point !== node)) {
        var x = node.x - quad.point.x;
        var y = node.y - quad.point.y;
        var l = Math.sqrt(x * x + y * y);
        var r = node.radius + quad.point.radius;

        if (l < r) {
          l = (l - r) / l * COLLISION_FACTOR;
          node.x -= x *= l;
          node.y -= y *= l;
          quad.point.x += x;
          quad.point.y += y;
        }
      }
      return x1 > nx2
        || x2 < nx1
        || y1 > ny2
        || y2 < ny1;
    };
  }
}

$(document).ready(function() {
  var d = new Diagram();
});

<commit_msg>uneven distro of fakey categories<commit_after>function Diagram() {

  // constants

  var MSECS_INA_MIN = 60 * 1000;
  var MSECS_INA_HOUR = 60 * MSECS_INA_MIN;
  var MSECS_INA_DAY = 24 * MSECS_INA_HOUR;
  var MIN_RADIUS = 2;
  var MAX_RADIUS = 20;
  var DATE_FACTOR = 0.1;
  var SIZE_FACTOR = 0;
  var CATEGORY_FACTOR = 0.3;
  var COLLISION_FACTOR = 0.01;
  var CHARGE = -50;
  var LINK_STRENGHT = 0.5;

  // factors

  var dateFactor = 0;
  var categoryFactor = 0;

  // padding and margin vaues

  var padding = {top: 10, right: 10, bottom: 10, left: 10};
  var margin = {top: 10, right: 10, bottom: 20, left: 10};

  // svg region

  var svgWidth;
  var svgHeight;

  // margin region

  var marginWidth;
  var marginHeight;

  // primary content area

  var width;
  var height;

  // create scales and axes

  var x = d3.time.scale();
  var y = d3.scale.pow().exponent(.5);
  var area = d3.scale.pow().exponent(.1).range([MAX_RADIUS, MIN_RADIUS]);
  var xAxis = d3.svg.axis();
  var yAxis = d3.svg.axis().orient("right");
  var color = d3.scale.category10();

  // standard diagram elements

  var svg;
  var marginArea;
  var dataArea;
  var defs;

  // layers

  var linkLayer;
  var nodeLayer;
  var tagLayer;

  // the article index

  var articleIndex = {};
  var articles = [];
  var links = [];
  var force = d3.layout.force()
    .charge(CHARGE)
    .linkStrength(0);

  var catGroups;

  // when document ready, initialize the chart

  $(document).ready(function() {
    initialize();
  });

  // perform all chart initialization

  function initialize() {

    // construct svg, defs, and outer and inner work areas

    svg = d3.select("#chart").append("svg");
    defs = svg.append("defs");
    marginArea = svg.append("g").classed("marginArea", true);
    dataArea = svg.append("g").classed("dataArea", true);
    linkLayer = dataArea.append("g");
    nodeLayer = dataArea.append("g");
    tagLayer = dataArea.append("g");

    // size the chart

    size();

    // load the data

    load();
  }

  function load() {

    d3.json("/api/posts", function(data) {

      d3.tsv("/static/data/en.txt", function(words) {
        wordFrequency = {};
        words.forEach(function(word) {
          wordFrequency[word.word] = word.cnt;
        });

        console.log("data", data);
        var dict = [
          "cat",
          "dog",
          "bat",
          "boy",
          "frog",
          "apple",
          "banana",
          "orange",
          "bear",
        ];
        var catGen = d3.scale.pow().exponent(4).domain([0, 1]).rangeRound([0, dict.length - 1]);

        // extract the article data

        Object.keys(data).forEach(function(key) {
          var article = data[key];
          article.date = new Date(article.time * 1000);
          article.category = dict[catGen(Math.random())];
//          article.category = article.tags.length > 0 ? article.tags[0] : "misc.";
          article.size = article.post_content.length;
          articles.push(article);
          articleIndex[article.postid] = article;
        });

        var docFilter = function(d) {return d.post_title != "The Archives"};
        articles.filter(docFilter).forEach(function(article) {
          article.internal_links.forEach(function(link) {
            var tokens = link.split("/");
            if (tokens.length > 0) {
              var id = tokens[tokens.length - 1];
              var mention = articleIndex[id];
              if (mention) {
                links.push({source: article, target: mention});
              }
            }
          });
        });

        // links = [];

        // var ra = d3.scale.linear().rangeRound([0, articleIndex.length - 1]);
        // for (var i = 0; i < 30; ++i) {
        //   var a1 = articleIndex[ra(Math.random())];
        //   var a2 = articleIndex[ra(Math.random())];
        //   if (a1 != a2) {
        //     links.push({source: a1, target: a2});
        //   }
        // }

        construct();
        update();
        force.start();
      });
    });
  }

  // establish all chart size related elements

  function size() {

    var context = this;

    // establish metrics

    svgWidth = $("#chart").width();
    svgHeight =  $("#chart").height();
    marginWidth = svgWidth - padding.left - padding.right;
    marginHeight = svgHeight - padding.top - padding.bottom;
    width = marginWidth  - margin.left - margin.right;
    height = marginHeight - margin.top - margin.bottom;

    // update elements

    x.range([MAX_RADIUS, width - MAX_RADIUS]);
    y.range([MAX_RADIUS, height - MAX_RADIUS]);
    svg.attr("width", svgWidth).attr("height", svgHeight);
    marginArea.attr("transform", "translate(" + padding.left + "," + padding.top + ")");
    dataArea.attr("transform", "translate(" + (padding.left + margin.left) + "," + (padding.top + margin.top) + ")");

    xAxis.scale(x);
    yAxis.scale(y);
    force.size([width, height]);
  }

  // construt ontime chart specific elements

  function construct() {
    x.domain(d3.extent(articles, function(d) {return d.date}));
    y.domain(d3.extent(articles, function(d) {return d.size}));
    area.domain(d3.extent(articles, function(d) {return d.size}));

    dataArea.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .on("click", function(d) {
        dateFactor = (dateFactor) ? 0 : DATE_FACTOR;
        force.resume();
      })
      .call(xAxis);

    // dataArea.append("g")
    //   .attr("class", "y axis")
    //   .attr("transform", "translate(" + width + ",0)")
    //   .call(yAxis);

    force.nodes(articles);
    force.links(links);

    catGroups = d3.nest()
      .key(function(d) {return d.category;})
      .map(articles, d3.map);

    console.log("catGroups", catGroups);
  };

  function update() {

    linkLayer.selectAll("line.link")
      .data(links)
      .enter()
      .append("line")
      .classed("link", true)
      .on("click", function(d) {
        var ls = force.linkStrength();
        console.log("ls", ls);
        force.linkStrength(ls ? 0 : LINK_STRENGHT);
        force.start();
      });

    var enters = nodeLayer.selectAll("g.article")
      .data(articles)
      .enter()
      .append("g");

    enters
      .append("title")
      .text(function(d) {return d.post_title});

    enters
      .classed("article", true)
      .attr("fill", function(d) {
        return color(d.category)
      })
      .append("circle")
      .attr("r", function(d) {d.radius = area(d.size); return d.radius});

    var categoryData = Object.keys(catGroups).map(function(name) {
      return {name: name}
    });

    tagLayer.selectAll("text.category")
      .data(categoryData)
      .enter()
      .append("text")
      .classed("category", true)
      .attr("text-anchor", "middle")
      .text(function(d) {return d.name})
      .on("click", function(d) {
        categoryFactor = categoryFactor ? 0 : CATEGORY_FACTOR;
        force.resume();
      });

    force.on("tick", function(e) {

      var CLUSTER = true;
      var COLLISION = true;

      if (CLUSTER) {
        var k = categoryFactor * e.alpha;
        categoryData.forEach(function(category) {
          var members = catGroups[category.name];
          var cx = 0;
          var cy = 0;
          members.forEach(function(member) {
            cx += member.x;
            cy += member.y;
          });

          category.x = cx / members.length;
          category.y = cy / members.length;

          members.forEach(function(member) {
            var clx = member.x + k * (category.x - member.x);
            var cly = member.y + k * (category.y - member.y);
            member.x = x(member.date) * dateFactor + clx * (1 - dateFactor);
            member.y = y(member.size) * SIZE_FACTOR + cly * (1 - SIZE_FACTOR);
          });
        });
      }

      if (COLLISION) {
        var q = d3.geom.quadtree(articles);

        var i = 0;
        var n = articles.length;

        while (++i < n) {
          q.visit(collide(articles[i]));
        }
      }

      d3.selectAll("text.category")
        .attr("x", function(d) {return d.x})
        .attr("y", function(d) {return d.y});

      d3.selectAll("g.article")
        .attr("transform", function(d) {
          var xt = d.x;
          var yt = d.y;
          return "translate(" + xt + ", " + yt + ")";
        });

      d3.selectAll("line.link")
        .attr("x1", function(d) {return d.source.x})
        .attr("y1", function(d) {return d.source.y})
        .attr("x2", function(d) {return d.target.x})
        .attr("y2", function(d) {return d.target.y});
    });
  }

  function collide(node) {
    var r = node.radius;
    var nx1 = node.x - r;
    var nx2 = node.x + r;
    var ny1 = node.y - r;
    var ny2 = node.y + r;

    return function(quad, x1, y1, x2, y2) {
      if (quad.point && (quad.point !== node)) {
        var x = node.x - quad.point.x;
        var y = node.y - quad.point.y;
        var l = Math.sqrt(x * x + y * y);
        var r = node.radius + quad.point.radius;

        if (l < r) {
          l = (l - r) / l * COLLISION_FACTOR;
          node.x -= x *= l;
          node.y -= y *= l;
          quad.point.x += x;
          quad.point.y += y;
        }
      }
      return x1 > nx2
        || x2 < nx1
        || y1 > ny2
        || y2 < ny1;
    };
  }
}

$(document).ready(function() {
  var d = new Diagram();
});

<|endoftext|>


<commit_before>/*
---

name: ART.Canvas

description: Canvas implementation for ART

authors: [Valerio Proietti](http://mad4milk.net) && [MooTools development team](http://mootools.net/developers)

provides: ART.Canvas

requires: ART

...
*/

ART.Canvas = new Class({

	initialize: function(id, width, height){
		this.element = new Element('canvas', {'id': id || 'art-' + $time()});
		this.context = this.element.getContext('2d');
		this.resize({x: width, y: height});
	},

	resize: function(size){
		this.element.width = size.x;
		this.element.height = size.y;
		return this;
	},

	clear: function(){
		this.context.clearRect(0, 0, this.element.width, this.element.height);
		return this;
	},

	start: function(){
		this.drawStack = [];
		this.drawn = false;
		this.previousOutline = null;
		this.bounds = {x: [], y: []};
		this.context.beginPath();
		return this;
	},

	end: function(style){
		var stack = this.drawStack;
		for (var i=0; i < stack.length; i++){
			var s = stack[i], method = s[0], args = s[1];
			this.context[method].apply(this.context, args);
		}

		if (style.fill != null){
			var fill = $splat(style.fill);
			this.fill(fill[0], fill[1], style.fillMode);
		}
		if (style.outline != null) this.outline(style.outline, style.outlineWidth, style.outlineCap, style.outlineJoin);

		if (style.shadow != null) this.shadow(style.shadow, style.shadowOffset, style.shadowBlur);

		return this;
	},

	join: function(){
		this.drawStack.push(['closePath', []]);
		return this;
	},

	/* drawing methods */

	move: function(vector){
		if (!this.drawn) this.lastVector = vector;
		this.drawStack.push(['moveTo', [vector.x, vector.y]]);
		return this;
	},

	line: function(vector){
		if (!this.drawn) this.setStartCoordinate();
		this.bounds.x.push(vector.x);
		this.bounds.y.push(vector.y);
		this.drawStack.push(['lineTo', [vector.x, vector.y]]);
		return this;
	},

	bezier: function(c1, c2, end){
		if (!this.drawn) this.setStartCoordinate();
		this.bounds.x.push(c1.x, c2.x, end.x);
		this.bounds.y.push(c1.y, c2.y, end.y);
		this.drawStack.push(['bezierCurveTo', [c1.x, c1.y, c2.x, c2.y, end.x, end.y]]);
		return this;
	},

	setStartCoordinate: function(){
		this.bounds.x.push(this.lastVector.x);
		this.bounds.y.push(this.lastVector.y);
		this.drawn = true;
	},

	/* privates */

	fill: function(color1, color2, mode){

		var fillStyle = color1.valueOf();

		if (color2 != null){
			var gradient;

			if (mode == 'vertical'){
				var minY = Math.min.apply(Math, this.bounds.y), maxY = Math.max.apply(Math, this.bounds.y);
				gradient = this.context.createLinearGradient(0, minY, 0, maxY);
			} else if (mode == 'horizontal') {
				var minX = Math.min.apply(Math, this.bounds.x), maxX = Math.max.apply(Math, this.bounds.x);
				gradient = this.context.createLinearGradient(minX, 0, maxX, 0);
			}

			gradient.addColorStop(0, fillStyle);
			gradient.addColorStop(1, color2.valueOf());
			fillStyle = gradient;
		}

		this.context.fillStyle = fillStyle;

		this.context.fill();
		return this;
	},

	outline: function(color, width, cap, join){
		this.previousOutline = [width, cap, join];
		this.context.strokeStyle = color.valueOf();
		this.context.lineWidth = Number(width);
		this.context.lineCap = cap;
		this.context.lineJoin = join;
		this.context.stroke();
		return this;
	},

	shadow: function(color, offset, blur){
		this.context.globalCompositeOperation = 'destination-over';
		var oldPath = this.drawStack, outline = this.previousOutline;
		this.context.translate(offset.x, offset.y);
		this.start();
		this.drawStack = oldPath;
		var end = {fill: color, outline: null, shadow: null};
		if (outline != null) $extend(end, {outline: color, outlineWidth: outline[0], outlineCap: outline[1], outlineJoin: outline[2]});
		this.end(end);
		this.context.translate(-offset.x, -offset.y);
		this.context.globalCompositeOperation = 'source-over';
	},

	/* $ */

	toElement: function(){
		return this.element;
	}

});

(function(){

var dummy = document.createElement('canvas');
if (!!(dummy && dummy.getContext)) ART.registerAdapter(ART.Canvas);

})();
<commit_msg> - saved previousFill in order to only draw outline shadows for non-filled elements.<commit_after>/*
---

name: ART.Canvas

description: Canvas implementation for ART

authors: [Valerio Proietti](http://mad4milk.net) && [MooTools development team](http://mootools.net/developers)

provides: ART.Canvas

requires: ART

...
*/

ART.Canvas = new Class({

	initialize: function(id, width, height){
		this.element = new Element('canvas', {'id': id || 'art-' + $time()});
		this.context = this.element.getContext('2d');
		this.resize({x: width, y: height});
	},

	resize: function(size){
		this.element.width = size.x;
		this.element.height = size.y;
		return this;
	},

	clear: function(){
		this.context.clearRect(0, 0, this.element.width, this.element.height);
		return this;
	},

	start: function(){
		this.drawStack = [];
		this.drawn = false;
		this.previousOutline = null;
		this.previousFill = null;
		this.bounds = {x: [], y: []};
		this.context.beginPath();
		return this;
	},

	end: function(style){
		var stack = this.drawStack;
		for (var i=0; i < stack.length; i++){
			var s = stack[i], method = s[0], args = s[1];
			this.context[method].apply(this.context, args);
		}

		if (style.fill != null){
			var fill = $splat(style.fill);
			this.fill(fill[0], fill[1], style.fillMode);
		}
		if (style.outline != null) this.outline(style.outline, style.outlineWidth, style.outlineCap, style.outlineJoin);

		if (style.shadow != null) this.shadow(style.shadow, style.shadowOffset, style.shadowBlur);

		return this;
	},

	join: function(){
		this.drawStack.push(['closePath', []]);
		return this;
	},

	/* drawing methods */

	move: function(vector){
		if (!this.drawn) this.lastVector = vector;
		this.drawStack.push(['moveTo', [vector.x, vector.y]]);
		return this;
	},

	line: function(vector){
		if (!this.drawn) this.setStartCoordinate();
		this.bounds.x.push(vector.x);
		this.bounds.y.push(vector.y);
		this.drawStack.push(['lineTo', [vector.x, vector.y]]);
		return this;
	},

	bezier: function(c1, c2, end){
		if (!this.drawn) this.setStartCoordinate();
		this.bounds.x.push(c1.x, c2.x, end.x);
		this.bounds.y.push(c1.y, c2.y, end.y);
		this.drawStack.push(['bezierCurveTo', [c1.x, c1.y, c2.x, c2.y, end.x, end.y]]);
		return this;
	},

	setStartCoordinate: function(){
		this.bounds.x.push(this.lastVector.x);
		this.bounds.y.push(this.lastVector.y);
		this.drawn = true;
	},

	/* privates */

	fill: function(color1, color2, mode){
		this.previousFill = true;

		var fillStyle = color1.valueOf();

		if (color2 != null){
			var gradient;

			if (mode == 'vertical'){
				var minY = Math.min.apply(Math, this.bounds.y), maxY = Math.max.apply(Math, this.bounds.y);
				gradient = this.context.createLinearGradient(0, minY, 0, maxY);
			} else if (mode == 'horizontal') {
				var minX = Math.min.apply(Math, this.bounds.x), maxX = Math.max.apply(Math, this.bounds.x);
				gradient = this.context.createLinearGradient(minX, 0, maxX, 0);
			}

			gradient.addColorStop(0, fillStyle);
			gradient.addColorStop(1, color2.valueOf());
			fillStyle = gradient;
		}

		this.context.fillStyle = fillStyle;

		this.context.fill();
		return this;
	},

	outline: function(color, width, cap, join){
		this.previousOutline = [width, cap, join];
		this.context.strokeStyle = color.valueOf();
		this.context.lineWidth = Number(width);
		this.context.lineCap = cap;
		this.context.lineJoin = join;
		this.context.stroke();
		return this;
	},

	shadow: function(color, offset, blur){
		this.context.globalCompositeOperation = 'destination-over';
		var oldPath = this.drawStack, outline = this.previousOutline, fill = this.previousFill;
		this.context.translate(offset.x, offset.y);
		this.start();
		this.drawStack = oldPath;
		var end = {fill: null, outline: null, shadow: null};
		if (fill != null) end.fill = color;
		if (outline != null) $extend(end, {outline: color, outlineWidth: outline[0], outlineCap: outline[1], outlineJoin: outline[2]});
		this.end(end);
		this.context.translate(-offset.x, -offset.y);
		this.context.globalCompositeOperation = 'source-over';
	},

	/* $ */

	toElement: function(){
		return this.element;
	}

});

(function(){

var dummy = document.createElement('canvas');
if (!!(dummy && dummy.getContext)) ART.registerAdapter(ART.Canvas);

})();
<|endoftext|>


<commit_before>
featureToggleFrontend.controller('TogglesController', ['$scope', '$timeout', 'toggleService', 'applicationService', 'focus', 'ENV', '$rootScope', function($scope, $timeout, toggleService, applicationService, focus, ENV, $rootScope) {

    $scope.adding = false;
    $scope.newToggleName = '';
    $scope.setAddingToggleState = function(state){
        $scope.adding = state;
        if (state){
            $scope.newToggleName = $scope.toggleSuggestions[0];
            focus('newToggleName');
        }
    };

    $scope.updateThisToggle = function(toggle){
        $timeout(function(){
            toggleService.updateFeatureToggle($scope.applicationName, $scope.featureName,
                $scope.isMultiToggle, toggle.name, toggle.value,
                function(){
                    $rootScope.$broadcast('toggleUpdated', toggle, $scope.isMultiToggle);
                },
                function(data){
                    $scope.$emit('error', "Failed to update toggle", new Error(data));
                });
        });
    };

    $scope.updateToggleDescription = function(featureName, newFeatureDescription){
        console.log(featureName);
        toggleService.updateFeatureDescription($scope.applicationName, featureName, newFeatureDescription,
            function(){
                $scope.description = newFeatureDescription;
                $scope.$emit('success', featureName + "'s description was successfully updated");
            },
            function(data){
                $scope.$emit('error', "Failed to update feature", new Error(data));
            });
    };

    var validateNewToggle = function(toggleName){
        if (!toggleName){
            return "Must enter an toggle name";
        }
        if (!_.contains($scope.toggleSuggestions, toggleName)){
            return "Not a valid toggle name. Please use the autocomplete box to get valid values.";
        }
        if (_.any($scope.toggles, function(toggle){ return toggle.name === toggleName;})){
            return "Toggle name must be unique in this application";
        }
    };

    var addFakeToggle = function(toggleName){
        $scope.toggles.push({
            name: toggleName,
            value: false
        });
        $scope.toggleSuggestions = _.without($scope.toggleSuggestions, toggleName);
    };

    $scope.addToggle = function() {
        var applicationName = $scope.applicationName;
        var featureName = $scope.featureName;
        var toggleName = $scope.newToggleName.trim();

        var validationError = validateNewToggle(toggleName);
        if (validationError){
            $scope.$emit('error', validationError);
            return;
        }

        toggleService.addFeatureToggle(applicationName, featureName, toggleName,
            function(){
                addFakeToggle(toggleName);
                $scope.setAddingToggleState(false);
                $scope.$emit('success', toggleName + " was successfully added");
            },
            function(data){
                $scope.$emit('error', "Failed to add feature", new Error(data));
            });
    };

    var addGithubSearchDataToToggles = function(feature, metaData){
        var githubRepoUrl = metaData.githubRepoUrl || 'https://github.com/opentable/' + $scope.applicationName;
        if (_.last(githubRepoUrl) === '/'){
            githubRepoUrl = githubRepoUrl.substring(0, githubRepoUrl.length - 1);
        }
        _.each($scope.toggles, function(toggle){
            var searchPhrase = feature.isMultiToggle ? $scope.featureName + '+AND+' + toggle.name : $scope.featureName;
            toggle.githubSearchUrl = githubRepoUrl + '/search?utf8=✓&type=Code&q=' + searchPhrase;
        });
    };

    (function loadFeatureToggles() {
        $scope.toggles = [];
        $scope.description = '';
        $scope.loadingToggles = true;
        $scope.isMultiToggle = false;

        toggleService.getFeature($scope.applicationName, $scope.featureName,
            function(feature){
                $scope.toggles = feature.toggles;
                $scope.description = feature.featureDescription;
                $scope.isMultiToggle = feature.isMultiToggle;
                $scope.toggleSuggestions = feature.toggleSuggestions;
                $scope.loadingToggles = false;

                applicationService.getApplicationMetaData($scope.applicationName, function(err, metaData){
                    if (err){
                        return $scope.$emit('error', "Failed to get Github search data for these toggles", new Error(err));
                    }
                    addGithubSearchDataToToggles(feature, metaData);
                });
            },
            function(data){
                $scope.$emit('error', "Failed to load this feature toggle", new Error(data));
                $scope.loadingToggles = false;
            });
    })();

}]);
<commit_msg>removed useless logging<commit_after>
featureToggleFrontend.controller('TogglesController', ['$scope', '$timeout', 'toggleService', 'applicationService', 'focus', 'ENV', '$rootScope', function($scope, $timeout, toggleService, applicationService, focus, ENV, $rootScope) {

    $scope.adding = false;
    $scope.newToggleName = '';
    $scope.setAddingToggleState = function(state){
        $scope.adding = state;
        if (state){
            $scope.newToggleName = $scope.toggleSuggestions[0];
            focus('newToggleName');
        }
    };

    $scope.updateThisToggle = function(toggle){
        $timeout(function(){
            toggleService.updateFeatureToggle($scope.applicationName, $scope.featureName,
                $scope.isMultiToggle, toggle.name, toggle.value,
                function(){
                    $rootScope.$broadcast('toggleUpdated', toggle, $scope.isMultiToggle);
                },
                function(data){
                    $scope.$emit('error', "Failed to update toggle", new Error(data));
                });
        });
    };

    $scope.updateToggleDescription = function(featureName, newFeatureDescription){
        toggleService.updateFeatureDescription($scope.applicationName, featureName, newFeatureDescription,
            function(){
                $scope.description = newFeatureDescription;
                $scope.$emit('success', featureName + "'s description was successfully updated");
            },
            function(data){
                $scope.$emit('error', "Failed to update feature", new Error(data));
            });
    };

    var validateNewToggle = function(toggleName){
        if (!toggleName){
            return "Must enter an toggle name";
        }
        if (!_.contains($scope.toggleSuggestions, toggleName)){
            return "Not a valid toggle name. Please use the autocomplete box to get valid values.";
        }
        if (_.any($scope.toggles, function(toggle){ return toggle.name === toggleName;})){
            return "Toggle name must be unique in this application";
        }
    };

    var addFakeToggle = function(toggleName){
        $scope.toggles.push({
            name: toggleName,
            value: false
        });
        $scope.toggleSuggestions = _.without($scope.toggleSuggestions, toggleName);
    };

    $scope.addToggle = function() {
        var applicationName = $scope.applicationName;
        var featureName = $scope.featureName;
        var toggleName = $scope.newToggleName.trim();

        var validationError = validateNewToggle(toggleName);
        if (validationError){
            $scope.$emit('error', validationError);
            return;
        }

        toggleService.addFeatureToggle(applicationName, featureName, toggleName,
            function(){
                addFakeToggle(toggleName);
                $scope.setAddingToggleState(false);
                $scope.$emit('success', toggleName + " was successfully added");
            },
            function(data){
                $scope.$emit('error', "Failed to add feature", new Error(data));
            });
    };

    var addGithubSearchDataToToggles = function(feature, metaData){
        var githubRepoUrl = metaData.githubRepoUrl || 'https://github.com/opentable/' + $scope.applicationName;
        if (_.last(githubRepoUrl) === '/'){
            githubRepoUrl = githubRepoUrl.substring(0, githubRepoUrl.length - 1);
        }
        _.each($scope.toggles, function(toggle){
            var searchPhrase = feature.isMultiToggle ? $scope.featureName + '+AND+' + toggle.name : $scope.featureName;
            toggle.githubSearchUrl = githubRepoUrl + '/search?utf8=✓&type=Code&q=' + searchPhrase;
        });
    };

    (function loadFeatureToggles() {
        $scope.toggles = [];
        $scope.description = '';
        $scope.loadingToggles = true;
        $scope.isMultiToggle = false;

        toggleService.getFeature($scope.applicationName, $scope.featureName,
            function(feature){
                $scope.toggles = feature.toggles;
                $scope.description = feature.featureDescription;
                $scope.isMultiToggle = feature.isMultiToggle;
                $scope.toggleSuggestions = feature.toggleSuggestions;
                $scope.loadingToggles = false;

                applicationService.getApplicationMetaData($scope.applicationName, function(err, metaData){
                    if (err){
                        return $scope.$emit('error', "Failed to get Github search data for these toggles", new Error(err));
                    }
                    addGithubSearchDataToToggles(feature, metaData);
                });
            },
            function(data){
                $scope.$emit('error', "Failed to load this feature toggle", new Error(data));
                $scope.loadingToggles = false;
            });
    })();

}]);
<|endoftext|>


<commit_before>/* eslint-disable no-console, no-undef, no-unused-vars */
import http from 'http'
import path from 'path'
import Express from 'express'
import serveStatic from 'serve-static'
import {HTTPS as https} from 'express-sslify'
import cookieParser from 'cookie-parser'
import raven from 'raven'

import config from 'src/config'
import configureApp from './configureApp'
import configureSocketCluster from './configureSocketCluster'
import configureChangeFeeds from './configureChangeFeeds'

import handleAuth from './auth'
import handleReports from './reports'
import handleGraphQL from './graphql'
import {default as renderApp} from './render'

export function start() {
  // capture unhandled exceptions
  raven.patchGlobal(config.server.sentryDSN)

  const app = new Express()
  const httpServer = http.createServer(app)

  configureApp(app)

  // parse cookies
  app.use(cookieParser())

  // ensure secure connection
  if (config.server.secure) {
    /* eslint new-cap: [2, {"capIsNewExceptions": ["HTTPS"]}] */
    app.use(https({trustProtoHeader: true}))
  }

  // static files
  app.use(serveStatic(path.join(__dirname, '../dist')))
  app.use(serveStatic(path.join(__dirname, '../public')))

  // handle auth requests
  app.use((req, res, next) => {
    handleAuth(req, res, next)
  })

  // handle report requests
  app.use((req, res, next) => {
    handleReports(req, res, next)
  })

  // handle GraphQL requests
  app.use((req, res, next) => {
    handleGraphQL(req, res, next)
  })

  // serve web app
  app.get('*', (req, res, next) => {
    renderApp(req, res, next)
  })

  // catch-all error handler
  app.use((err, req, res, next) => {
    if (!config.server.secure) {
      console.error(err.stack)
    }
    const errCode = err.code || 500
    const errType = err.type || 'Internal Server Error'
    const errMessage = err.message || err.toString()
    const errInfo = `<h1>${errCode} - ${errType}</h1><p>${errMessage}</p>`
    res.status(500).send(errInfo)
  })

  // socket cluster
  configureSocketCluster(httpServer)

  // change feeds
  configureChangeFeeds()

  return httpServer.listen(config.server.port, error => {
    if (error) {
      console.error(error)
    } else {
      console.info(`🌍  Listening at ${config.server.baseURL} on port ${config.server.port}`)
    }
  })
}
<commit_msg>multiple require over single import for hot reloading in server.js<commit_after>/* eslint-disable no-console, no-undef, no-unused-vars */
import http from 'http'
import path from 'path'
import Express from 'express'
import serveStatic from 'serve-static'
import {HTTPS as https} from 'express-sslify'
import cookieParser from 'cookie-parser'
import raven from 'raven'

import config from 'src/config'
import configureApp from './configureApp'
import configureSocketCluster from './configureSocketCluster'
import configureChangeFeeds from './configureChangeFeeds'

import {default as renderApp} from './render'

export function start() {
  // capture unhandled exceptions
  raven.patchGlobal(config.server.sentryDSN)

  const app = new Express()
  const httpServer = http.createServer(app)

  configureApp(app)

  // parse cookies
  app.use(cookieParser())

  // ensure secure connection
  if (config.server.secure) {
    /* eslint new-cap: [2, {"capIsNewExceptions": ["HTTPS"]}] */
    app.use(https({trustProtoHeader: true}))
  }

  // static files
  app.use(serveStatic(path.join(__dirname, '../dist')))
  app.use(serveStatic(path.join(__dirname, '../public')))

  // handle auth requests
  app.use((req, res, next) => {
    require('./auth')(req, res, next)
  })

  // handle report requests
  app.use((req, res, next) => {
    require('./reports')(req, res, next)
  })

  // handle GraphQL requests
  app.use((req, res, next) => {
    require('./graphql')(req, res, next)
  })

  // serve web app
  app.get('*', (req, res, next) => {
    renderApp(req, res, next)
  })

  // catch-all error handler
  app.use((err, req, res, next) => {
    if (!config.server.secure) {
      console.error(err.stack)
    }
    const errCode = err.code || 500
    const errType = err.type || 'Internal Server Error'
    const errMessage = err.message || err.toString()
    const errInfo = `<h1>${errCode} - ${errType}</h1><p>${errMessage}</p>`
    res.status(500).send(errInfo)
  })

  // socket cluster
  configureSocketCluster(httpServer)

  // change feeds
  configureChangeFeeds()

  return httpServer.listen(config.server.port, error => {
    if (error) {
      console.error(error)
    } else {
      console.info(`🌍  Listening at ${config.server.baseURL} on port ${config.server.port}`)
    }
  })
}
<|endoftext|>