<commit_before>'use strict';

var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };

exports.__esModule = true;
/*!
 * router
 * Copyright(c) 2015 Fangdun Cai
 * MIT Licensed
 */

const METHODS = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'];

const SNODE = 0; // static route
const PNODE = 1; // param route
const ANODE = 2; // all star route

let Node = (function () {
  function Node(prefix, has, handler, edges) {
    _classCallCheck(this, Node);

    this.label = prefix[0];
    this.prefix = prefix;
    this.has = has;
    this.handler = handler;
    this.edges = edges;
    if (!edges) this.edges = [];
  }

  Node.prototype.findEdge = function findEdge(c) {
    let i = 0;
    let l = this.edges.length;
    let e = void 0;

    for (; i < l; i++) {
      e = this.edges[i];
      if (e.label.charCodeAt() === c.charCodeAt()) return e;
    }
    return null;
  };

  return Node;
})();

let Router = (function () {
  function Router() {
    var _this = this;

    _classCallCheck(this, Router);

    this.trees = Object.create(null);
    METHODS.forEach(function (m) {
      _this.trees[m.toUpperCase()] = new Node('', null, null, []);
    });
  }

  Router.prototype.add = function add(method, path, handler) {
    var i = 0,
        l = path.length;
    for (; i < l; i++) {
      // `:`
      if (path.charCodeAt(i) === 58) {
        this.insert(method, path.substring(0, i), null, PNODE);
        // `/`
        for (; i < l && path.charCodeAt(i) !== 47; i++) {}
        if (i === l) {
          this.insert(method, path.substring(0, i), handler, SNODE);
          return;
        }
        this.insert(method, path.substring(0, i), null, SNODE);
        // `*`
      } else if (path.charCodeAt(i) === 42) {
        this.insert(method, path.substring(0, i), handler, ANODE);
      }
    }
    this.insert(method, path, handler, SNODE);
  };

  Router.prototype.insert = function insert(method, path, handler, has) {
    let cn = this.trees[method]; // Current node as root
    let search = path;

    while (true) {
      let sl = search.length;
      let pl = cn.prefix.length;
      let l = lcp(search, cn.prefix);

      if (l === 0) {
        // At root node
        cn.label = search[0];
        cn.prefix = search;
        cn.has = has;
        if (handler) {
          cn.handler = handler;
        }
        return;
      } else if (l < pl) {
        // Split the node
        let n = new Node(cn.prefix.substring(l), cn.has, cn.handler, cn.edges);
        cn.edges = [n]; // Add to parent

        // Reset parent node
        cn.label = cn.prefix[0];
        cn.prefix = cn.prefix.substring(0, l);
        cn.has = SNODE;
        cn.handler = null;

        if (l === sl) {
          // At parent node
          cn.handler = handler;
        } else {
          // Need to fork a node
          let n = new Node(search.substring(l), has, handler, null);
          cn.edges.push(n);
        }
        break;
      } else if (l < sl) {
        search = search.substring(l);
        let e = cn.findEdge(search[0]);
        if (e) {
          cn = e;
        } else {
          let n = new Node(search, has, handler, []);
          cn.edges.push(n);
          break;
        }
      } else {
        // Node already exists
        if (handler) {
          cn.handler = handler;
        }
        break;
      }
    }
  };

  Router.prototype.find = function find(method, path) {
    let cn = this.trees[method]; // Current node as root
    let search = path;
    let n = 0; // Param count
    let result = [null];
    let params = [];

    while (true) {
      if (search === '' || search === cn.prefix) {
        // Found
        result[0] = cn.handler;
        result[1] = params;
        return result;
      }

      let pl = cn.prefix.length;
      let l = lcp(search, cn.prefix);

      if (l === pl) {
        search = search.substring(l);
        switch (cn.has) {
          case PNODE:
            cn = cn.edges[0];
            var i = 0;
            l = search.length;
            // `/`
            for (; i < l && search.charCodeAt(i) !== 47; i++) {}

            params[n] = {
              name: cn.prefix.substring(1),
              value: search.substring(0, i)
            };
            n++;

            search = search.substring(i);

            if (i === l) {
              // All params read
              continue;
            }
            break;
          case ANODE:
            params[n] = {
              name: cn.prefix.substring(1),
              value: search.substring(0, i)
            };
            search = ''; // End search
            continue;
        }

        let e = cn.findEdge(search[0]);
        if (!e) {
          // Not found
          return result;
        }
        cn = e;
        continue;
      }
      return result;
    }
  };

  return Router;
})();

// Length of longest common prefix
function lcp(a, b) {
  var i = 0;
  let max = a.length;
  let l = b.length;
  if (l < max) {
    max = l;
  }
  for (; i < max && a.charCodeAt(i) === b.charCodeAt(i); i++) {}
  return i;
}

Router.Node = Node;

exports['default'] = Router;
module.exports = exports['default'];<commit_msg>lib: recompile<commit_after>'use strict';

var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };

exports.__esModule = true;
/*!
 * router
 * Copyright(c) 2015 Fangdun Cai
 * MIT Licensed
 */

const METHODS = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'];

const SNODE = 0; // Static node
const PNODE = 1; // Param node
const ANODE = 2; // Catch-all node

let Node = (function () {
  function Node(prefix, has, handler, edges) {
    _classCallCheck(this, Node);

    this.label = prefix[0];
    this.prefix = prefix;
    this.has = has;
    this.handler = handler;
    this.edges = edges;
    if (!edges) this.edges = [];
  }

  Node.prototype.findEdge = function findEdge(c) {
    let i = 0;
    let l = this.edges.length;
    let e = void 0;

    for (; i < l; i++) {
      e = this.edges[i];
      if (e.label.charCodeAt() === c.charCodeAt()) return e;
    }
    return null;
  };

  return Node;
})();

let Router = (function () {
  function Router() {
    var _this = this;

    _classCallCheck(this, Router);

    this.trees = Object.create(null);
    METHODS.forEach(function (m) {
      _this.trees[m.toUpperCase()] = new Node('', null, null, []);
    });
  }

  Router.prototype.add = function add(method, path, handler) {
    for (let i = 0, l = path.length; i < l; i++) {
      // `:`
      if (path.charCodeAt(i) === 58) {
        this.insert(method, path.substring(0, i), null, PNODE);
        // `/`
        for (; i < l && path.charCodeAt(i) !== 47; i++) {}
        if (i === l) {
          this.insert(method, path.substring(0, i), handler, SNODE);
          return;
        }
        this.insert(method, path.substring(0, i), null, SNODE);
        // `*`
      } else if (path.charCodeAt(i) === 42) {
        this.insert(method, path.substring(0, i), handler, ANODE);
      }
    }
    this.insert(method, path, handler, SNODE);
  };

  Router.prototype.insert = function insert(method, path, handler, has) {
    let cn = this.trees[method]; // Current node as root
    let search = path;

    while (true) {
      let sl = search.length;
      let pl = cn.prefix.length;
      let l = lcp(search, cn.prefix);

      if (l === 0) {
        // At root node
        cn.label = search[0];
        cn.prefix = search;
        cn.has = has;
        if (handler) {
          cn.handler = handler;
        }
        return;
      } else if (l < pl) {
        // Split the node
        let n = new Node(cn.prefix.substring(l), cn.has, cn.handler, cn.edges);
        cn.edges = [n]; // Add to parent

        // Reset parent node
        cn.label = cn.prefix[0];
        cn.prefix = cn.prefix.substring(0, l);
        cn.has = SNODE;
        cn.handler = null;

        if (l === sl) {
          // At parent node
          cn.handler = handler;
        } else {
          // Need to fork a node
          let n = new Node(search.substring(l), has, handler, null);
          cn.edges.push(n);
        }
        break;
      } else if (l < sl) {
        search = search.substring(l);
        let e = cn.findEdge(search[0]);
        if (e) {
          cn = e;
        } else {
          let n = new Node(search, has, handler, []);
          cn.edges.push(n);
          break;
        }
      } else {
        // Node already exists
        if (handler) {
          cn.handler = handler;
        }
        break;
      }
    }
  };

  Router.prototype.find = function find(method, path) {
    let cn = this.trees[method]; // Current node as root
    let search = path;
    let n = 0; // Param count
    let result = [null];
    let params = [];

    while (true) {
      if (search === '' || search === cn.prefix) {
        // Found
        result[0] = cn.handler;
        result[1] = params;
        return result;
      }

      let pl = cn.prefix.length;
      let l = lcp(search, cn.prefix);

      if (l === pl) {
        search = search.substring(l);
        switch (cn.has) {
          case PNODE:
            cn = cn.edges[0];
            var i = 0;
            l = search.length;
            // `/`
            for (; i < l && search.charCodeAt(i) !== 47; i++) {}

            params[n] = {
              name: cn.prefix.substring(1),
              value: search.substring(0, i)
            };
            n++;

            search = search.substring(i);

            if (i === l) {
              // All params read
              continue;
            }
            break;
          case ANODE:
            params[n] = {
              name: cn.prefix.substring(1),
              value: search.substring(0, i)
            };
            search = ''; // End search
            continue;
        }

        let e = cn.findEdge(search[0]);
        if (!e) {
          // Not found
          return result;
        }
        cn = e;
        continue;
      }
      return result;
    }
  };

  return Router;
})();

// Length of longest common prefix
function lcp(a, b) {
  var i = 0;
  let max = a.length;
  let l = b.length;
  if (l < max) {
    max = l;
  }
  for (; i < max && a.charCodeAt(i) === b.charCodeAt(i); i++) {}
  return i;
}

Router.Node = Node;

exports['default'] = Router;
module.exports = exports['default'];<|endoftext|>


<commit_before>(function() {

    var url = new URL(location.href);
    /**
     * This represents one oscillator of Kuramoto-Network.
     * @constructor
     */
    var Oscillator = function () {
        /**
         * References to coupled oscillators.
         * @type {Array.<Oscillator>} */
        this.coupled = [];
        this.omega = 0;
        this.nextTheta = 0;
        this.lastTheta = 0;
        this.step = 0;

        // 1st term
        // Value between 0 and 1.0 will be stored
        var times = parseInt(url.searchParams.get("gaussianLargeness"), 10);
        this.omega = gaussianRand(isNaN(times) ? 10 : times );
    };

    // Coefficient of 2nd term (K in Wikipedia)
    Oscillator.coeff = 1.0;

    Oscillator.prototype.addCoupledOscillator = function (oscilattor) {
        this.coupled.push(oscilattor);
    };

    Oscillator.prototype.calculateNextTheta = function () {

        // Calculates the 2nd term
        if (this.coupled.length < 1) {
            this.nextTheta = this.omega;
            return;
        }
        // Here is Kuramoto Model
        var sum = 0.0;
        for (var i = 0; i < this.coupled.length; i++) {
            sum += Math.sin(this.lastTheta - this.coupled[ i ].lastTheta);
        }
        this.nextTheta += this.omega - ((Oscillator.coeff / (this.coupled.length - 1)) * sum);
    };

    Oscillator.prototype.updateTheta = function () {
        this.lastTheta = this.nextTheta;
        this.step++;
    };

    Oscillator.prototype.getPhase = function () {
        return this.lastTheta;
    }

    /**
     * This class uses d3.js
     * @param {Array.<Array.<Number>>} data
     * @constructor
     */
    function LineGraph(data, orderParameters) {
        // Specifies the parent element this graph add to.
       this.container = d3.select("#debugLineGraphs");
       this.width = 960;
       this.height = 200;
       var margin = {};
       margin.top = margin.right = margin.bottom = margin.left = 30;
       this.margin = margin;
       this.data = data;
       this.orderParameters = orderParameters;
       this.x = d3.scaleLinear().range([0, this.width]);

       this.color = d3.scaleOrdinal(d3.schemeCategory10);
    }

    LineGraph.prototype.render = function() {
        var self = this;

        if (!self.svg) { // render first time
            self.y = d3.scaleLinear()
                .range([self.height, 0]);

            self.yOrderParam = d3.scaleLinear()
                .range([self.height, 0])
            self.yOrderParam.domain([0,1]);

            self.xAxis = d3.axisBottom()
                .scale(self.x);
            self.yAxis = d3.axisLeft()
                .scale(self.y);

            self.yAxis2 = d3.axisRight()
                .scale(self.yOrderParam);

            self.line = d3.line()
                .x(function(d, i) { return self.x(i); })
                .y(function(d) { return self.y(d); });
                // Really need this?
                //.interpolate("basis");

            self.orderParamLine = d3.line()
                .x(function(d, i) { /*console.log("x)d:" + d + ",i:" + i);*/ return self.x(i); })
                .y(function(d) { /*console.log("y)d:" + d);*/ return self.yOrderParam(d);});

            self.svg = self.container.append("svg")
                .attr("width", self.width + self.margin.left + self.margin.right)
                .attr("height", self.height + self.margin.top + self.margin.bottom)
                .append("g")
                .attr("transform", "translate(" + self.margin.left + "," + self.margin.top + ")");

            //self.x.domain(d3.extent(data, function(d) { return d.x; }));
            //self.y.domain(d3.extent(data, function(d) { return d.y; }));

            self.svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + self.height + ")")
                .call(self.xAxis);

            self.svg.append("g")
                .attr("class", "y axis")
                .call(self.yAxis);

            self.svg.append("g")
                .attr("class", "y axis2")
                .attr("transform", "translate(" + self.width + ",0)")
                .call(self.yAxis2);

            self.lines = self.svg.append("g")
                .attr("class", "lines");

            self.lines
                .selectAll("path.line")
                .data(self.data, function(ts, i) {return i;})
                .enter()
                .append("path")
                .attr("class", "line")
                .attr("stroke", "red")
                .attr("fill", "none")
                .attr("d", self.line);

            self.orderParameter = self.svg.append("g")
                .attr("class", "orderParameterLine");

            self.orderParameter
                .append("path")
                .data(self.orderParameters)
                .attr("fill", "none")
                .attr("stroke", "silver")
                .attr("d", self.orderParamLine);

        } else {
            // Resets the target domain (min and max values of each axis)
            self.x.domain([0, d3.max(self.data, function(d) {return d.length;})]);
            self.y.domain(d3.extent(d3.merge(self.data)));

            self.svg.select("g.y")
                .transition()
                .duration(100)
                .call(self.yAxis);

            self.svg.select("g.x")
                .transition()
                .duration(100)
                .call(self.xAxis);

            self.lines
                .selectAll("path.line")
                .data(self.data)
                .attr("d", self.line).style("stroke", function(d, i) {return self.color(i);});

            self.orderParameter
                .select("path")
                .attr("stroke", "black")
                .attr("d", self.orderParamLine(self.orderParameters));
        }
    };

    /**
     * Generate gaussian-distributed numbers with the Central number theorem.
     * @param {Number} times Integer representing how large numbers to add to simulate gaussian distribution.
     */
    function gaussianRand (times) {
        var rand = 0;
        for (var i = 1; i <= times; i++) {
            rand += Math.random();
        }
        return rand / times;
    }

    /**
     *
     * @constructor
     */
    function OrderParameterCell() {
        this.td = document.createElement("td");
        this.svg = d3.select(this.td).append("svg");
        this.text = document.createTextNode("");
        this.td.appendChild(this.text);
    }

    window.App = !(typeof window['App'] !== 'undefined') ? (function () {

        var oscillators = parseInt(url.searchParams.get("oscillators") ,10);
        var NUMBERS_OF_OSCILLATOR = isNaN(oscillators) ? 10 : oscillators;
        var STEPS_TO_REMEMBER = 50;
        var intervalTimer = null;

        return {
            init: function () {
                var oscillators = [];

                /**
                 * Stores old values of the oscillators.
                 * @type {Array.<Array.<Number>>}
                 * */
                var oscillatorValues = [
                    // Elements such below come here
                    // - Time series values (an array) of oscillator #1,
                    // - Time series values (an array) of oscillator #2,..
                ];
                var orderParameters = [];
                var orderParameterTable = document.getElementById("orderParameterTable");
                /* @type {Array.<Array.{Element(td)}>} */
                var orderParameterCells = [];

                // Set K
                var k = parseFloat(document.getElementById("k").value);
                if (Number.isNaN(k)) {
                    alert("K is NaN");
                    return;
                } else {
                    Oscillator.coeff = k;
                }

                var omegaDist = {0.0: 0, 0.1:0, 0.2:0, 0.3:0, 0.4: 0,
                    0.5: 0, 0.6:0, 0.7:0, 0.8:0, 0.9: 0};
                for (var i = 0; i < NUMBERS_OF_OSCILLATOR; i++) {
                    // Constructs an oscillator.
                    var oscillator = new Oscillator()
                    oscillators.push(oscillator);
                    // Constructs an oscillator value holder.
                    oscillatorValues.push([]);

                    // Appends a row of the order parameter table
                    var tr = document.createElement("tr");
                    var cells = [];
                    for (var k = 0; k < NUMBERS_OF_OSCILLATOR; k++) {
                        if (k === i) {
                            var td = document.createElement("td");
                            td.appendChild(document.createTextNode("Osc #" + i));
                            td.setAttribute("class", "diagonal");
                            tr.appendChild(td);
                            cells.push(td);
                        } else {
                            var cell = new OrderParameterCell();
                            tr.appendChild(cell.td);
                            cells.push(cell);
                        }
                    }
                    orderParameterTable.appendChild(tr);
                    orderParameterCells.push(cells);

                    omegaDist[oscillator.omega.toFixed(1)] += 1;
                }
                console.log("Omega distribution:");
                for (var key in omegaDist) {
                    console.log("[" + key + "]" + omegaDist[key]);
                }
                var lineGraph = new LineGraph(oscillatorValues, orderParameters);

                // Sets coupled oscillators
                for (var target = 0; target < oscillators.length; target++) {
                    //console.log("connecting #" + target + " to:");
                    for (i = 0; i < oscillators.length; i++) {
                        if (i === target) {
                            // Skips if the setting target and the oscillator to be set are same.
                            continue;
                        }
                        oscillators[target].addCoupledOscillator(oscillators[i]);
                        //console.log("\t#" + i);
                    }
                }

                // Sets up interval oscillator updates.
                var x = 0;
                intervalTimer = window.setInterval(function() {

                    for (var i = 0; i < oscillators.length; i++) {
                        oscillators[i].calculateNextTheta();
                    }

                    // Its absolute value will be taken when we calculate the order parameter.
                    var sum_of_euler_real = 0.0;
                    var sum_of_euler_imaginary = 0.0;
                    for (var i = 0; i < oscillators.length; i++) {
                        oscillators[i].updateTheta();

                        // Saves the value onto oscillatorValues.
                        if (oscillatorValues[i].length >= STEPS_TO_REMEMBER) {
                            // Removes the oldest value if the array exceeds the limit.
                            oscillatorValues[i].shift();
                        }
                        oscillatorValues[i].push(Math.sin(oscillators[i].lastTheta % (Math.PI * 2)));

                        // Updates the order parameter table.
                        for (var k = i + 1; k < oscillators.length; k++) {
                            // Calculates an order parameter just for the 2 oscillators.
                            var real = Math.cos(oscillators[i].getPhase()) + Math.cos(oscillators[k].getPhase());
                            var imaginary = Math.sin(oscillators[i].getPhase()) + Math.sin(oscillators[k].getPhase());
                            var partialOrderParameter = Math.sqrt(Math.pow(real, 2) + Math.pow(imaginary, 2)) / 2;

                            // Updates the target cell.
                            if (orderParameterCells[i][k] instanceof OrderParameterCell) {
                                orderParameterCells[i][k].text.textContent =  partialOrderParameter.toFixed(3);
                                // Updates: #FFFFFF
                                //             ^^^^ here, like if 0.0 -> FFFFFF, 1.0 -> FF0000
                                var blueOrGreen = Math.round((1 - partialOrderParameter) * 255).toString(16);
                                // Add leading zeros
                                blueOrGreen = ("00" + blueOrGreen).substr(-2);
                                orderParameterCells[i][k].td.style.backgroundColor = "#FF" +
                                    blueOrGreen + blueOrGreen;
                            }
                        }

                        // Calculates order parameter components for the whole system (all oscillators).
                        sum_of_euler_real += Math.cos(oscillators[i].getPhase());
                        sum_of_euler_imaginary += Math.sin(oscillators[i].getPhase());
                    }

                    if (orderParameters.length >= STEPS_TO_REMEMBER) {
                        // Removes the oldest value if the array exceeds the limit.
                        orderParameters.shift();
                    }
                    // Calculates the order parameter
                    var absoluteSum = Math.sqrt(Math.pow(sum_of_euler_real, 2) + Math.pow(sum_of_euler_imaginary, 2));
                    //console.log("m=" + (absoluteSum / oscillators.length));
                    orderParameters.push((absoluteSum / oscillators.length));

                    lineGraph.render();

                    x++;
                }, 300);

            },
            stop: function() {
                if (intervalTimer !== null)
                {
                    clearInterval(intervalTimer);
                }
            }
        };
    })() : window.app;

})();
<commit_msg>Simplify (remove an unnecessary member)<commit_after>(function() {

    var url = new URL(location.href);
    /**
     * This represents one oscillator of Kuramoto-Network.
     * @constructor
     */
    var Oscillator = function () {
        /**
         * References to coupled oscillators.
         * @type {Array.<Oscillator>} */
        this.coupled = [];
        this.omega = 0;
        this.nextTheta = 0;
        this.lastTheta = 0;
        this.step = 0;

        // 1st term
        // Value between 0 and 1.0 will be stored
        var times = parseInt(url.searchParams.get("gaussianLargeness"), 10);
        this.omega = gaussianRand(isNaN(times) ? 10 : times );
    };

    // Coefficient of 2nd term (K in Wikipedia)
    Oscillator.coeff = 1.0;

    Oscillator.prototype.addCoupledOscillator = function (oscilattor) {
        this.coupled.push(oscilattor);
    };

    Oscillator.prototype.calculateNextTheta = function () {

        // Calculates the 2nd term
        if (this.coupled.length < 1) {
            this.nextTheta = this.omega;
            return;
        }
        // Here is Kuramoto Model
        var sum = 0.0;
        for (var i = 0; i < this.coupled.length; i++) {
            sum += Math.sin(this.lastTheta - this.coupled[ i ].lastTheta);
        }
        this.nextTheta += this.omega - ((Oscillator.coeff / this.coupled.length) * sum);
    };

    Oscillator.prototype.updateTheta = function () {
        this.lastTheta = this.nextTheta;
        this.step++;
    };

    Oscillator.prototype.getPhase = function () {
        return this.lastTheta;
    }

    /**
     * This class uses d3.js
     * @param {Array.<Array.<Number>>} data
     * @constructor
     */
    function LineGraph(data, orderParameters) {
        // Specifies the parent element this graph add to.
       this.container = d3.select("#debugLineGraphs");
       this.width = 960;
       this.height = 200;
       var margin = {};
       margin.top = margin.right = margin.bottom = margin.left = 30;
       this.margin = margin;
       this.data = data;
       this.orderParameters = orderParameters;
       this.x = d3.scaleLinear().range([0, this.width]);

       this.color = d3.scaleOrdinal(d3.schemeCategory10);
    }

    LineGraph.prototype.render = function() {
        var self = this;

        if (!self.svg) { // render first time
            self.y = d3.scaleLinear()
                .range([self.height, 0]);

            self.yOrderParam = d3.scaleLinear()
                .range([self.height, 0])
            self.yOrderParam.domain([0,1]);

            self.xAxis = d3.axisBottom()
                .scale(self.x);
            self.yAxis = d3.axisLeft()
                .scale(self.y);

            self.yAxis2 = d3.axisRight()
                .scale(self.yOrderParam);

            self.line = d3.line()
                .x(function(d, i) { return self.x(i); })
                .y(function(d) { return self.y(d); });
                // Really need this?
                //.interpolate("basis");

            self.orderParamLine = d3.line()
                .x(function(d, i) { /*console.log("x)d:" + d + ",i:" + i);*/ return self.x(i); })
                .y(function(d) { /*console.log("y)d:" + d);*/ return self.yOrderParam(d);});

            self.svg = self.container.append("svg")
                .attr("width", self.width + self.margin.left + self.margin.right)
                .attr("height", self.height + self.margin.top + self.margin.bottom)
                .append("g")
                .attr("transform", "translate(" + self.margin.left + "," + self.margin.top + ")");

            //self.x.domain(d3.extent(data, function(d) { return d.x; }));
            //self.y.domain(d3.extent(data, function(d) { return d.y; }));

            self.svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + self.height + ")")
                .call(self.xAxis);

            self.svg.append("g")
                .attr("class", "y axis")
                .call(self.yAxis);

            self.svg.append("g")
                .attr("class", "y axis2")
                .attr("transform", "translate(" + self.width + ",0)")
                .call(self.yAxis2);

            self.lines = self.svg.append("g")
                .attr("class", "lines");

            self.lines
                .selectAll("path.line")
                .data(self.data, function(ts, i) {return i;})
                .enter()
                .append("path")
                .attr("class", "line")
                .attr("stroke", "red")
                .attr("fill", "none")
                .attr("d", self.line);

            self.orderParameter = self.svg.append("g")
                .attr("class", "orderParameterLine");

            self.orderParameter
                .append("path")
                .data(self.orderParameters)
                .attr("fill", "none")
                .attr("stroke", "silver")
                .attr("d", self.orderParamLine);

        } else {
            // Resets the target domain (min and max values of each axis)
            self.x.domain([0, d3.max(self.data, function(d) {return d.length;})]);
            self.y.domain(d3.extent(d3.merge(self.data)));

            self.svg.select("g.y")
                .transition()
                .duration(100)
                .call(self.yAxis);

            self.svg.select("g.x")
                .transition()
                .duration(100)
                .call(self.xAxis);

            self.lines
                .selectAll("path.line")
                .data(self.data)
                .attr("d", self.line).style("stroke", function(d, i) {return self.color(i);});

            self.orderParameter
                .select("path")
                .attr("stroke", "black")
                .attr("d", self.orderParamLine(self.orderParameters));
        }
    };

    /**
     * Generate gaussian-distributed numbers with the Central number theorem.
     * @param {Number} times Integer representing how large numbers to add to simulate gaussian distribution.
     */
    function gaussianRand (times) {
        var rand = 0;
        for (var i = 1; i <= times; i++) {
            rand += Math.random();
        }
        return rand / times;
    }

    /**
     *
     * @constructor
     */
    function OrderParameterCell() {
        this.td = document.createElement("td");
        this.svg = d3.select(this.td).append("svg");
        this.text = document.createTextNode("");
        this.td.appendChild(this.text);
    }

    window.App = !(typeof window['App'] !== 'undefined') ? (function () {

        var oscillators = parseInt(url.searchParams.get("oscillators") ,10);
        var NUMBERS_OF_OSCILLATOR = isNaN(oscillators) ? 10 : oscillators;
        var STEPS_TO_REMEMBER = 50;
        var intervalTimer = null;

        return {
            init: function () {
                var oscillators = [];

                /**
                 * Stores old values of the oscillators.
                 * @type {Array.<Array.<Number>>}
                 * */
                var oscillatorValues = [
                    // Elements such below come here
                    // - Time series values (an array) of oscillator #1,
                    // - Time series values (an array) of oscillator #2,..
                ];
                var orderParameters = [];
                var orderParameterTable = document.getElementById("orderParameterTable");
                /* @type {Array.<Array.{Element(td)}>} */
                var orderParameterCells = [];

                // Set K
                var k = parseFloat(document.getElementById("k").value);
                if (Number.isNaN(k)) {
                    alert("K is NaN");
                    return;
                } else {
                    Oscillator.coeff = k;
                }

                var omegaDist = {0.0: 0, 0.1:0, 0.2:0, 0.3:0, 0.4: 0,
                    0.5: 0, 0.6:0, 0.7:0, 0.8:0, 0.9: 0};
                for (var i = 0; i < NUMBERS_OF_OSCILLATOR; i++) {
                    // Constructs an oscillator.
                    var oscillator = new Oscillator()
                    oscillators.push(oscillator);
                    // Constructs an oscillator value holder.
                    oscillatorValues.push([]);

                    // Appends a row of the order parameter table
                    var tr = document.createElement("tr");
                    var cells = [];
                    for (var k = 0; k < NUMBERS_OF_OSCILLATOR; k++) {
                        if (k === i) {
                            var td = document.createElement("td");
                            td.appendChild(document.createTextNode("Osc #" + i));
                            td.setAttribute("class", "diagonal");
                            tr.appendChild(td);
                            cells.push(td);
                        } else {
                            var cell = new OrderParameterCell();
                            tr.appendChild(cell.td);
                            cells.push(cell);
                        }
                    }
                    orderParameterTable.appendChild(tr);
                    orderParameterCells.push(cells);

                    omegaDist[oscillator.omega.toFixed(1)] += 1;
                }
                console.log("Omega distribution:");
                for (var key in omegaDist) {
                    console.log("[" + key + "]" + omegaDist[key]);
                }
                var lineGraph = new LineGraph(oscillatorValues, orderParameters);

                // Sets coupled oscillators
                for (var target = 0; target < oscillators.length; target++) {
                    //console.log("connecting #" + target + " to:");
                    for (i = 0; i < oscillators.length; i++) {
                        if (i === target) {
                            // Skips if the setting target and the oscillator to be set are same.
                            continue;
                        }
                        oscillators[target].addCoupledOscillator(oscillators[i]);
                        //console.log("\t#" + i);
                    }
                }

                // Sets up interval oscillator updates.
                var x = 0;
                intervalTimer = window.setInterval(function() {

                    for (var i = 0; i < oscillators.length; i++) {
                        oscillators[i].calculateNextTheta();
                    }

                    // Its absolute value will be taken when we calculate the order parameter.
                    var sum_of_euler_real = 0.0;
                    var sum_of_euler_imaginary = 0.0;
                    for (var i = 0; i < oscillators.length; i++) {
                        oscillators[i].updateTheta();

                        // Saves the value onto oscillatorValues.
                        if (oscillatorValues[i].length >= STEPS_TO_REMEMBER) {
                            // Removes the oldest value if the array exceeds the limit.
                            oscillatorValues[i].shift();
                        }
                        oscillatorValues[i].push(Math.sin(oscillators[i].lastTheta % (Math.PI * 2)));

                        // Updates the order parameter table.
                        for (var k = i + 1; k < oscillators.length; k++) {
                            // Calculates an order parameter just for the 2 oscillators.
                            var real = Math.cos(oscillators[i].getPhase()) + Math.cos(oscillators[k].getPhase());
                            var imaginary = Math.sin(oscillators[i].getPhase()) + Math.sin(oscillators[k].getPhase());
                            var partialOrderParameter = Math.sqrt(Math.pow(real, 2) + Math.pow(imaginary, 2)) / 2;

                            // Updates the target cell.
                            if (orderParameterCells[i][k] instanceof OrderParameterCell) {
                                orderParameterCells[i][k].text.textContent =  partialOrderParameter.toFixed(3);
                                // Updates: #FFFFFF
                                //             ^^^^ here, like if 0.0 -> FFFFFF, 1.0 -> FF0000
                                var blueOrGreen = Math.round((1 - partialOrderParameter) * 255).toString(16);
                                // Add leading zeros
                                blueOrGreen = ("00" + blueOrGreen).substr(-2);
                                orderParameterCells[i][k].td.style.backgroundColor = "#FF" +
                                    blueOrGreen + blueOrGreen;
                            }
                        }

                        // Calculates order parameter components for the whole system (all oscillators).
                        sum_of_euler_real += Math.cos(oscillators[i].getPhase());
                        sum_of_euler_imaginary += Math.sin(oscillators[i].getPhase());
                    }

                    if (orderParameters.length >= STEPS_TO_REMEMBER) {
                        // Removes the oldest value if the array exceeds the limit.
                        orderParameters.shift();
                    }
                    // Calculates the order parameter
                    var absoluteSum = Math.sqrt(Math.pow(sum_of_euler_real, 2) + Math.pow(sum_of_euler_imaginary, 2));
                    //console.log("m=" + (absoluteSum / oscillators.length));
                    orderParameters.push((absoluteSum / oscillators.length));

                    lineGraph.render();

                    x++;
                }, 300);

            },
            stop: function() {
                if (intervalTimer !== null)
                {
                    clearInterval(intervalTimer);
                }
            }
        };
    })() : window.app;

})();
<|endoftext|>


<commit_before>var subscriptions = new SubsManager();

Router.configure({
    layoutTemplate: 'layout',
    loadingTemplate: 'loading',
    notFoundTemplate: 'notFound'
});

Router.route('/', {
    name: 'home',
    waitOn: function() {
        return subscriptions.subscribe('allMangasCover');
    },
    fastRender: true
});

Router.route('/ownedMangas', {
    name: 'ownedMangas',
    waitOn: function() {
        return subscriptions.subscribe('allOwnedMangas', Meteor.userId());
    }
});

Router.route('/missingMangas', {
    name: 'missingMangas',
    waitOn: function() {
        return subscriptions.subscribe('allMissingMangas', Meteor.userId());
    }
});

Router.route('/:mangasName/tome/:tomeNumber/:_id', {
    name: 'tomeDetails',
    waitOn: function() {
        return [subscriptions.subscribe('tomeDetails', this.params._id), subscriptions.subscribe('allTomes', Meteor.userId(), this.params.mangasName)];
    },
    data: function() {
        return Mangas.findOne(this.params._id);
    }
});

Router.route('/:author', {
    name: 'mangaka',
    waitOn: function() {
        return subscriptions.subscribe('mangaka', Meteor.userId(), this.params.author);
    }
});

Router.route('/admin/addCompleteMangas', {
    name: 'addCompleteMangas',
    waitOn: function() {
        return subscriptions.subscribe('allMangasData');
    }
});
<commit_msg>Remove a subscription<commit_after>var subscriptions = new SubsManager();

Router.configure({
    layoutTemplate: 'layout',
    loadingTemplate: 'loading',
    notFoundTemplate: 'notFound'
});

Router.route('/', {
    name: 'home',
    waitOn: function() {
        return subscriptions.subscribe('allMangasCover');
    },
    fastRender: true
});

Router.route('/ownedMangas', {
    name: 'ownedMangas',
    waitOn: function() {
        return subscriptions.subscribe('allOwnedMangas', Meteor.userId());
    }
});

Router.route('/missingMangas', {
    name: 'missingMangas',
    waitOn: function() {
        return subscriptions.subscribe('allMissingMangas', Meteor.userId());
    }
});

Router.route('/:mangasName/tome/:tomeNumber/:_id', {
    name: 'tomeDetails',
    waitOn: function() {
        return [subscriptions.subscribe('tomeDetails', this.params._id), subscriptions.subscribe('allTomes', Meteor.userId(), this.params.mangasName)];
    },
    data: function() {
        return Mangas.findOne(this.params._id);
    }
});

Router.route('/:author', {
    name: 'mangaka',
    waitOn: function() {
        return subscriptions.subscribe('mangaka', Meteor.userId(), this.params.author);
    }
});

Router.route('/admin/addCompleteMangas', {
    name: 'addCompleteMangas'
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

let ssdp = require('node-upnp-ssdp');
let Subscription = require('node-upnp-subscription');
let parsexmlresponse  = require('parsexmlresponse');
let http = require('http');
let url = require('url');
let mqtt = require('mqtt');
let async = require('async');
let winston = require('winston');
let devices = new Map();
let processed = new Set();
let subscriptionQueue = [];

let log = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({
            timestamp: function() {
                return new Date().toISOString();
            },
            formatter: function(options) {
                return options.timestamp() +' '+ options.level.toUpperCase() +' '+ (undefined !== options.message ? options.message : '') +
                    (options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' );
            }
        })
    ]
});

let program = require('commander');

program
    .version(require('./package.json').version)
    .option('-u, --url <url>', 'Set the URI of the broker [mqtt://localhost]')
    .parse(process.argv);

function kvToObject(arr) {
    return arr.reduce((memo, val) => {
        memo[Object.keys(val)[0]] = val[Object.keys(val)[0]];
        return memo;
    }, {});
}

function extractProperties(message) {
    let properties = message['body'] ? message['body'] : message;
    properties = properties['e:propertyset'] ? properties['e:propertyset']['e:property'] : properties;
    if (Array.isArray(properties)) {
        return kvToObject(properties);
    } else {
        return properties;
    }
}

function announceMessageFor(usn, sid) {
    let device = devices.get(usn);
    return (message) => {
        let service = device.subscriptions.get(sid);
        let msg = JSON.stringify(extractProperties(message));
        client.publish(`upnp/${device.description.UDN}/${service.serviceId}`, msg);
    };
}

function announceDiscovery(device) {
    let msg = JSON.stringify({
        available: true
    });
    client.publish(`upnp/${device.description.UDN}`, msg);
}

function announceByeBye(device) {
    let msg = JSON.stringify({
        available: false
    });
    client.publish(`upnp/${device.description.UDN}`, msg);
}

function subscribe(path, usn, callback) {
    let eventUrl = url.parse(path);
    let sub = new Subscription(eventUrl.hostname, eventUrl.port, eventUrl.path, 10);
    let deviceDescription = devices.get(usn).description;
    sub.on('error', callback);
    sub.on('subscribed', (data) => {
        if (!data.sid) {
            callback(new Error(`Received no sid for subscription to ${path}`));
        } else {
            sub.on('message', announceMessageFor(usn, data.sid));
            sub.once('error:resubscribe', (e) => {
                log.error(`Failed to resubscribe: ${deviceDescription.friendlyName} ${e.error}`);
                unsubscribe(sub, () => subscribe(path, usn, callback));
            });
            callback(null, {sid: data.sid, subscription: sub});
        }
    });
}

function subscribeAll(usn, services, callback) {
    async.eachSeries(services, (service, iterCallback) => {
        log.info(`Subscribing ${usn} (${service.serviceId})`);
        subscribe(service.path, usn, (err, data) => {
            if (err) {
                log.error(`Failed to setup subscription to ${service.path}`);
                iterCallback(err);
            } else {
                devices.get(usn).subscriptions.set(data.sid, { serviceId: service.serviceId, subscription: data.subscription });
                iterCallback();
            }
        });
    }, callback);
}

function unsubscribe(subscription, iterCallback) {
    log.info(`Unsubscribing ${sid} (${subscription.serviceId})`);
    let callbackInvoked = false;
    subscription.subscription.on('unsubscribed', (data) => {
        if (!callbackInvoked) {
            callbackInvoked = true;
            iterCallback();
        }
    });
    subscription.subscription.on('error:unsubscribe', (err) => {
        if (!callbackInvoked) {
            callbackInvoked = true;
            if (err) {
                log.error(err);
            } else {
                log.error(`Unknown error unsubscribing from ${sid} (${subscription.serviceId})`);
            }
            iterCallback();
        }
    });
    subscription.subscription.unsubscribe();
}

function unsubscribeAll(usn, callback) {
    let device = devices.get(usn);
    announceByeBye(device);
    devices.delete(usn);
    processed.delete(device.location);
    async.each(Array.from(device.subscriptions.keys()), (sid, iterCallback) => {
        let subscription = device.subscriptions.get(sid);
        unsubscribe(subscription, iterCallback);
    }, callback);
}

function unsubscribeAllSync(usn) {
    let device = devices.get(usn);
    for (let sid of device.subscriptions.keys()) {
        let subscription = device.subscriptions.get(sid);
        log.info(`Unsubscribing ${sid} (${subscription.serviceId})`);
        subscription.subscription.unsubscribe();
    }
}

function findServices(device, location) {
    let services = [];
    function addService(service) {
        if (service.eventSubURL) {
            let path = url.resolve(location, service.eventSubURL);
            let serviceId = service.serviceId;
            services.push({ serviceId, path });
        }
    }
    if (device.serviceList && device.serviceList.service) {
        if (Array.isArray(device.serviceList.service)) {
            for (let service of device.serviceList.service) {
                addService(service);
            }
        } else {
            addService(device.serviceList.service);
        }
    }
    return services;
}

function unprocess(usn, callback) {
    if (devices.has(usn)) {
        unsubscribeAll(usn, (err, data) => {
            if (err) {
                callback(err);
            } else {
                log.info(`Removing ${usn} from devices`);
                callback();
            }
        });
    } else {
        callback();
    }
}

function processDiscovery(discovery, callback) {
    if (!processed.has(discovery.location)) {
        processed.add(discovery.location);
        http.get(discovery.location, parsexmlresponse((err, data) => {
            if (err) {
                log.error(`${discovery.server}@${discovery.location} [${discovery.usn}]: ${err}`);
                processed.delete(discovery.location);
                callback(err);
            } else if (data) {
                if (data.root) {
                    devices.set(discovery.usn, { location: discovery.location, description: data.root.device, subscriptions: new Map() });
                    announceDiscovery(devices.get(discovery.usn));
                    let services = findServices(devices.get(discovery.usn).description, discovery.location, discovery.usn);
                    subscribeAll(discovery.usn, services, callback);
                } else {
                    log.error(new Error(`Failed to parse description of ${discovery.server} at ${discovery.location}`));
                    callback();
                }
            } else {
                log.error(new Error(`Failed to download description of ${discovery.server}: returned no data`));
                callback();
            }
        })).on('error', (err) => {
            log.error(`${discovery.server}@${discovery.location} [${discovery.usn}]: ${err}`);
            processed.delete(discovery.location);
            callback(err);
        });
    } else {
        callback();
    }
}

function processQueue() {
    let discoveredDevice = subscriptionQueue.shift();
    if (discoveredDevice) {
        processDiscovery(discoveredDevice, (err, data) => {
            if (err) {
                log.error(err);
                log.warn('Rolling back subscriptions');
                unprocess(discoveredDevice.usn, (err, data) => {
                    subscriptionQueue.push(discoveredDevice);
                    processQueue();
                });
            } else {
                processQueue();
            }
        });
    } else {
        setTimeout(processQueue, 1000);
    }
}

function unsubscribeAllDevices() {
    for(let usn of devices.keys()) {
        unsubscribeAllSync(usn);
    }
    process.exit();
}

function handleException(e) {
    log.error(e.stack);
    unsubscribeAllDevices();
}

process.title = 'upnp-sub-mqtt';

process.stdin.resume();//so the program will not close instantly

process.on('exit', unsubscribeAllDevices);
process.on('SIGINT', unsubscribeAllDevices);
process.on('uncaughtException', handleException);

ssdp.on('DeviceFound', (discovery) => {
    subscriptionQueue.push(discovery)
});
ssdp.on('DeviceAvailable', (discovery) => {
    subscriptionQueue.push(discovery)
});
ssdp.on('DeviceUpdate', (discovery) => {
    unprocess(discovery.usn, (err) => {
        if (err) {
            log.error(`Error unprocessing after device update ${discovery.usn}: ${err}`)
        }
    });
    processDiscovery(discovery, (err) => {
        if (err) {
            log.error(`Error processing ${discovery.usn}: ${err}`)
        }
    });
});
ssdp.on('DeviceUnavailable', (discovery) => {
    unprocess(discovery.usn, (err) => {
        if (err) {
            log.error(`Error unprocessing after device unavailable: ${discovery.usn}: ${err}`)
        }
    });
});

let client = mqtt.connect(program.url || process.env.MQTTHOST || 'mqtt://localhost');
log.info(`Connecting: ${client.options.href}`);

client.on('connect', (connack) => {
    log.info('Connected');
    if (!connack.sessionPresent) {
        setTimeout(processQueue, 1000);
        ssdp.mSearch();
    }
});

client.on('error', (err) => {
    log.error(`MQTT Client Error: ${err}`);
})
<commit_msg>Increased timeout from 10s to 5 minutes, fixed IoC issue<commit_after>#!/usr/bin/env node
"use strict";

let ssdp = require('node-upnp-ssdp');
let Subscription = require('node-upnp-subscription');
let parsexmlresponse  = require('parsexmlresponse');
let http = require('http');
let url = require('url');
let mqtt = require('mqtt');
let async = require('async');
let winston = require('winston');
let devices = new Map();
let processed = new Set();
let subscriptionQueue = [];

let log = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({
            timestamp: function() {
                return new Date().toISOString();
            },
            formatter: function(options) {
                return options.timestamp() +' '+ options.level.toUpperCase() +' '+ (undefined !== options.message ? options.message : '') +
                    (options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' );
            }
        })
    ]
});

let program = require('commander');

program
    .version(require('./package.json').version)
    .option('-u, --url <url>', 'Set the URI of the broker [mqtt://localhost]')
    .parse(process.argv);

function kvToObject(arr) {
    return arr.reduce((memo, val) => {
        memo[Object.keys(val)[0]] = val[Object.keys(val)[0]];
        return memo;
    }, {});
}

function extractProperties(message) {
    let properties = message['body'] ? message['body'] : message;
    properties = properties['e:propertyset'] ? properties['e:propertyset']['e:property'] : properties;
    if (Array.isArray(properties)) {
        return kvToObject(properties);
    } else {
        return properties;
    }
}

function announceMessageFor(usn, sid) {
    let device = devices.get(usn);
    return (message) => {
        let service = device.subscriptions.get(sid);
        let msg = JSON.stringify(extractProperties(message));
        client.publish(`upnp/${device.description.UDN}/${service.serviceId}`, msg);
    };
}

function announceDiscovery(device) {
    let msg = JSON.stringify({
        available: true
    });
    client.publish(`upnp/${device.description.UDN}`, msg);
}

function announceByeBye(device) {
    let msg = JSON.stringify({
        available: false
    });
    client.publish(`upnp/${device.description.UDN}`, msg);
}

function subscribe(path, usn, callback) {
    let eventUrl = url.parse(path);
    let sub = new Subscription(eventUrl.hostname, eventUrl.port, eventUrl.path, 600);
    let deviceDescription = devices.get(usn).description;
    sub.on('error', callback);
    sub.on('subscribed', (data) => {
        if (!data.sid) {
            callback(new Error(`Received no sid for subscription to ${path}`));
        } else {
            sub.on('message', announceMessageFor(usn, data.sid));
            sub.once('error:resubscribe', (e) => {
                log.error(`Failed to resubscribe: ${deviceDescription.friendlyName} ${e.error}`);
                unsubscribe(sub, () => subscribe(path, usn, callback));
            });
            callback(null, {sid: data.sid, subscription: sub});
        }
    });
}

function subscribeAll(usn, services, callback) {
    async.eachSeries(services, (service, iterCallback) => {
        log.info(`Subscribing ${usn} (${service.serviceId})`);
        subscribe(service.path, usn, (err, data) => {
            if (err) {
                log.error(`Failed to setup subscription to ${service.path}`);
                iterCallback(err);
            } else {
                devices.get(usn).subscriptions.set(data.sid, { serviceId: service.serviceId, subscription: data.subscription });
                iterCallback();
            }
        });
    }, callback);
}

function unsubscribe(subscription, iterCallback) {
    log.info(`Unsubscribing ${sid} (${subscription.serviceId})`);
    let callbackInvoked = false;
    subscription.subscription.on('unsubscribed', (data) => {
        if (!callbackInvoked) {
            callbackInvoked = true;
            iterCallback();
        }
    });
    subscription.subscription.on('error:unsubscribe', (err) => {
        if (!callbackInvoked) {
            callbackInvoked = true;
            if (err) {
                log.error(err);
            } else {
                log.error(`Unknown error unsubscribing from ${sid} (${subscription.serviceId})`);
            }
            iterCallback();
        }
    });
    subscription.subscription.unsubscribe();
}

function unsubscribeAll(usn, callback) {
    let device = devices.get(usn);
    announceByeBye(device);
    devices.delete(usn);
    processed.delete(device.location);
    async.each(Array.from(device.subscriptions.keys()), (sid, iterCallback) => {
        let subscription = device.subscriptions.get(sid);
        unsubscribe(subscription, iterCallback);
    }, callback);
}

function unsubscribeAllSync(usn) {
    let device = devices.get(usn);
    for (let sid of device.subscriptions.keys()) {
        let subscription = device.subscriptions.get(sid);
        log.info(`Unsubscribing ${sid} (${subscription.serviceId})`);
        subscription.subscription.unsubscribe();
    }
}

function findServices(device, location) {
    let services = [];
    function addService(service) {
        if (service.eventSubURL) {
            let path = url.resolve(location, service.eventSubURL);
            let serviceId = service.serviceId;
            services.push({ serviceId, path });
        }
    }
    if (device.serviceList && device.serviceList.service) {
        if (Array.isArray(device.serviceList.service)) {
            for (let service of device.serviceList.service) {
                addService(service);
            }
        } else {
            addService(device.serviceList.service);
        }
    }
    return services;
}

function unprocess(usn, callback) {
    if (devices.has(usn)) {
        unsubscribeAll(usn, (err, data) => {
            if (err) {
                callback(err);
            } else {
                log.info(`Removing ${usn} from devices`);
                callback();
            }
        });
    } else {
        callback();
    }
}

function processDiscovery(discovery, callback) {
    if (!processed.has(discovery.location)) {
        processed.add(discovery.location);
        http.get(discovery.location, parsexmlresponse((err, data) => {
            if (err) {
                log.error(`${discovery.server}@${discovery.location} [${discovery.usn}]: ${err}`);
                processed.delete(discovery.location);
                callback(err);
            } else if (data) {
                if (data.root) {
                    devices.set(discovery.usn, { location: discovery.location, description: data.root.device, subscriptions: new Map() });
                    announceDiscovery(devices.get(discovery.usn));
                    let services = findServices(devices.get(discovery.usn).description, discovery.location, discovery.usn);
                    subscribeAll(discovery.usn, services, callback);
                } else {
                    log.error(new Error(`Failed to parse description of ${discovery.server} at ${discovery.location}`));
                    callback();
                }
            } else {
                log.error(new Error(`Failed to download description of ${discovery.server}: returned no data`));
                callback();
            }
        })).on('error', (err) => {
            log.error(`${discovery.server}@${discovery.location} [${discovery.usn}]: ${err}`);
            processed.delete(discovery.location);
            callback(err);
        });
    } else {
        callback();
    }
}

function processQueue() {
    let discoveredDevice = subscriptionQueue.shift();
    if (discoveredDevice) {
        processDiscovery(discoveredDevice, (err, data) => {
            if (err) {
                log.error(err);
                log.warn('Rolling back subscriptions');
                unprocess(discoveredDevice.usn, (err, data) => {
                    setTimeout(() => subscriptionQueue.push(discoveredDevice), 60000);
                    processQueue();
                });
            } else {
                processQueue();
            }
        });
    } else {
        setTimeout(processQueue, 1000);
    }
}

function unsubscribeAllDevices() {
    for(let usn of devices.keys()) {
        unsubscribeAllSync(usn);
    }
    process.exit();
}

function handleException(e) {
    log.error(e.stack);
    unsubscribeAllDevices();
}

process.title = 'upnp-sub-mqtt';

process.stdin.resume();//so the program will not close instantly

process.on('exit', unsubscribeAllDevices);
process.on('SIGINT', unsubscribeAllDevices);
process.on('uncaughtException', handleException);

ssdp.on('DeviceFound', (discovery) => {
    subscriptionQueue.push(discovery)
});
ssdp.on('DeviceAvailable', (discovery) => {
    subscriptionQueue.push(discovery)
});
ssdp.on('DeviceUpdate', (discovery) => {
    unprocess(discovery.usn, (err) => {
        if (err) {
            log.error(`Error unprocessing after device update ${discovery.usn}: ${err}`)
        }
    });
    processDiscovery(discovery, (err) => {
        if (err) {
            log.error(`Error processing ${discovery.usn}: ${err}`)
        }
    });
});
ssdp.on('DeviceUnavailable', (discovery) => {
    unprocess(discovery.usn, (err) => {
        if (err) {
            log.error(`Error unprocessing after device unavailable: ${discovery.usn}: ${err}`)
        }
    });
});

let client = mqtt.connect(program.url || process.env.MQTTHOST || 'mqtt://localhost');
log.info(`Connecting: ${client.options.href}`);

client.on('connect', (connack) => {
    log.info('Connected');
    if (!connack.sessionPresent) {
        setTimeout(processQueue, 1000);
        ssdp.mSearch();
    }
});

client.on('error', (err) => {
    log.error(`MQTT Client Error: ${err}`);
})
<|endoftext|>


<commit_before>'use strict';

// ------------------------------------------------------------------------------------------ Dependencies

require('date-utils');
var _ = require('lodash');
var uuid = require('uuid');
var nconf = require('nconf');
var nstatic = require('node-static');
var validator = require('validator');
var youtransfer = require('./youtransfer');

// ------------------------------------------------------------------------------------------ Module Exposure

module.exports = function(options) {
	return new Router(options);
};

// ------------------------------------------------------------------------------------------ Module definition

function Router(options) {
	options = options || {};
	this.options = options;

	if(_.isString(this.options)) {
		this.fileServer = new nstatic.Server(this.options);
	} else if(_.isObject(this.options)) {
		this.fileServer = options.fileServer || new nstatic.Server('./dist');
	} else {
		throw 'Invalid options provided';
	}
}

Router.prototype.upload = function() {
	return function(req, res, next) {

		req.errors.register(new Error('An error occurred while uploading your file(s).'));
		var payload = req.files.payload || req.files['dz-payload'];
		var files = _.isArray(payload) ? payload : new Array(payload);

		var bundle = {
			id: req.params.bundle || uuid.v4(),
			files: []
		};

		var completed = _.after(files.length, function() {
			if(!req.errors.exist()) {
				youtransfer.bundle(bundle, function(err) {
					var response = {
						bundle: bundle
					};
					req.errors.parse(err);
					res.process('index.html', response, next);
				});
			} else {
				res.process('index.html', null, next);
			}
		});

		_.each(files, function(file) {
			youtransfer.upload(file, bundle, function(err, context) {
				if(!req.errors.exist()) {
					req.errors.parse(err);
					bundle.files.push(context);
				}
				completed();
			});
		});
	};
};

Router.prototype.uploadBundle = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An error occurred while uploading your file(s)'));

		try {
			var bundle = JSON.parse(req.params.bundle);
			youtransfer.bundle(bundle, function(err) {
				req.errors.parse(err);
				res.process('index.html', null, next);
			});
		} catch (err) {
			req.errors.parse(err);
			res.process('index.html', null, next);
		}
	};
};

Router.prototype.send = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An error occurred while sending your message'));
		youtransfer.send(req, res, function(err) {
			req.errors.parse(err);
			res.process('index.html', null, next);
		});
	};
};

Router.prototype.download = function() {
	return function(req, res, next) {

		req.errors.register([
			{
				code: 'ENOENT',
				message: 'Oh no... there is no file or archive to match this token! Are you sure you\'ve entered the right one?',
				html: 'Oh no... there is no file or archive to match this token!
Are you sure you\'ve entered the right one?'
			},
			{
				message: 'Oh my... something went terribly wrong!',
			}
		]);

		var token = req.params.token;
		var callback = function(err) {
			req.errors.parse(err);
			res.process('download.html', null, next);
		};

		if(validator.isUUID(token)) {
			youtransfer.archive(token, res, callback);
		} else {
			youtransfer.download(token, res, callback);
		}

	};
};

Router.prototype.settingsRedirect = function() {
	return function(req, res) {
		res.redirect('/settings/general');
	};
};

Router.prototype.settingsFinalise = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An unknown error occurred while finalising the settings. Please try again.'));

		var code = req.params.settings.state.unlockCode;
		youtransfer.settings.finalise(code, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('settings.finalise.html', null, next);
			} else {
				res.redirect('/');
				next();
			}
		});
	};
};

Router.prototype.settingsUnlock = function() {
	return function(req, res, next) {
		req.errors.register([
			new Error('An unknown error occurred while unlocking the settings'),
			{
				code: 'INVALID_CODE',
				message: 'The unlock code is invalid. Please try again',
			}
		]);

		var code = req.params.unlockCode;
		youtransfer.settings.unlock(code, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('unlock.html', null, next);
			} else {
				res.redirect('/');
				next();
			}
		});
	};
};

//TODO: this method only provides JSON output, which will not work with noscript browsers
Router.prototype.settingsGetTemplateByName = function() {
	return function(req, res, next) {

		req.errors.register([
			new Error('An error occurred while trying to retrieve the template'),
			{
				code: 'ENOENT',
				message: 'An invalid template has been selected. Please try again.',
			},
			{
				code: 'SETTINGS_FINALISED',
				message: 'The settings are currently locked. Please unlock them if you wish to make changes.',
				html: 'The settings are currently locked. Please unlock them if you wish to make changes.'
			}
		]);

		var template = req.params.template;
		youtransfer.templates.get(template, function(err, data) {
			if(err) {
				req.errors.parse(err);
				res.process('settings.template.html', null, next);
			} else {
				res.on('end', next);
				res.setHeader('Content-Type', 'text/html');
				res.setHeader('Cache-Control', 'private, max-age=0, proxy-revalidate, no-store, no-cache, must-revalidate');
				res.send(data);
				res.end();
			}
		});
	};
};

Router.prototype.settingsSaveTemplate = function() {
	var self = this;
	return function(req, res, next) {

		req.errors.register([
			new Error('An error occurred while trying to save the template'),
			{
				code: 'ENOENT',
				message: 'An invalid template has been selected. Please try again.',
			},
			{
				code: 'SETTINGS_FINALISED',
				message: 'The settings are currently locked. Please unlock them if you wish to make changes.',
				html: 'The settings are currently locked. Please unlock them if you wish to make changes.'
			}
		]);

		var template = req.params.template;
		var content = req.params.body;
		youtransfer.templates.push(template, content, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('settings.template.html', null, next);
			} else {
				self.settingsGetByName()(req, res, next);
			}
		});
	};
};

Router.prototype.settingsGetByName = function() {
	return function(req, res, next) {

		req.errors.register(new Error('An unknown error occurred while retrieving the settings'));

		var page = req.params.name || 'general';
		youtransfer.settings.get(function(err, settings) {
			req.errors.parse(err);

			var context = {
				activeTab: page
			};

			if(page === 'dropzone') {
				context.dropzone = settings.dropzone || {};
			}

			if(settings.state.finalised) {
				res.process('404.html', context, next);
			} else {
				res.process('settings.' + page + '.html', context, next);
			}
		});
	};
};

Router.prototype.settingsSaveByName = function() {
	var self = this;
	return function(req, res, next) {

		if(req.params.name === 'template') {
			self.settingsSaveTemplate()(req, res, next);
		} else {

			req.errors.register([
				new Error('An unknown error occurred while saving the settings'),
				{
					code: 'SETTINGS_FINALISED',
					message: 'The settings are currently locked. Please unlock them prior to making changes.',
					html: 'The settings are currently locked. Please unlock them prior to making changes.'
				}
			]);

			var value = req.params.settings;
			youtransfer.settings.push(value, function(err) {
				req.errors.parse(err);
				self.settingsGetByName()(req, res, next);
			});
		}
	};
};

Router.prototype.signout = function() {
	return function(req, res) {
		req.logout();
		res.redirect('/');
	};
};

Router.prototype.staticFiles = function() {
	var self = this;
	return function(req, res) {
		self.fileServer.serveFile('/' + req.params[1] + '/' + req.params[2], 200, { server: 'youtransfer.io', 'Cache-Control': 'max-age=' + nconf.get('CACHE_MAX_AGE') }, req, res);
	};
};

Router.prototype.default = function() {
	return function(req, res, next) {
		var page = req.params[0] || 'index';
		res.setHeader('Cache-Control', 'private, max-age=0, proxy-revalidate, no-store, no-cache, must-revalidate');
		res.process(page + '.html', null, next);
	};
};
<commit_msg>fixes #105 : Add ACL with login screen - Fixing code climate issues<commit_after>'use strict';

// ------------------------------------------------------------------------------------------ Dependencies

require('date-utils');
var _ = require('lodash');
var uuid = require('uuid');
var nconf = require('nconf');
var nstatic = require('node-static');
var validator = require('validator');
var youtransfer = require('./youtransfer');

// ------------------------------------------------------------------------------------------ Module Exposure

module.exports = function(options) {
	return new Router(options);
};

// ------------------------------------------------------------------------------------------ Module definition

function Router(options) {
	options = options || {};
	this.options = options;

	if(_.isString(this.options)) {
		this.fileServer = new nstatic.Server(this.options);
	} else if(_.isObject(this.options)) {
		this.fileServer = options.fileServer || new nstatic.Server('./dist');
	} else {
		throw 'Invalid options provided';
	}
}

Router.prototype.upload = function() {
	return function(req, res, next) {

		req.errors.register(new Error('An error occurred while uploading your file(s).'));
		var payload = req.files.payload || req.files['dz-payload'];
		var files = _.isArray(payload) ? payload : new Array(payload);

		var bundle = {
			id: req.params.bundle || uuid.v4(),
			files: []
		};

		var completed = _.after(files.length, function() {
			if(!req.errors.exist()) {
				youtransfer.bundle(bundle, function(err) {
					var response = {
						bundle: bundle
					};
					req.errors.parse(err);
					res.process('index.html', response, next);
				});
			} else {
				res.process('index.html', null, next);
			}
		});

		_.each(files, function(file) {
			youtransfer.upload(file, bundle, function(err, context) {
				if(!req.errors.exist()) {
					req.errors.parse(err);
					bundle.files.push(context);
				}
				completed();
			});
		});
	};
};

Router.prototype.uploadBundle = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An error occurred while uploading your file(s)'));

		try {
			var bundle = JSON.parse(req.params.bundle);
			youtransfer.bundle(bundle, function(err) {
				req.errors.parse(err);
				res.process('index.html', null, next);
			});
		} catch (err) {
			req.errors.parse(err);
			res.process('index.html', null, next);
		}
	};
};

Router.prototype.send = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An error occurred while sending your message'));
		youtransfer.send(req, res, function(err) {
			req.errors.parse(err);
			res.process('index.html', null, next);
		});
	};
};

Router.prototype.download = function() {
	return function(req, res, next) {

		req.errors.register([
			{
				code: 'ENOENT',
				message: 'Oh no... there is no file or archive to match this token! Are you sure you\'ve entered the right one?',
				html: 'Oh no... there is no file or archive to match this token!
Are you sure you\'ve entered the right one?'
			},
			{
				message: 'Oh my... something went terribly wrong!',
			}
		]);

		var token = req.params.token;
		var callback = function(err) {
			req.errors.parse(err);
			res.process('download.html', null, next);
		};

		if(validator.isUUID(token)) {
			youtransfer.archive(token, res, callback);
		} else {
			youtransfer.download(token, res, callback);
		}

	};
};

Router.prototype.settingsRedirect = function() {
	return function(req, res) {
		res.redirect('/settings/general');
	};
};

Router.prototype.settingsFinalise = function() {
	return function(req, res, next) {
		req.errors.register(new Error('An unknown error occurred while finalising the settings. Please try again.'));

		youtransfer.settings.finalise(req.params.settings.state.unlockCode, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('settings.finalise.html', null, next);
			} else {
				res.redirect('/');
				next();
			}
		});
	};
};

Router.prototype.settingsUnlock = function() {
	return function(req, res, next) {
		req.errors.register([
			new Error('An unknown error occurred while unlocking the settings'),
			{
				code: 'INVALID_CODE',
				message: 'The unlock code is invalid. Please try again',
			}
		]);

		youtransfer.settings.unlock(req.params.unlockCode, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('unlock.html', null, next);
			} else {
				res.redirect('/');
				next();
			}
		});
	};
};

//TODO: this method only provides JSON output, which will not work with noscript browsers
Router.prototype.settingsGetTemplateByName = function() {
	return function(req, res, next) {

		req.errors.register([
			new Error('An error occurred while trying to retrieve the template'),
			{
				code: 'ENOENT',
				message: 'An invalid template has been selected. Please try again.',
			},
			{
				code: 'SETTINGS_FINALISED',
				message: 'The settings are currently locked. Please unlock them if you wish to make changes.',
				html: 'The settings are currently locked. Please unlock them if you wish to make changes.'
			}
		]);

		var template = req.params.template;
		youtransfer.templates.get(template, function(err, data) {
			if(err) {
				req.errors.parse(err);
				res.process('settings.template.html', null, next);
			} else {
				res.on('end', next);
				res.setHeader('Content-Type', 'text/html');
				res.setHeader('Cache-Control', 'private, max-age=0, proxy-revalidate, no-store, no-cache, must-revalidate');
				res.send(data);
				res.end();
			}
		});
	};
};

Router.prototype.settingsSaveTemplate = function() {
	var self = this;
	return function(req, res, next) {

		req.errors.register([
			new Error('An error occurred while trying to save the template'),
			{
				code: 'ENOENT',
				message: 'An invalid template has been selected. Please try again.',
			},
			{
				code: 'SETTINGS_FINALISED',
				message: 'The settings are currently locked. Please unlock them if you wish to make changes.',
				html: 'The settings are currently locked. Please unlock them if you wish to make changes.'
			}
		]);

		var template = req.params.template;
		var content = req.params.body;
		youtransfer.templates.push(template, content, function(err) {
			req.errors.parse(err);
			if(req.errors.exist()) {
				res.process('settings.template.html', null, next);
			} else {
				self.settingsGetByName()(req, res, next);
			}
		});
	};
};

Router.prototype.settingsGetByName = function() {
	return function(req, res, next) {

		req.errors.register(new Error('An unknown error occurred while retrieving the settings'));

		var page = req.params.name || 'general';
		youtransfer.settings.get(function(err, settings) {
			req.errors.parse(err);

			var context = {
				activeTab: page
			};

			if(page === 'dropzone') {
				context.dropzone = settings.dropzone || {};
			}

			if(settings.state.finalised) {
				res.process('404.html', context, next);
			} else {
				res.process('settings.' + page + '.html', context, next);
			}
		});
	};
};

Router.prototype.settingsSaveByName = function() {
	var self = this;
	return function(req, res, next) {

		if(req.params.name === 'template') {
			self.settingsSaveTemplate()(req, res, next);
		} else {

			req.errors.register([
				new Error('An unknown error occurred while saving the settings'),
				{
					code: 'SETTINGS_FINALISED',
					message: 'The settings are currently locked. Please unlock them prior to making changes.',
					html: 'The settings are currently locked. Please unlock them prior to making changes.'
				}
			]);

			var value = req.params.settings;
			youtransfer.settings.push(value, function(err) {
				req.errors.parse(err);
				self.settingsGetByName()(req, res, next);
			});
		}
	};
};

Router.prototype.signout = function() {
	return function(req, res) {
		req.logout();
		res.redirect('/');
	};
};

Router.prototype.staticFiles = function() {
	var self = this;
	return function(req, res) {
		self.fileServer.serveFile('/' + req.params[1] + '/' + req.params[2], 200, { server: 'youtransfer.io', 'Cache-Control': 'max-age=' + nconf.get('CACHE_MAX_AGE') }, req, res);
	};
};

Router.prototype.default = function() {
	return function(req, res, next) {
		var page = req.params[0] || 'index';
		res.setHeader('Cache-Control', 'private, max-age=0, proxy-revalidate, no-store, no-cache, must-revalidate');
		res.process(page + '.html', null, next);
	};
};
<|endoftext|>


<commit_before>'use strict'

const { Router } = require('express')

const { wrap, urlencodedParser, markdownParser } = require('./utils')

// load controller
const indexController = require('./homepage')
const errorPageController = require('./errorPage')
const statusController = require('./status')
const historyController = require('./history')
const userController = require('./user')
const noteController = require('./note')
const response = require('./response')
const appRouter = Router()

// register route

// get index
appRouter.get('/', wrap(indexController.showIndex))

// ----- error page -----
// get 403 forbidden
appRouter.get('/403', errorPageController.errorForbidden)
// get 404 not found
appRouter.get('/404', errorPageController.errorNotFound)
// get 500 internal error
appRouter.get('/500', errorPageController.errorInternalError)

appRouter.get('/config', statusController.getConfig)

// register auth module
appRouter.use(require('./auth'))

// get history
appRouter.get('/history', historyController.historyGet)
// post history
appRouter.post('/history', urlencodedParser, historyController.historyPost)
// post history by note id
appRouter.post('/history/:noteId', urlencodedParser, historyController.historyPost)
// delete history
appRouter.delete('/history', historyController.historyDelete)
// delete history by note id
appRouter.delete('/history/:noteId', historyController.historyDelete)

// user
// get me info
appRouter.get('/me', wrap(userController.getMe))

// delete the currently authenticated user
appRouter.get('/me/delete/:token?', wrap(userController.deleteUser))

// export the data of the authenticated user
appRouter.get('/me/export', userController.exportMyData)

appRouter.get('/user/:username/avatar.svg', userController.getMyAvatar)

// register image upload module
appRouter.use(require('./imageRouter'))

// get new note
appRouter.get('/new', response.newNote)
// post new note with content
appRouter.post('/new', markdownParser, response.newNote)
// get publish note
appRouter.get('/s/:shortid', noteController.showPublishNote)
// publish note actions
appRouter.get('/s/:shortid/:action', response.publishNoteActions)
// get publish slide
appRouter.get('/p/:shortid', response.showPublishSlide)
// publish slide actions
appRouter.get('/p/:shortid/:action', response.publishSlideActions)
// gey my note list
appRouter.get('/myNotes', noteController.listMyNotes)
// get note by id
appRouter.get('/:noteId', wrap(noteController.showNote))
// note actions
appRouter.get('/:noteId/:action', noteController.noteActions)
// note actions with action id
appRouter.get('/:noteId/:action/:actionId', noteController.noteActions)

exports.router = appRouter
<commit_msg>Update route of list-my-notes api<commit_after>'use strict'

const { Router } = require('express')

const { wrap, urlencodedParser, markdownParser } = require('./utils')

// load controller
const indexController = require('./homepage')
const errorPageController = require('./errorPage')
const statusController = require('./status')
const historyController = require('./history')
const userController = require('./user')
const noteController = require('./note')
const response = require('./response')
const appRouter = Router()

// register route

// get index
appRouter.get('/', wrap(indexController.showIndex))

// ----- error page -----
// get 403 forbidden
appRouter.get('/403', errorPageController.errorForbidden)
// get 404 not found
appRouter.get('/404', errorPageController.errorNotFound)
// get 500 internal error
appRouter.get('/500', errorPageController.errorInternalError)

appRouter.get('/config', statusController.getConfig)

// register auth module
appRouter.use(require('./auth'))

// get history
appRouter.get('/history', historyController.historyGet)
// post history
appRouter.post('/history', urlencodedParser, historyController.historyPost)
// post history by note id
appRouter.post('/history/:noteId', urlencodedParser, historyController.historyPost)
// delete history
appRouter.delete('/history', historyController.historyDelete)
// delete history by note id
appRouter.delete('/history/:noteId', historyController.historyDelete)

// user
// get me info
appRouter.get('/me', wrap(userController.getMe))

// delete the currently authenticated user
appRouter.get('/me/delete/:token?', wrap(userController.deleteUser))

// export the data of the authenticated user
appRouter.get('/me/export', userController.exportMyData)

appRouter.get('/user/:username/avatar.svg', userController.getMyAvatar)

// register image upload module
appRouter.use(require('./imageRouter'))

// get new note
appRouter.get('/new', response.newNote)
// post new note with content
appRouter.post('/new', markdownParser, response.newNote)
// get publish note
appRouter.get('/s/:shortid', noteController.showPublishNote)
// publish note actions
appRouter.get('/s/:shortid/:action', response.publishNoteActions)
// get publish slide
appRouter.get('/p/:shortid', response.showPublishSlide)
// publish slide actions
appRouter.get('/p/:shortid/:action', response.publishSlideActions)
// gey my note list
appRouter.get('/api/notes/myNotes', noteController.listMyNotes)
// get note by id
appRouter.get('/:noteId', wrap(noteController.showNote))
// note actions
appRouter.get('/:noteId/:action', noteController.noteActions)
// note actions with action id
appRouter.get('/:noteId/:action/:actionId', noteController.noteActions)

exports.router = appRouter
<|endoftext|>


<commit_before>var fs = require('fs'),
    express = require('express'),
    bodyParser = require('body-parser'),
    app = express(),
    configFile = __dirname + '/config/modules.json',
    appPort = 8080

//
//  Express Configurations
//
//  app.disable('x-powered-by')
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

//
//  Load Routes/Modules
//
function modLoader(configFile) {
    modules = JSON.parse(fs.readFileSync(configFile))
    for (var key in modules) {
        console.log("Loading Module => " + key)
        app.use('/' + key, require('./routes/' + key))
    }
}
modLoader(configFile)

fs.watchFile(configFile, function(curr, prev) {
    if (prev.mtime.toString() !== curr.mtime.toString()) {
        modLoader(configFile)
    }
});

//
//  Get Mavigation
//
function getNav() {
    navString = '[ / ] '
    nav = JSON.parse(fs.readFileSync(configFile))
    for (var key in nav) {
        navString += "[ " + nav[key] + " ] "
    }
    return navString
}

//
//  Simple Template Engine
//
var debugString = ' -- undefined -- '
app.engine('shtml', function(filePath, options, callback) {
    fs.readFile(filePath, function(err, content) {
        if (err) return callback(new Error(err))
        var rendered = content.toString()
            .replace(/#navigation#/g, getNav() || debugString)
            .replace(/#title#/g, options.title || debugString)
            .replace(/#content#/g, options.content || debugString)
            .replace(/#code#/g, options.code || debugString)
            .replace(/#status#/g, options.status || debugString)
            .replace(/#message#/g, options.message || debugString)
            .replace(/#error#/g, options.error || debugString)
        return callback(null, rendered)
    })
})
app.set('views', './views')
app.set('view engine', 'shtml')

//
//  Routes
//
app.use('/', require('./routes/index'))

//
//  Catch 404 and forward to Error Handler
//
app.use(function(req, res, next) {
    var err = new Error('Not Found')
    err.status = 404
    next(err)
})

//
//  Error Handler
//
app.use(function(err, req, res, next) {
    res.status(err.status || 500)
    res.render('error', { status: err.status || 500, message: err, error: err.stack })
});

//
//  Start Server
//
app.listen(appPort, function() {
    console.log("INFO:", new Date(), ": Listening on port " + appPort)
})<commit_msg>Added CORS for APIs<commit_after>var fs = require('fs'),
    express = require('express'),
    bodyParser = require('body-parser'),
    app = express(),
    configFile = __dirname + '/config/modules.json',
    appPort = 8080

//
//  Express Configurations
//
//  app.disable('x-powered-by')
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
//
//  CORS for APIs
//
CORS = function (req,res,next) {
    res.header("X-Powered-By","NodeJS")
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Credentials', true)
    res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
    res.header('Access-Control-Allow-Headers', 'Content-Type, Api-Key, User')
    next()
}
app.use(CORS)

//
//  Load Routes/Modules
//
function modLoader(configFile) {
    modules = JSON.parse(fs.readFileSync(configFile))
    for (var key in modules) {
        console.log("Loading Module => " + key)
        app.use('/' + key, require('./routes/' + key))
    }
}
modLoader(configFile)

fs.watchFile(configFile, function(curr, prev) {
    if (prev.mtime.toString() !== curr.mtime.toString()) {
        modLoader(configFile)
    }
});

//
//  Get Mavigation
//
function getNav() {
    navString = '[ / ] '
    nav = JSON.parse(fs.readFileSync(configFile))
    for (var key in nav) {
        navString += "[ " + nav[key] + " ] "
    }
    return navString
}

//
//  Simple Template Engine
//
var debugString = ' -- undefined -- '
app.engine('shtml', function(filePath, options, callback) {
    fs.readFile(filePath, function(err, content) {
        if (err) return callback(new Error(err))
        var rendered = content.toString()
            .replace(/#navigation#/g, getNav() || debugString)
            .replace(/#title#/g, options.title || debugString)
            .replace(/#content#/g, options.content || debugString)
            .replace(/#code#/g, options.code || debugString)
            .replace(/#status#/g, options.status || debugString)
            .replace(/#message#/g, options.message || debugString)
            .replace(/#error#/g, options.error || debugString)
        return callback(null, rendered)
    })
})
app.set('views', './views')
app.set('view engine', 'shtml')

//
//  Routes
//
app.use('/', require('./routes/index'))

//
//  Catch 404 and forward to Error Handler
//
app.use(function(req, res, next) {
    var err = new Error('Not Found')
    err.status = 404
    next(err)
})

//
//  Error Handler
//
app.use(function(err, req, res, next) {
    res.status(err.status || 500)
    res.render('error', { status: err.status || 500, message: err, error: err.stack })
});

//
//  Start Server
//
app.listen(appPort, function() {
    console.log("INFO:", new Date(), ": Listening on port " + appPort)
})
<|endoftext|>


<commit_before>var router = require('routes')()

function route (str, f) { router.addRoute(str, f) }

route('GET /api/(0.6)?/capabilities', require('../handlers/misc_capabilities.js'))
route('GET /api/0.6/map?*', require('../handlers/misc_map.js'))
route('PUT /api/0.6/:type(changeset)/create', require('../handlers/changeset_create.js'))
route('POST /api/0.6/changeset/:id/upload', require('../handlers/changeset_upload.js'))
route('GET /api/0.6/changeset/:id/download', require('../handlers/changeset_download.js'))
route('PUT /api/0.6/changeset/:id/close', require('../handlers/changeset_close.js'))
route('PUT /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_create.js'))
route('GET /api/0.6/:type(node|way|relation)/:id/history', require('../handlers/element_history.js'))
route('GET /api/0.6/:type(node|way|relation)/:id/:version', require('../handlers/element_version.js'))
route('GET /api/0.6/:type(nodes|ways|relations)\\?:ktype=:ids', require('../handlers/element_multi_fetch.js'))
route('GET /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_read.js'))
route('DELETE /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_delete'))

module.exports = router
<commit_msg>Fix route for capabilities<commit_after>var router = require('routes')()

function route (str, f) { router.addRoute(str, f) }

route('GET /api(/0.6)?/capabilities', require('../handlers/misc_capabilities.js'))
route('GET /api/0.6/map?*', require('../handlers/misc_map.js'))
route('PUT /api/0.6/:type(changeset)/create', require('../handlers/changeset_create.js'))
route('POST /api/0.6/changeset/:id/upload', require('../handlers/changeset_upload.js'))
route('GET /api/0.6/changeset/:id/download', require('../handlers/changeset_download.js'))
route('PUT /api/0.6/changeset/:id/close', require('../handlers/changeset_close.js'))
route('PUT /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_create.js'))
route('GET /api/0.6/:type(node|way|relation)/:id/history', require('../handlers/element_history.js'))
route('GET /api/0.6/:type(node|way|relation)/:id/:version', require('../handlers/element_version.js'))
route('GET /api/0.6/:type(nodes|ways|relations)\\?:ktype=:ids', require('../handlers/element_multi_fetch.js'))
route('GET /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_read.js'))
route('DELETE /api/0.6/:type(node|way|relation)/:id', require('../handlers/element_delete'))

module.exports = router
<|endoftext|>