<commit_before>angular.module('pcApp.metrics.directives.formula', ['pcApp.indicators.services.indicator'])

    .directive('pcFormulaEditor', [function(){
        /** Implements basic equation editor inside an element.
         *
         * This code basically implements the editor reqlying on jQuery or
         * jqlite (angular). The formula is presented as a series of s.
         * There are text-s and variable-s. Texts are content
         * editable, while variables are added via the addVariable element.
         * Every variable element is surrunded by two text elements.
         *
         * If you are asked to maintain this: RUN!!
         */
        return {
            restirct: 'A',
            scope: {
                formula: '=',
                variables: '='
            },
            link: function ($scope, element, attrs) {
                $scope.formula = $scope.formula || '';
                $scope.variables = $scope.variables || {};

                var setCursor = function (element, atEnd) {
                    /** Set cursor to the given jq-element (or its first textnode child). */
                    var selection = window.getSelection();
                    var range = document.createRange();
                    var position;

                    if (atEnd) {
                        position = element.text().length;
                    } else {
                        position = 0;
                    }

                    var target = element[0];
                    // if target as an elment and has a text child select that one instead
                    if (target.hasChildNodes() && target.childNodes[0].nodeType === 3) {
                        target = target.childNodes[0];
                    }

                    range.setStart(target, position);
                    range.setEnd(target, position);
                    selection.removeAllRanges();
                    selection.addRange(range);
                };

                /** Translate a group of text and  node into a formula string. */
                var childNodesToFormula = function(childNodes) {
                    var result = [];
                    angular.forEach(childNodes, function (node) {
                        if (node.dataset.variable){
                            result.push(node.dataset.variable);
                        } else {
                            result.push(node.textContent);
                        }
                    });
                    return result.join(' ');
                };

                /** Translate a fromula string into a list of text and  nodes. */
                var formulaToChildNodes = function (formula, variables) {
                    var parts = formula.split(/(__\d+__)/g);
                    var result = [];
                    angular.forEach(parts, function (variableOrText) {
                        var node;
                        if  (!variableOrText) {
                            return;
                        }

                        var isVariable = variableOrText.match(/^__\d+__$/);
                        if (isVariable) {
                            var variable = variableOrText;
                            var node = createVariableNode(variable, variables[variable]);
                        } else {
                            var text = variableOrText;
                            var node = createTextNode(text);
                        }
                        this.push(node);
                    }, result);
                    result.push(createTextNode());
                    return result;
                };

                var createTextNode = function(text) {
                    var span = angular.element('');
                    span.attr('contenteditable', true);
                    span.text(text);
                    span.addClass('text-formula');

                    span.bind('keydown', function(event) {
                        var selection = window.getSelection();
                        var deleteNode, text;
                        if (event.keyCode === 46 && selection.anchorOffset === span.text().length) {
                            // pressed delete at last position
                            deleteNode = span.next();

                            if (deleteNode && deleteNode.data('variable')) {
                                deleteNode.remove();
                                event.preventDefault();

                                var nextTextNode = span.next();
                                if (nextTextNode) {
                                    text = nextTextNode.text();
                                    nextTextNode.remove();
                                    span.append(text);
                                }
                            }
                        } else if (event.keyCode ===  8 && selection.anchorOffset === 0) {
                            // pressed backspace at firs position
                            deleteNode = span.prev();

                            if (deleteNode && deleteNode.data('variable')) {
                                deleteNode.remove();
                                event.preventDefault();

                                var prevTextNode = span.prev();
                                if (prevTextNode) {
                                    text = prevTextNode.text();
                                    prevTextNode.remove();
                                    span.prepend(text);
                                }
                            }
                        } else if(event.keyCode === 39 && selection.anchorOffset === span.text().length) {
                            if (span.next()) {
                                setCursor(span.next().next());
                                event.preventDefault();
                            }
                        } else if(event.keyCode === 37 && selection.anchorOffset === 0) {
                            if (span.prev()) {
                                setCursor(span.prev().prev(), true);
                                event.preventDefault();
                            }
                        }

                    });

                    span.bind('focus', function (event) {
                        span.parent().addClass('focused');
                    });

                    span.bind('blur', function(event){
                        span.parent().removeClass('focused');
                    });

                    span.bind('keyup focus blur', function(event) {
                        var editableDiv = element[0];
                        var selection = window.getSelection();

                        if (selection.anchorNode != editableDiv) {
                            $scope.cursorNode = selection.anchorNode;
                            $scope.cursorNodeOffset = selection.anchorOffset;
                        }

                        $scope.formula = childNodesToFormula(element.children());
                    });

                    return span;
                };

                /** Create a sepcially crafted span element from a variable definition */
                var createVariableNode = function(variableName, variableValue) {
                    var span = angular.element('');
                    var label;
                    if (variableValue.type === 'dataset') {
                        label = variableValue.dataset.name;
                    } else if (variableValue.type === 'indicator') {
                        label = variableValue.indicator.name;
                    }
                    span.addClass('indicator-formula').addClass('indicator-formula-selected');
                    span.attr('contenteditable', false);
                    span.attr('data-variable', variableName);
                    span.attr('data-label', label);
                    span.text(label);

                    span.click(function () {
                        setCursor(span.next());
                    });

                    return span;
                };

                element.empty().append(formulaToChildNodes($scope.formula, $scope.variables));

                var addVariableAtCursor = function(element, variable) {
                    var editableDiv = element[0];
                    var textOffset = $scope.cursorNodeOffset;
                    var currentElement;

                    if (!$scope.cursorNode) {
                        currentElement = element.children().last();
                    } else {
                        currentElement = angular.element($scope.cursorNode).closest('span');
                    }

                    // split current text node
                    var text = currentElement.text();
                    currentElement.text(text.slice(0, textOffset));
                    var nextElement = createTextNode(text.slice(textOffset));
                    currentElement.after(nextElement);

                    // add new textnode
                    var index = Object.keys($scope.variables).length + 1;
                    var variableName = '__' + index + '__';
                    $scope.variables[variableName] = variable;
                    var variableElement = createVariableNode(variableName, variable);
                    currentElement.after(variableElement);

                    // set cursor after inserted div
                    setCursor(nextElement);
                };

                $scope.$on('AddVariable', function(event, variable) {
                    addVariableAtCursor(element, variable);
                    $scope.formula = childNodesToFormula(element.children());
                });
            }
        };
    }])

    .directive('formula', [
        '$http', 'API_CONF', '$q', function ($http, API_CONF, $q) {

            return {
                restrict: 'E',
                replace: true,
                scope: {
                    formula: '=formula',
                    variables: '=variables'
                },
                template: function (scope) {
                    return '

';
                },
                link: function (scope, element, attrs) {

                    var parseFormula = function () {
                        var variable;
                        if (scope.formula) {
                            var parsedFormula = scope.formula;
                            if (angular.isObject(scope.variables)) {
                                variables = scope.variables;
                            } else {
                                variables = JSON.parse(scope.variables.replace(/'/g, '"'));
                            }
                            var urlCalls = [];
                            angular.forEach(variables, function (value, key, obj) {
                                var index = scope.formula.indexOf(key.replace(' ', ''));
                                if (index > -1) {
                                    var url = API_CONF.DATASETS_MANAGER_URL + "/datasets/" + value.id;
                                    urlCalls.push($http({
                                        url: url,
                                        method: "GET"
                                    }).then(function (response) {
                                        return {
                                            response: response,
                                            key: key
                                        };
                                    }));
                                    parsedFormula = parsedFormula.replace(key.replace(' ', ''), " %" + value.id + "% ");
                                }
                            });
                            var deferred = $q.defer();
                            $q.all(urlCalls).then(function (results) {
                                angular.forEach(results, function (value, key, obj) {
                                    var variable = value.key.trim();
                                    var replaceable = "%" + value.response.data.id + "%";
                                    var span = '' + value.response.data.title + '';
                                    parsedFormula = parsedFormula.replace(replaceable, span);
                                });
                                element.empty();
                                element.append(parsedFormula);
                            }, function (errors) {
                                deferred.reject(errors);
                            }, function (updates) {
                                deferred.update(updates);
                            });
                        } else {
                            element.empty();
                        }
                    };

                    scope.$watch('formula', function () {
                        parseFormula();
                    });
                }
            };
        }
    ]);
<commit_msg>Improve formula editor<commit_after>angular.module('pcApp.metrics.directives.formula', ['pcApp.indicators.services.indicator'])

    .directive('pcFormulaEditor', [function(){
        /** Implements basic equation editor inside an element.
         *
         * This code basically implements the editor reqlying on jQuery or
         * jqlite (angular). The formula is presented as a series of s.
         * There are text-s and variable-s. Texts are content
         * editable, while variables are added via the addVariable element.
         * Every variable element is surrunded by two text elements.
         *
         * If you are asked to maintain this: RUN!!
         */
        return {
            restirct: 'A',
            scope: {
                formula: '=',
                variables: '='
            },
            link: function ($scope, element, attrs) {
                $scope.formula = $scope.formula || '';
                $scope.variables = $scope.variables || {};

                var setCursor = function (element, atEnd) {
                    /** Set cursor to the given jq-element (or its first textnode child). */
                    var selection = window.getSelection();
                    var range = document.createRange();
                    var position;

                    if (atEnd) {
                        position = element.text().length;
                    } else {
                        position = 0;
                    }

                    var target = element[0];
                    // if target as an elment and has a text child select that one instead
                    if (target.hasChildNodes() && target.childNodes[0].nodeType === 3) {
                        target = target.childNodes[0];
                    }

                    range.setStart(target, position);
                    range.setEnd(target, position);
                    selection.removeAllRanges();
                    selection.addRange(range);
                };

                /** Translate a group of text and  node into a formula string. */
                var childNodesToFormula = function(childNodes) {
                    var result = [];
                    angular.forEach(childNodes, function (node) {
                        if (node.dataset.variable){
                            result.push(node.dataset.variable);
                        } else {
                            result.push(node.textContent);
                        }
                    });
                    return result.join(' ');
                };

                /** Translate a fromula string into a list of text and  nodes. */
                var formulaToChildNodes = function (formula, variables) {
                    var parts = formula.split(/(__\d+__)/g);
                    var result = [];
                    angular.forEach(parts, function (variableOrText) {
                        var node;
                        if  (!variableOrText) {
                            return;
                        }

                        var isVariable = variableOrText.match(/^__\d+__$/);
                        if (isVariable) {
                            var variable = variableOrText;
                            var node = createVariableNode(variable, variables[variable]);
                        } else {
                            var text = variableOrText;
                            var node = createTextNode(text);
                        }
                        this.push(node);
                    }, result);
                    result.push(createTextNode());
                    return result;
                };

                var createTextNode = function(text) {
                    var span = angular.element('');
                    span.attr('contenteditable', true);
                    span.text(text);
                    span.addClass('text-formula');

                    span.bind('keydown', function(event) {
                        var selection = window.getSelection();
                        var deleteNode, text;
                        if (event.keyCode === 46 && selection.anchorOffset === span.text().length) {
                            // pressed delete at last position
                            deleteNode = span.next();

                            if (deleteNode && deleteNode.data('variable')) {
                                deleteNode.remove();
                                event.preventDefault();

                                var nextTextNode = span.next();
                                if (nextTextNode) {
                                    text = nextTextNode.text();
                                    nextTextNode.remove();
                                    span.append(text);
                                }
                            }
                        } else if (event.keyCode ===  8 && selection.anchorOffset === 0) {
                            // pressed backspace at first position
                            deleteNode = span.prev();

                            if (deleteNode && deleteNode.data('variable')) {
                                deleteNode.remove();
                                event.preventDefault();

                                var prevTextNode = span.prev();
                                if (prevTextNode) {
                                    text = prevTextNode.text();
                                    var spanText = span.text();
                                    prevTextNode.remove();
                                    span.prepend(text);

                                    if (!spanText) {
                                        // only if span was empty, the cursor needs to be placed again
                                        setCursor(span, true);
                                    }
                                }
                            }
                        } else if(event.keyCode === 39 && selection.anchorOffset === span.text().length) {
                            // pressed right arrow at last position
                            if (span.next()) {
                                setCursor(span.next().next());
                                event.preventDefault();
                            }
                        } else if(event.keyCode === 37 && selection.anchorOffset === 0) {
                            // pressed left error at first position
                            if (span.prev()) {
                                setCursor(span.prev().prev(), true);
                                event.preventDefault();
                            }
                        }

                    });

                    span.bind('focus', function (event) {
                        span.parent().addClass('focused');
                    });

                    span.bind('blur', function(event){
                        span.parent().removeClass('focused');
                    });

                    span.bind('keyup focus blur', function(event) {
                        var editableDiv = element[0];
                        var selection = window.getSelection();

                        if (selection.anchorNode != editableDiv) {
                            $scope.cursorNode = selection.anchorNode;
                            $scope.cursorNodeOffset = selection.anchorOffset;
                        }

                        $scope.formula = childNodesToFormula(element.children());
                    });

                    return span;
                };

                /** Create a sepcially crafted span element from a variable definition */
                var createVariableNode = function(variableName, variableValue) {
                    var span = angular.element('');
                    var label;
                    if (variableValue.type === 'dataset') {
                        label = variableValue.dataset.name;
                    } else if (variableValue.type === 'indicator') {
                        label = variableValue.indicator.name;
                    }
                    span.addClass('indicator-formula').addClass('indicator-formula-selected');
                    span.attr('contenteditable', false);
                    span.attr('data-variable', variableName);
                    span.attr('data-label', label);
                    span.text(label);

                    span.click(function () {
                        setCursor(span.next());
                    });

                    return span;
                };

                element.empty().append(formulaToChildNodes($scope.formula, $scope.variables));

                var addVariableAtCursor = function(element, variable) {
                    var editableDiv = element[0];
                    var textOffset = $scope.cursorNodeOffset;
                    var currentElement;

                    if (!$scope.cursorNode) {
                        currentElement = element.children().last();
                    } else {
                        currentElement = angular.element($scope.cursorNode).closest('span');
                    }

                    // split current text node
                    var text = currentElement.text();
                    currentElement.text(text.slice(0, textOffset));
                    var nextElement = createTextNode(text.slice(textOffset));
                    currentElement.after(nextElement);

                    // add new textnode
                    var index = Object.keys($scope.variables).length + 1;
                    var variableName = '__' + index + '__';
                    $scope.variables[variableName] = variable;
                    var variableElement = createVariableNode(variableName, variable);
                    currentElement.after(variableElement);

                    // set cursor after inserted div
                    setCursor(nextElement);
                };

                $scope.$on('AddVariable', function(event, variable) {
                    addVariableAtCursor(element, variable);
                    $scope.formula = childNodesToFormula(element.children());
                });
            }
        };
    }])

    .directive('formula', [
        '$http', 'API_CONF', '$q', function ($http, API_CONF, $q) {

            return {
                restrict: 'E',
                replace: true,
                scope: {
                    formula: '=formula',
                    variables: '=variables'
                },
                template: function (scope) {
                    return '

';
                },
                link: function (scope, element, attrs) {

                    var parseFormula = function () {
                        var variable;
                        if (scope.formula) {
                            var parsedFormula = scope.formula;
                            if (angular.isObject(scope.variables)) {
                                variables = scope.variables;
                            } else {
                                variables = JSON.parse(scope.variables.replace(/'/g, '"'));
                            }
                            var urlCalls = [];
                            angular.forEach(variables, function (value, key, obj) {
                                var index = scope.formula.indexOf(key.replace(' ', ''));
                                if (index > -1) {
                                    var url = API_CONF.DATASETS_MANAGER_URL + "/datasets/" + value.id;
                                    urlCalls.push($http({
                                        url: url,
                                        method: "GET"
                                    }).then(function (response) {
                                        return {
                                            response: response,
                                            key: key
                                        };
                                    }));
                                    parsedFormula = parsedFormula.replace(key.replace(' ', ''), " %" + value.id + "% ");
                                }
                            });
                            var deferred = $q.defer();
                            $q.all(urlCalls).then(function (results) {
                                angular.forEach(results, function (value, key, obj) {
                                    var variable = value.key.trim();
                                    var replaceable = "%" + value.response.data.id + "%";
                                    var span = '' + value.response.data.title + '';
                                    parsedFormula = parsedFormula.replace(replaceable, span);
                                });
                                element.empty();
                                element.append(parsedFormula);
                            }, function (errors) {
                                deferred.reject(errors);
                            }, function (updates) {
                                deferred.update(updates);
                            });
                        } else {
                            element.empty();
                        }
                    };

                    scope.$watch('formula', function () {
                        parseFormula();
                    });
                }
            };
        }
    ]);
<|endoftext|>


<commit_before>/* jshint node: true */
/**
 * Wake Up Platform
 * (c) Telefonica Digital, 2013 - All rights reserved
 * License: GNU Affero V3 (see LICENSE file)
 * Fernando Rodríguez Sela <frsela@tid.es>
 */

var log = require('../shared_libs/logger'),
    querystring = require('querystring'),
    net = require('net');

module.exports.info = {
  name: 'wakeupRouter',
  type: 'router',
  virtualpath: 'wakeup',
  description: 'The heart of the system: Used to wakeup devices'
};

function processWakeUpQuery(paramsString, request, response, cb) {
  response.setHeader('Content-Type', 'text/plain');

  // Check request ...
  if (!paramsString) {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> No required data provided');
    response.statusCode = 400;
    response.write('Bad parameters. No required data provided');
    return;
  }
  var wakeup_data = querystring.parse(paramsString);
  if (wakeup_data.proto) {
    wakeup_data.protocol = wakeup_data.proto;
  } else {
    wakeup_data.protocol = 'udp';
  }

  // Check parameters
  if (!net.isIP(wakeup_data.ip) ||     // Is a valid IP address
      isNaN(wakeup_data.port) ||       // The port is a Number
      wakeup_data.port <= 0 || wakeup_data.port > 65535 // Port in a valid range
  ) {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad IP/Port');
    response.statusCode = 400;
    response.write('Bad parameters. Bad IP/Port');
    return;
  }

  // Check protocol
  if (wakeup_data.protocol !== 'udp' && wakeup_data.protocol !== 'tcp') {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad Protocol');
    response.statusCode = 400;
    response.write('Bad parameters. Bad Protocol');
    return;
  }

  // All Ok, we can wakeup the device !
  log.debug('WU_ListenerHTTP_WakeUpRouter --> WakeUp IP = ' + wakeup_data.ip +
    ':' + wakeup_data.port + ' through (' + wakeup_data.protocol + ')');

  response.statusCode = 200;
  response.write('Accepted');
  process.nextTick(function() {
    cb(wakeup_data);
  });
}

module.exports.entrypoint =
  function router_wakeup(parsedURL, body, request, response, cb) {
    switch (request.method) {
    case 'GET':
      processWakeUpQuery(parsedURL.query, request, response, cb);
      break;
    case 'POST':
      processWakeUpQuery(body, request, response, cb);
      break;
    default:
      response.setHeader('Content-Type', 'text/plain');
      response.statusCode = 405;
      response.write('Bad method. Only GET and POST is allowed');
      log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad method - ' +
        request.method);
    }
  };
<commit_msg>CORS support added<commit_after>/* jshint node: true */
/**
 * Wake Up Platform
 * (c) Telefonica Digital, 2013 - All rights reserved
 * License: GNU Affero V3 (see LICENSE file)
 * Fernando Rodríguez Sela <frsela@tid.es>
 */

var log = require('../shared_libs/logger'),
    querystring = require('querystring'),
    net = require('net');

module.exports.info = {
  name: 'wakeupRouter',
  type: 'router',
  virtualpath: 'wakeup',
  description: 'The heart of the system: Used to wakeup devices'
};

function processWakeUpQuery(paramsString, request, response, cb) {
  response.setHeader('Content-Type', 'text/plain');

  // Check request ...
  if (!paramsString) {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> No required data provided');
    response.statusCode = 400;
    response.write('Bad parameters. No required data provided');
    return;
  }
  var wakeup_data = querystring.parse(paramsString);
  if (wakeup_data.proto) {
    wakeup_data.protocol = wakeup_data.proto;
  } else {
    wakeup_data.protocol = 'udp';
  }

  // Check parameters
  if (!net.isIP(wakeup_data.ip) ||     // Is a valid IP address
      isNaN(wakeup_data.port) ||       // The port is a Number
      wakeup_data.port <= 0 || wakeup_data.port > 65535 // Port in a valid range
  ) {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad IP/Port');
    response.statusCode = 400;
    response.write('Bad parameters. Bad IP/Port');
    return;
  }

  // Check protocol
  if (wakeup_data.protocol !== 'udp' && wakeup_data.protocol !== 'tcp') {
    log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad Protocol');
    response.statusCode = 400;
    response.write('Bad parameters. Bad Protocol');
    return;
  }

  // All Ok, we can wakeup the device !
  log.debug('WU_ListenerHTTP_WakeUpRouter --> WakeUp IP = ' + wakeup_data.ip +
    ':' + wakeup_data.port + ' through (' + wakeup_data.protocol + ')');

  response.statusCode = 200;
  response.write('Accepted');
  process.nextTick(function() {
    cb(wakeup_data);
  });
}

module.exports.entrypoint =
  function router_wakeup(parsedURL, body, request, response, cb) {
    switch (request.method) {
    case 'GET':
      processWakeUpQuery(parsedURL.query, request, response, cb);
      break;
    case 'POST':
      processWakeUpQuery(body, request, response, cb);
      break;
    case 'OPTIONS':
      // CORS support
      log.debug('WU_ListenerHTTP_WakeUpRouter --> Received an OPTIONS method');
      response.setHeader('Access-Control-Allow-Origin', '*');
      response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
      response.statusCode = 200;
      break;
    default:
      response.setHeader('Content-Type', 'text/plain');
      response.statusCode = 405;
      response.write('Bad method. Only GET and POST is allowed');
      log.debug('WU_ListenerHTTP_WakeUpRouter --> Bad method - ' +
        request.method);
    }
  };
<|endoftext|>


<commit_before>var chai = require('chai');
var mock = require('chai-kerouac-middleware');
var sitemap = require('../../lib');

describe('middleware/urlset', function() {

  it('should include location of URL', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html', fullURL: 'http://www.example.com/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include location of URL

  it('should include date of last modification of URL', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html',
            fullURL: 'http://www.example.com/',
            modifiedAt: new Date(Date.UTC(2017, 8, 3, 17, 30, 15)) }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '    <lastmod>2017-09-03T17:30:15+00:00</lastmod>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include date of last modification of URL

  it('should include multiple URLs', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html', fullURL: 'http://www.example.com/' },
          { path: '/about.html', fullURL: 'http://www.example.com/about/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '  </url>',
          '  <url>',
          '    <loc>http://www.example.com/contact/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include multiple URLs

  it('should only include URLs which are HTML format', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.html', fullURL: 'http://www.example.com/hello.html' },
          { path: '/assets/script.js', fullURL: 'http://www.example.com/assets/script.js' },
          { path: '/assets/stylesheet.css', fullURL: 'http://www.example.com/assets/stylesheet.css' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.html</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        expect(this.locals.pages[2].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should only include URLs which are HTML format

  it('should not include URLs which are already in a sitemap', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/blog/index.html', fullURL: 'http://www.example.com/blog/', isInSitemap: true },
          { path: '/blog/hello.html', fullURL: 'http://www.example.com/blog/hello/', isInSitemap: true },
          { path: '/blog/hello-again.html', fullURL: 'http://www.example.com/blog/hello-again/', isInSitemap: true },
          { path: '/legal/terms.html', fullURL: 'http://www.example.com/legal/terms/'  },
          { path: '/legal/privacy.html', fullURL: 'http://www.example.com/legal/privacy/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/legal/terms/</loc>',
          '  </url>',
          '  <url>',
          '    <loc>http://www.example.com/legal/privacy/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.equal(true);
        expect(this.locals.pages[2].isInSitemap).to.equal(true);
        expect(this.locals.pages[3].isInSitemap).to.equal(true);
        expect(this.locals.pages[4].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should not include URLs which are already in a sitemap

  it('should include URLs which are TXT format when option is set but exclude robots.txt', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.txt' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.txt', fullURL: 'http://www.example.com/hello.txt' },
          { path: '/robots.txt', fullURL: 'http://www.example.com/robots.txt' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.txt</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are TXT format when option is set but exclude robots.txt

  it('should include URLs which are XML format when option is set but exclude sitemaps', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.xml' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.xml', fullURL: 'http://www.example.com/hello.xml' },
          { path: '/blog/sitemap.xml', fullURL: 'http://www.example.com/blog/sitemap.xml', isSitemap: true }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.xml</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are XML format when option is set but exclude sitemaps

  it('should include URLs which are XML format when option is set but exclude sitemap indexes', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.xml' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.xml', fullURL: 'http://www.example.com/hello.xml' },
          { path: '/sitemap_index.xml', fullURL: 'http://www.example.com/sitemap_index.xml', isSitemap: true }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.xml</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are XML format when option is set but exclude sitemap indexes

  describe('without base url setting', function() {
    var page, err;

    before(function(done) {
      chai.kerouac.use(sitemap())
        .request(function(page) {
          page.absoluteURL = '/sitemap.xml';
          page.locals = {};
          page.locals.pages = [
            { path: '/hello.html', absoluteURL: '/hello' },
          ];
        })
        .next(function(e) {
          err = e;
          done();
        })
        .generate();
    });

    it('should error', function() {
      expect(err).to.be.an.instanceOf(Error);
      expect(err.message).to.equal('Unable to add "/hello" to sitemap, set \'base url\' setting and try again');
    });
  }); // without base url setting

});
<commit_msg>Clean up tests.<commit_after>var chai = require('chai');
var mock = require('chai-kerouac-middleware');
var sitemap = require('../../lib');

describe('middleware/urlset', function() {

  it('should include location of URL', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html', fullURL: 'http://www.example.com/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include location of URL

  it('should include date of last modification of URL', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html',
            fullURL: 'http://www.example.com/',
            modifiedAt: new Date(Date.UTC(2017, 8, 3, 17, 30, 15)) }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '    <lastmod>2017-09-03T17:30:15+00:00</lastmod>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include date of last modification of URL

  it('should include multiple URLs', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/index.html', fullURL: 'http://www.example.com/' },
          { path: '/about.html', fullURL: 'http://www.example.com/about/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/</loc>',
          '  </url>',
          '  <url>',
          '    <loc>http://www.example.com/about/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should include multiple URLs

  it('should only include URLs which are HTML format', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.html', fullURL: 'http://www.example.com/hello.html' },
          { path: '/assets/script.js', fullURL: 'http://www.example.com/assets/script.js' },
          { path: '/assets/stylesheet.css', fullURL: 'http://www.example.com/assets/stylesheet.css' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.html</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        expect(this.locals.pages[2].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should only include URLs which are HTML format

  it('should not include URLs which are already in a sitemap', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/blog/index.html', fullURL: 'http://www.example.com/blog/', isInSitemap: true },
          { path: '/blog/hello.html', fullURL: 'http://www.example.com/blog/hello/', isInSitemap: true },
          { path: '/blog/hello-again.html', fullURL: 'http://www.example.com/blog/hello-again/', isInSitemap: true },
          { path: '/legal/terms.html', fullURL: 'http://www.example.com/legal/terms/'  },
          { path: '/legal/privacy.html', fullURL: 'http://www.example.com/legal/privacy/' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/legal/terms/</loc>',
          '  </url>',
          '  <url>',
          '    <loc>http://www.example.com/legal/privacy/</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.equal(true);
        expect(this.locals.pages[2].isInSitemap).to.equal(true);
        expect(this.locals.pages[3].isInSitemap).to.equal(true);
        expect(this.locals.pages[4].isInSitemap).to.equal(true);
        done();
      })
      .generate();
  }); // should not include URLs which are already in a sitemap

  it('should include URLs which are TXT format when option is set but exclude robots.txt', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.txt' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.txt', fullURL: 'http://www.example.com/hello.txt' },
          { path: '/robots.txt', fullURL: 'http://www.example.com/robots.txt' }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.txt</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are TXT format when option is set but exclude robots.txt

  it('should include URLs which are XML format when option is set but exclude sitemaps', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.xml' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.xml', fullURL: 'http://www.example.com/hello.xml' },
          { path: '/blog/sitemap.xml', fullURL: 'http://www.example.com/blog/sitemap.xml', isSitemap: true }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.xml</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are XML format when option is set but exclude sitemaps

  it('should include URLs which are XML format when option is set but exclude sitemap indexes', function(done) {
    chai.kerouac.use(sitemap({ include: [ '.xml' ] }))
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.xml', fullURL: 'http://www.example.com/hello.xml' },
          { path: '/sitemap_index.xml', fullURL: 'http://www.example.com/sitemap_index.xml', isSitemap: true }
        ];
      })
      .finish(function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
          '  <url>',
          '    <loc>http://www.example.com/hello.xml</loc>',
          '  </url>',
          '</urlset>',
          ''
        ].join("\n");

        expect(this.body).to.equal(expected);
        expect(this.isSitemap).to.equal(true);
        expect(this.locals.pages[0].isInSitemap).to.equal(true);
        expect(this.locals.pages[1].isInSitemap).to.be.undefined;
        done();
      })
      .generate();
  }); // should include URLs which are XML format when option is set but exclude sitemap indexes

  it('should error when fully-qualified URL is not known', function(done) {
    chai.kerouac.use(sitemap())
      .request(function(page) {
        page.absoluteURL = '/sitemap.xml';
        page.locals = {};
        page.locals.pages = [
          { path: '/hello.html', absoluteURL: '/hello' },
        ];
      })
      .next(function(err) {
        expect(err).to.be.an.instanceOf(Error);
        expect(err.message).to.equal('Unable to add "/hello" to sitemap, set \'base url\' setting and try again');
        done();
      })
      .generate();
  }); // should error when fully-qualified URL is not known

});
<|endoftext|>


<commit_before>angular.module('orka.config', [])

.provider('ConfigService', [function() {
    this.config = {};
    var defaults = {
        map: {
            projection: new ol.proj.Projection({
                code: 'EPSG:25833',
                units: 'm'
            }),
            extent: [200000, 5880000, 480000, 6075000],
            resolutions:  [
                529.166666667,
                352.777777778,
                264.583333333,
                176.388888889,
                88.1944444444,
                52.9166666667,
                35.2777777778,
                28.2222222222,
                22.9305555556,
                17.6388888889,
                12.3472222222,
                8.8194444444,
                7.0555555556,
                5.2916666667,
                3.5277777778,
                2.6458333333,
                1.7638888889,
                0.8819444444,
                0.3527777778,
                0.1763888889
            ]
            // TODO attribution
        },
        backgroundLayer: {
            'ORKA_STADTPLAN': {
                baseURL: 'http://geo.sv.rostock.de/geodienste/stadtplan/tms/1.0.0/',
                layer: 'stadtplan_EPSG25833',
                format: 'png',
                title: 'Stadtplan',
                shortcut: 'S'
            },
            'ORKA_STADTPLAN_GRAU': {
                baseURL: 'http://geo.sv.rostock.de/geodienste/stadtplan/tms/1.0.0/',
                layer: 'stadtplan_greyscale_EPSG25833',
                format: 'png',
                title: 'Stadtplan Grau',
                shortcut: 'G'
            }
        },
        poi: {
            layerURL: 'http://10.1.1.49:8888/proxy/http://10.1.1.49:4000/poi.geojson?',
            iconBaseURL: 'http://www.orka-mv.de/static/icons/',
            markerIcon: '/static/img/marker.svg',
            legendURL: '/static/data/poi_legend_data.json',
        },
        track: {
            layerURL: 'http://www.orka-mv.de/citymap/tracks',
            layerName: 'tracks',
            legendURL: '/static/data/track_legend_data.json'
        },
        print: {
            defaultScale: 250000,
            createURL: '/print',
            checkURL: '',
            checkDelay: 2000,
            pageSizes: [{
                'label': 'DIN A4 Hoch',
                'icon': 'glyphicon-resize-horizontal',
                'value': [210, 297]
            }, {
                'label': 'DIN A4 Quer',
                'icon': 'glyphicon-resize-vertical',
                'value': [297, 210]
            }],
            outputFormats: [{
                'label': 'PDF',
                'value': 'pdf'
            },
            {
                'label': 'PNG',
                'value': 'png'
            }]
        }
    };

    this.setConfig = function(config) {
        var self = this;
        self.config.map = $.extend({}, defaults.map, config.map);
        self.config.backgroundLayer = [];
        angular.forEach(config.layers, function(layerName) {
            self.config.backgroundLayer.push(defaults.backgroundLayer[layerName]);
        });
        self.config.poi = $.extend({}, defaults.poi, config.poi);
        self.config.track = $.extend({}, defaults.track, config.track);
        if(config.print === true) {
            self.config.print = $.extend({}, defaults.print);
        }
        ol.proj.addProjection(self.config.map.projection);
    };

    this.$get = [function() {
        return this;
    }];
}]);
<commit_msg>Added center and zoom to defaults<commit_after>angular.module('orka.config', [])

.provider('ConfigService', [function() {
    this.config = {};
    var defaults = {
        map: {
            projection: new ol.proj.Projection({
                code: 'EPSG:25833',
                units: 'm'
            }),
            extent: [200000, 5880000, 480000, 6075000],
            resolutions:  [
                529.166666667,
                352.777777778,
                264.583333333,
                176.388888889,
                88.1944444444,
                52.9166666667,
                35.2777777778,
                28.2222222222,
                22.9305555556,
                17.6388888889,
                12.3472222222,
                8.8194444444,
                7.0555555556,
                5.2916666667,
                3.5277777778,
                2.6458333333,
                1.7638888889,
                0.8819444444,
                0.3527777778,
                0.1763888889
            ],
            center: [313282, 6003693],
            zoom: 9
            // TODO attribution
        },
        backgroundLayer: {
            'ORKA_STADTPLAN': {
                baseURL: 'http://geo.sv.rostock.de/geodienste/stadtplan/tms/1.0.0/',
                layer: 'stadtplan_EPSG25833',
                format: 'png',
                title: 'Stadtplan',
                shortcut: 'S'
            },
            'ORKA_STADTPLAN_GRAU': {
                baseURL: 'http://geo.sv.rostock.de/geodienste/stadtplan/tms/1.0.0/',
                layer: 'stadtplan_greyscale_EPSG25833',
                format: 'png',
                title: 'Stadtplan Grau',
                shortcut: 'G'
            }
        },
        poi: {
            layerURL: 'http://10.1.1.49:8888/proxy/http://10.1.1.49:4000/poi.geojson?',
            iconBaseURL: 'http://www.orka-mv.de/static/icons/',
            markerIcon: '/static/img/marker.svg',
            legendURL: '/static/data/poi_legend_data.json',
        },
        track: {
            layerURL: 'http://www.orka-mv.de/citymap/tracks',
            layerName: 'tracks',
            legendURL: '/static/data/track_legend_data.json'
        },
        print: {
            defaultScale: 250000,
            createURL: '/print',
            checkURL: '',
            checkDelay: 2000,
            pageSizes: [{
                'label': 'DIN A4 Hoch',
                'icon': 'glyphicon-resize-horizontal',
                'value': [210, 297]
            }, {
                'label': 'DIN A4 Quer',
                'icon': 'glyphicon-resize-vertical',
                'value': [297, 210]
            }],
            outputFormats: [{
                'label': 'PDF',
                'value': 'pdf'
            },
            {
                'label': 'PNG',
                'value': 'png'
            }]
        }
    };

    this.setConfig = function(config) {
        var self = this;
        self.config.map = $.extend({}, defaults.map, config.map);
        self.config.backgroundLayer = [];
        angular.forEach(config.layers, function(layerName) {
            self.config.backgroundLayer.push(defaults.backgroundLayer[layerName]);
        });
        self.config.poi = $.extend({}, defaults.poi, config.poi);
        self.config.track = $.extend({}, defaults.track, config.track);
        if(config.print === true) {
            self.config.print = $.extend({}, defaults.print);
        }
        ol.proj.addProjection(self.config.map.projection);
    };

    this.$get = [function() {
        return this;
    }];
}]);
<|endoftext|>


<commit_before>//  Dependancies
const express = require('express');
const request = require('request');
const path = require('path');
const Conversation = require('watson-developer-cloud/conversation/v1'); //  watson sdk

//  Router
const router = express.Router();

//  Send response back to facebook
const returnRespose = require(path.join(__dirname, '../', 'helpers', 'returnResponse'));
//  Send request to Watson
const pingWatson = require(path.join(__dirname, '../', 'helpers', 'pingWatson'));

//  Watson convo config
const { USER_NAME, USER_PASS, WORKSPACE_ID } = process.env;

//  Facebook AUTH
router.get('/', (req, res) => {
    if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === 'alexander') {
        console.log("Validating webhook");
        return res
            .status(200)
            .send(req.query['hub.challenge']);
    }
    else {
        console.error("Failed validation. Make sure the validation tokens match.");
        return res
            .sendStatus(403);
    }
});

//  Webhook
router.post('/', function (req, res) {

    //  Get events
    let messaging_events = req.body.entry[0].messaging;

    //  Itterate over events
    for (let i = 0; i < messaging_events.length; i++) {
        //  Get message and sender data
        let event = req.body.entry[0].messaging[i];
        let sender = event.sender.id;

        //  Message exists
        if (event.message && event.message.text) {
            let text = event.message.text;
            console.log(`
                The text is ${text}
            `);

            pingWatson(req.body)
                .then((data) => {
                    // !!!
                    console.log(data);
                })
                .catch((err) => {
                    //  error from watson
                    console.log(err);
                });
        }

    }
})

//  Export the module
module.exports = router;<commit_msg>bugfix<commit_after>//  Dependancies
const express = require('express');
const request = require('request');
const path = require('path');
const Conversation = require('watson-developer-cloud/conversation/v1'); //  watson sdk

//  Router
const router = express.Router();

//  Send response back to facebook
const returnRespose = require(path.join(__dirname, '../', 'helpers', 'returnResponse'));
//  Send request to Watson
const pingWatson = require(path.join(__dirname, '../', 'helpers', 'pingWatson'));

//  Watson convo config
const { USER_NAME, USER_PASS, WORKSPACE_ID } = process.env;

//  Facebook AUTH
router.get('/', (req, res) => {
    if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === 'alexander') {
        console.log("Validating webhook");
        return res
            .status(200)
            .send(req.query['hub.challenge']);
    }
    else {
        console.error("Failed validation. Make sure the validation tokens match.");
        return res
            .sendStatus(403);
    }
});

//  Webhook
router.post('/', function (req, res) {

    //  Get events
    let messaging_events = req.body.entry[0].messaging;

    //  Itterate over events
    for (let i = 0; i < messaging_events.length; i++) {
        //  Get message and sender data
        let event = req.body.entry[0].messaging[i];
        let sender = event.sender.id;

        //  Message exists
        if (event.message && event.message.text) {
            let text = event.message.text;
            console.log(`
                The text is ${text}
            `);

            pingWatson(req.body)
                .then((data) => {
                    returnRespose();
                    return res.status(200);
                })
                .catch((err) => {
                    //  error from watson
                    console.log(err);
                    return res.status(500);
                });
        }

    }
})

//  Export the module
module.exports = router;<|endoftext|>


<commit_before>import { values, omit, filter, includes, isEmpty, get } from 'lodash'

const isJustNewPost = activity => {
  const reasons = activity.get('meta').reasons
  return reasons.every(reason => reason.match(/^newPost/))
}

const isAnnouncement = activity => {
  const reasons = activity.get('meta').reasons
  return filter(reasons, reason => reason.match(/^announcement/)).length > 0
}

const isTopic = activity => {
  const reasons = activity.get('meta').reasons
  const t = filter(reasons, reason => reason.match(/^tag/)).length > 0
  return t
}

const mergeByReader = activities => {
  const fields = ['actor_id', 'community_id']
  const merged = activities.reduce((acc, activity) => {
    const current = acc[activity.reader_id]
    if (acc[activity.reader_id]) {
      fields.forEach(f => {
        if (activity[f]) current[f] = activity[f]
      })
      current.reasons.push(activity.reason)
    } else {
      acc[activity.reader_id] = Object.assign(
        {reasons: [activity.reason]}, omit(activity, 'reason'))
    }
    return acc
  }, {})
  return values(merged)
}

const removeForRelation = (model) => (id, trx) => {
  const trxOpt = {transacting: trx}
  return Activity.where(`${model}_id`, id).query()
  .pluck('id').transacting(trx)
  .then(ids => {
    // TODO: New Activity count needs to be decremented
    // if inApp medium is used-- see User#decNewNotificationCount
    return Notification.where('activity_id', 'in', ids).destroy(trxOpt)
    .then(() => Activity.where('id', 'in', ids).destroy(trxOpt))
  })
}

module.exports = bookshelf.Model.extend({
  tableName: 'activities',

  actor: function () {
    return this.belongsTo(User, 'actor_id')
  },

  reader: function () {
    return this.belongsTo(User, 'reader_id')
  },

  comment: function () {
    console.log('comment is called')
    return this.belongsTo(Comment)
  },

  contribution: function () {
    return this.belongsTo(Contribution, 'contribution_id')
  },

  projectContribution: function () {
    return this.belongsTo(ProjectContribution, 'project_contribution_id')
  },

  post: function () {
    return this.belongsTo(Post)
  },

  parentComment: function () {
    return this.belongsTo(Comment, 'parent_comment_id')
  },

  community: function () {
    return this.belongsTo(Community)
  },

  notifications: function () {
    return this.hasMany(Notification)
  },

  createNotifications: async function (trx) {
    const relations = ['reader']
    if (this.get('post_id')) {
      relations.splice(0, 0, 'post', 'post.communities')
    }
    if (this.get('contribution_id')) {
      relations.splice(0, 0, 'contribution', 'contribution.post', 'contribution.user')
    }
    if (this.get('comment_id')) {
      relations.splice(0, 0, 'comment', 'comment.post', 'comment.post.communities')
    }
    if (this.get('community_id')) {
      relations.push('community')
    }
    await this.load(relations, {transacting: trx})
    const notificationData = await Activity.generateNotificationMedia(this)

    return Promise.map(notificationData, medium =>
      new Notification({
        activity_id: this.id,
        created_at: new Date(),
        medium,
        user_id: this.get('reader_id')
      }).save({}, {transacting: trx}))
  },

  contributionAmount: async function () {
    await this.load('projectContribution')
    if (!this.relations.projectContribution) return null
    return this.relations.projectContribution.get('amount')
  }

}, {
  Reason: {
    Mention: 'mention', // you are mentioned in a post or comment
    Comment: 'comment', // someone makes a comment on a post you follow
    Contribution: 'contribution', // someone add you as a contributor to a #request
    FollowAdd: 'followAdd', // you are added as a follower
    Follow: 'follow', // someone follows your post
    Unfollow: 'unfollow', // someone leaves your post
    Announcement: 'announcement'
  },

  find: function (id, options) {
    return this.where({id}).fetch(options)
  },

  filterInactiveContent: q => {
    q.whereRaw('(comments.active = true or comments.id is null)')
    .leftJoin('comments', function () {
      this.on('comments.id', '=', 'activities.comment_id')
    })

    q.whereRaw('(posts.active = true or posts.id is null)')
    .leftJoin('posts', function () {
      this.on('posts.id', '=', 'activities.post_id')
    })
  },

  joinWithCommunity: (communityId, q) => {
    q.where('communities_posts.community_id', communityId)
    .join('communities_posts', function () {
      this.on('comments.post_id', 'communities_posts.post_id')
      .orOn('posts.id', 'communities_posts.post_id')
    })
  },

  forComment: function (comment, userId, action) {
    if (!action) {
      action = includes(comment.mentions(), userId.toString())
        ? this.Reason.Mention
        : this.Reason.Comment
    }

    return new Activity({
      reader_id: userId,
      actor_id: comment.get('user_id'),
      comment_id: comment.id,
      post_id: comment.get('post_id'),
      action: action,
      created_at: comment.get('created_at')
    })
  },

  forPostMention: function (post, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: post.get('user_id'),
      post_id: post.id,
      meta: {reasons: [this.Reason.Mention]},
      created_at: post.get('created_at')
    })
  },

  forFollowAdd: function (follow, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: follow.get('added_by_id'),
      post_id: follow.get('post_id'),
      meta: {reasons: [this.Reason.FollowAdd]},
      created_at: follow.get('added_at')
    })
  },

  forFollow: function (follow, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: follow.get('user_id'),
      post_id: follow.get('post_id'),
      meta: {reasons: [this.Reason.Follow]},
      created_at: follow.get('added_at')
    })
  },

  forUnfollow: function (post, unfollowerId) {
    return new Activity({
      reader_id: post.get('user_id'),
      actor_id: unfollowerId,
      post_id: post.id,
      meta: {reasons: [this.Reason.Unfollow]},
      created_at: new Date()
    })
  },

  unreadCountForUser: function (user) {
    return Activity.query().where({reader_id: user.id, unread: true}).count()
    .then(rows => rows[0].count)
  },

  saveForReasonsOpts: function ({ activities }) {
    return Activity.saveForReasons(activities)
  },

  saveForReasons: function (activities, trx) {
    return Promise.map(mergeByReader(activities), activity => {
      const attrs = Object.assign(
        {},
        omit(activity, 'reasons'),
        {meta: {reasons: activity.reasons}}
      )

      return Activity.createWithNotifications(attrs, trx)
    })
    .tap(() => Queue.classMethod('Notification', 'sendUnsent'))
  },

  communityIds: function (activity) {
    if (activity.get('post_id')) {
      return get(activity, 'relations.post.relations.communities', []).map(c => c.id)
    } else if (activity.get('comment_id')) {
      return get(activity, 'relations.comment.relations.post.relations.communities', []).map(c => c.id)
    } else if (activity.get('community_id')) {
      return [activity.relations.community.id]
    }
    return []
  },

  generateNotificationMedia: async function (activity) {
    await activity.load('post.communities')

    // TODO: rename 'notifications' to 'media'
    var notifications = []
    var communities = Activity.communityIds(activity)

    var user = activity.relations.reader

    const memberships = await user.groupMembershipsForModel(Community)
    .fetch({withRelated: 'group'})

    const relevantMemberships = filter(memberships.models, mem =>
      includes(communities, mem.relations.group.get('group_data_id')))

    const membershipsPermitting = key =>
      filter(relevantMemberships, mem => mem.getSetting(key))

    const emailable = membershipsPermitting('sendEmail')
    const pushable = membershipsPermitting('sendPushNotifications')

    if ((!isEmpty(emailable) && !isJustNewPost(activity)) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.Email)
    }

    if (isTopic(activity) || !isEmpty(pushable) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.Push)
    }

    if (!isJustNewPost(activity) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.InApp)
    }

    return notifications
  },

  createWithNotifications: function (attributes, trx) {
    return new Activity(Object.assign({created_at: new Date()}, attributes))
    .save({}, {transacting: trx})
    .tap(activity => activity.createNotifications(trx))
  },

  removeForComment: removeForRelation('comment'),

  removeForPost: removeForRelation('post'),

  removeForContribution: removeForRelation('contribution')

})
<commit_msg>remove log<commit_after>import { values, omit, filter, includes, isEmpty, get } from 'lodash'

const isJustNewPost = activity => {
  const reasons = activity.get('meta').reasons
  return reasons.every(reason => reason.match(/^newPost/))
}

const isAnnouncement = activity => {
  const reasons = activity.get('meta').reasons
  return filter(reasons, reason => reason.match(/^announcement/)).length > 0
}

const isTopic = activity => {
  const reasons = activity.get('meta').reasons
  const t = filter(reasons, reason => reason.match(/^tag/)).length > 0
  return t
}

const mergeByReader = activities => {
  const fields = ['actor_id', 'community_id']
  const merged = activities.reduce((acc, activity) => {
    const current = acc[activity.reader_id]
    if (acc[activity.reader_id]) {
      fields.forEach(f => {
        if (activity[f]) current[f] = activity[f]
      })
      current.reasons.push(activity.reason)
    } else {
      acc[activity.reader_id] = Object.assign(
        {reasons: [activity.reason]}, omit(activity, 'reason'))
    }
    return acc
  }, {})
  return values(merged)
}

const removeForRelation = (model) => (id, trx) => {
  const trxOpt = {transacting: trx}
  return Activity.where(`${model}_id`, id).query()
  .pluck('id').transacting(trx)
  .then(ids => {
    // TODO: New Activity count needs to be decremented
    // if inApp medium is used-- see User#decNewNotificationCount
    return Notification.where('activity_id', 'in', ids).destroy(trxOpt)
    .then(() => Activity.where('id', 'in', ids).destroy(trxOpt))
  })
}

module.exports = bookshelf.Model.extend({
  tableName: 'activities',

  actor: function () {
    return this.belongsTo(User, 'actor_id')
  },

  reader: function () {
    return this.belongsTo(User, 'reader_id')
  },

  comment: function () {
    return this.belongsTo(Comment)
  },

  contribution: function () {
    return this.belongsTo(Contribution, 'contribution_id')
  },

  projectContribution: function () {
    return this.belongsTo(ProjectContribution, 'project_contribution_id')
  },

  post: function () {
    return this.belongsTo(Post)
  },

  parentComment: function () {
    return this.belongsTo(Comment, 'parent_comment_id')
  },

  community: function () {
    return this.belongsTo(Community)
  },

  notifications: function () {
    return this.hasMany(Notification)
  },

  createNotifications: async function (trx) {
    const relations = ['reader']
    if (this.get('post_id')) {
      relations.splice(0, 0, 'post', 'post.communities')
    }
    if (this.get('contribution_id')) {
      relations.splice(0, 0, 'contribution', 'contribution.post', 'contribution.user')
    }
    if (this.get('comment_id')) {
      relations.splice(0, 0, 'comment', 'comment.post', 'comment.post.communities')
    }
    if (this.get('community_id')) {
      relations.push('community')
    }
    await this.load(relations, {transacting: trx})
    const notificationData = await Activity.generateNotificationMedia(this)

    return Promise.map(notificationData, medium =>
      new Notification({
        activity_id: this.id,
        created_at: new Date(),
        medium,
        user_id: this.get('reader_id')
      }).save({}, {transacting: trx}))
  },

  contributionAmount: async function () {
    await this.load('projectContribution')
    if (!this.relations.projectContribution) return null
    return this.relations.projectContribution.get('amount')
  }

}, {
  Reason: {
    Mention: 'mention', // you are mentioned in a post or comment
    Comment: 'comment', // someone makes a comment on a post you follow
    Contribution: 'contribution', // someone add you as a contributor to a #request
    FollowAdd: 'followAdd', // you are added as a follower
    Follow: 'follow', // someone follows your post
    Unfollow: 'unfollow', // someone leaves your post
    Announcement: 'announcement'
  },

  find: function (id, options) {
    return this.where({id}).fetch(options)
  },

  filterInactiveContent: q => {
    q.whereRaw('(comments.active = true or comments.id is null)')
    .leftJoin('comments', function () {
      this.on('comments.id', '=', 'activities.comment_id')
    })

    q.whereRaw('(posts.active = true or posts.id is null)')
    .leftJoin('posts', function () {
      this.on('posts.id', '=', 'activities.post_id')
    })
  },

  joinWithCommunity: (communityId, q) => {
    q.where('communities_posts.community_id', communityId)
    .join('communities_posts', function () {
      this.on('comments.post_id', 'communities_posts.post_id')
      .orOn('posts.id', 'communities_posts.post_id')
    })
  },

  forComment: function (comment, userId, action) {
    if (!action) {
      action = includes(comment.mentions(), userId.toString())
        ? this.Reason.Mention
        : this.Reason.Comment
    }

    return new Activity({
      reader_id: userId,
      actor_id: comment.get('user_id'),
      comment_id: comment.id,
      post_id: comment.get('post_id'),
      action: action,
      created_at: comment.get('created_at')
    })
  },

  forPostMention: function (post, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: post.get('user_id'),
      post_id: post.id,
      meta: {reasons: [this.Reason.Mention]},
      created_at: post.get('created_at')
    })
  },

  forFollowAdd: function (follow, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: follow.get('added_by_id'),
      post_id: follow.get('post_id'),
      meta: {reasons: [this.Reason.FollowAdd]},
      created_at: follow.get('added_at')
    })
  },

  forFollow: function (follow, userId) {
    return new Activity({
      reader_id: userId,
      actor_id: follow.get('user_id'),
      post_id: follow.get('post_id'),
      meta: {reasons: [this.Reason.Follow]},
      created_at: follow.get('added_at')
    })
  },

  forUnfollow: function (post, unfollowerId) {
    return new Activity({
      reader_id: post.get('user_id'),
      actor_id: unfollowerId,
      post_id: post.id,
      meta: {reasons: [this.Reason.Unfollow]},
      created_at: new Date()
    })
  },

  unreadCountForUser: function (user) {
    return Activity.query().where({reader_id: user.id, unread: true}).count()
    .then(rows => rows[0].count)
  },

  saveForReasonsOpts: function ({ activities }) {
    return Activity.saveForReasons(activities)
  },

  saveForReasons: function (activities, trx) {
    return Promise.map(mergeByReader(activities), activity => {
      const attrs = Object.assign(
        {},
        omit(activity, 'reasons'),
        {meta: {reasons: activity.reasons}}
      )

      return Activity.createWithNotifications(attrs, trx)
    })
    .tap(() => Queue.classMethod('Notification', 'sendUnsent'))
  },

  communityIds: function (activity) {
    if (activity.get('post_id')) {
      return get(activity, 'relations.post.relations.communities', []).map(c => c.id)
    } else if (activity.get('comment_id')) {
      return get(activity, 'relations.comment.relations.post.relations.communities', []).map(c => c.id)
    } else if (activity.get('community_id')) {
      return [activity.relations.community.id]
    }
    return []
  },

  generateNotificationMedia: async function (activity) {
    await activity.load('post.communities')

    // TODO: rename 'notifications' to 'media'
    var notifications = []
    var communities = Activity.communityIds(activity)

    var user = activity.relations.reader

    const memberships = await user.groupMembershipsForModel(Community)
    .fetch({withRelated: 'group'})

    const relevantMemberships = filter(memberships.models, mem =>
      includes(communities, mem.relations.group.get('group_data_id')))

    const membershipsPermitting = key =>
      filter(relevantMemberships, mem => mem.getSetting(key))

    const emailable = membershipsPermitting('sendEmail')
    const pushable = membershipsPermitting('sendPushNotifications')

    if ((!isEmpty(emailable) && !isJustNewPost(activity)) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.Email)
    }

    if (isTopic(activity) || !isEmpty(pushable) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.Push)
    }

    if (!isJustNewPost(activity) || isAnnouncement(activity)) {
      notifications.push(Notification.MEDIUM.InApp)
    }

    return notifications
  },

  createWithNotifications: function (attributes, trx) {
    return new Activity(Object.assign({created_at: new Date()}, attributes))
    .save({}, {transacting: trx})
    .tap(activity => activity.createNotifications(trx))
  },

  removeForComment: removeForRelation('comment'),

  removeForPost: removeForRelation('post'),

  removeForContribution: removeForRelation('contribution')

})
<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular
    .module('porttare.controllers')
    .controller('MapController', MapController);

  function MapController($ionicLoading, $ionicPopup, GeolocationService) {

    var mapVm = this;
    mapVm.disableTap = disableTap;

    $ionicLoading.show({
      template: 'cargando...'
    });

    GeolocationService
      .getCurrentPosition()
      .then(function success(position) {

        var map = loadMap(position);
        loadPlacesSearchBox(map);
        $ionicLoading.hide();

      },
      function error() {
        $ionicLoading.hide();
        $ionicPopup.alert({
          title: 'Error',
          template: 'Hubo un error al cargar el mapa.'
        });
      });

    function loadMap(position) {
      var lat = position.coords.latitude;
      var long = position.coords.longitude;

      var latLng = new google.maps.LatLng(lat, long);

      var mapOptions = {
        center: latLng,
        zoom: 17,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: true,
        mapTypeControlOptions: {
          style: google.maps.MapTypeControlStyle.VERTICAL_BAR,
          position: google.maps.ControlPosition.LEFT_BOTTOM
        }
      };

      var map = new google.maps.Map(document.getElementById('map'), mapOptions);

      new google.maps.Marker({
        position: latLng,
        map: map
      });

      return map;
    }

    function loadPlacesSearchBox(map) {
      var input = document.getElementById('input-places');
      var placesSearchBox = new google.maps.places.SearchBox(input);
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(input);

      var markers = [];

      placesSearchBox.addListener('places_changed', function () {
        var places = placesSearchBox.getPlaces();

        if (places.length === 0) {
          return;
        }

        // Clear out the old markers.
        markers.forEach(function (marker) {
          marker.setMap(null);
        });
        markers = [];

        // For each place, get the icon, name and location.
        var bounds = new google.maps.LatLngBounds();
        places.forEach(function (place) {
          var icon = {
            url: place.icon,
            size: new google.maps.Size(71, 71),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(17, 34),
            scaledSize: new google.maps.Size(25, 25)
          };

          // Create a marker for each place.
          markers.push(new google.maps.Marker({
            map: map,
            icon: icon,
            title: place.name,
            position: place.geometry.location
          }));

          if (place.geometry.viewport) {
            bounds.union(place.geometry.viewport);
          } else {
            bounds.extend(place.geometry.location);
          }
        });
        map.fitBounds(bounds);
      });
    }

    function disableTap() {
      var container = document.getElementsByClassName('pac-container');
      angular.element(container).attr('data-tap-disabled', 'true');
      angular.element(container).on('click', function(){
          document.getElementById('input-places').blur();
      });
    }

  }
})();
<commit_msg>Show errors<commit_after>(function () {
  'use strict';

  angular
    .module('porttare.controllers')
    .controller('MapController', MapController);

  function MapController($ionicLoading, $ionicPopup, GeolocationService) {

    var mapVm = this;
    mapVm.disableTap = disableTap;

    $ionicLoading.show({
      template: 'cargando...'
    });

    GeolocationService
      .getCurrentPosition()
      .then(function success(position) {

        var map = loadMap(position);
        loadPlacesSearchBox(map);
        $ionicLoading.hide();

      },
      function error(err) {
        $ionicLoading.hide();
        $ionicPopup.alert({
          title: 'Error',
          template: 'Hubo un error al cargar el mapa.</br>' + err
        });
      });

    function loadMap(position) {
      var lat = position.coords.latitude;
      var long = position.coords.longitude;

      var latLng = new google.maps.LatLng(lat, long);

      var mapOptions = {
        center: latLng,
        zoom: 17,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: true,
        mapTypeControlOptions: {
          style: google.maps.MapTypeControlStyle.VERTICAL_BAR,
          position: google.maps.ControlPosition.LEFT_BOTTOM
        }
      };

      var map = new google.maps.Map(document.getElementById('map'), mapOptions);

      new google.maps.Marker({
        position: latLng,
        map: map
      });

      return map;
    }

    function loadPlacesSearchBox(map) {
      var input = document.getElementById('input-places');
      var placesSearchBox = new google.maps.places.SearchBox(input);
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(input);

      var markers = [];

      placesSearchBox.addListener('places_changed', function () {
        var places = placesSearchBox.getPlaces();

        if (places.length === 0) {
          return;
        }

        // Clear out the old markers.
        markers.forEach(function (marker) {
          marker.setMap(null);
        });
        markers = [];

        // For each place, get the icon, name and location.
        var bounds = new google.maps.LatLngBounds();
        places.forEach(function (place) {
          var icon = {
            url: place.icon,
            size: new google.maps.Size(71, 71),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(17, 34),
            scaledSize: new google.maps.Size(25, 25)
          };

          // Create a marker for each place.
          markers.push(new google.maps.Marker({
            map: map,
            icon: icon,
            title: place.name,
            position: place.geometry.location
          }));

          if (place.geometry.viewport) {
            bounds.union(place.geometry.viewport);
          } else {
            bounds.extend(place.geometry.location);
          }
        });
        map.fitBounds(bounds);
      });
    }

    function disableTap() {
      var container = document.getElementsByClassName('pac-container');
      angular.element(container).attr('data-tap-disabled', 'true');
      angular.element(container).on('click', function(){
          document.getElementById('input-places').blur();
      });
    }

  }
})();
<|endoftext|>


<commit_before>"use strict";
var config = require("../config.js");
var Sequelize = require("sequelize");

var sequelize = new Sequelize(config.localdb.localdburl, {
	dialect:'postgres',
	define: {
			timestamps: true,
			updatedAt: 'updatedat',
			createdAt: 'createdat'
	}
});

//var sequelize = new Sequelize(config.database.dbname, config.database.dbuser, config.database.dbpassword, {
////	"host": "127.0.0.1",
//	"dialect": "postgres",
//	"port": 5432
//});

var Users = sequelize.define("users", {
		email: Sequelize.STRING
});

var Jobs = sequelize.define('jobs', {});
var Job_items = sequelize.define('job_items', {});

module.exports = {
	Users: Users,
	Jobs: Jobs,
	Job_items: Job_items
};
<commit_msg>setting the models<commit_after>"use strict";
var config = require("../config.js");
var Sequelize = require("sequelize");

var sequelize = new Sequelize(config.localdb.localdburl, {
	dialect:'postgres',
	define: {
			timestamps: true,
			updatedAt: 'updatedat',
			createdAt: 'createdat'
	}
});

//var sequelize = new Sequelize(config.database.dbname, config.database.dbuser, config.database.dbpassword, {
////	"host": "127.0.0.1",
//	"dialect": "postgres",
//	"port": 5432
//});

var Users = sequelize.define("users", {
		email: Sequelize.STRING
});

var Jobs = sequelize.define('jobs', {
	job_id: 						Sequelize.STRING,
	client: 						Sequelize.STRING,
	project: 						Sequelize.STRING,
	job_status: 				Sequelize.STRING,
	order_type: 				Sequelize.STRING,
	shipping_date: 			Sequelize.DATE,
	num_of_job_items: 	Sequelize.INT,
	parts_status: 			Sequelize.STRING,
	last_update: 				Sequelize.DATE
});

var Job_items = sequelize.define('job_items', {
	item_id: 			Sequelize.STRING,
	product: 			Sequelize.STRING,
	description: 	Sequelize.STRING,
	glass: 				Sequelize.STRING,
	metal: 				Sequelize.STRING,
	flex: 				Sequelize.STRING,
	bulb: 				Sequelize.STRING,
	qty_req: 			Sequelize.INT,
	qty_hot: 			Sequelize.INT,
	qty_cold: 		Sequelize.INT,
	qty_assem: 		Sequelize.INT,
	qty_packed: 	Sequelize.INT,
	notes: 				Sequelize.STRING
});

module.exports = {
	Users: 			Users,
	Jobs: 			Jobs,
	Job_items: 	Job_items
};
<|endoftext|>