<commit_before>var React = require('react');
var merge = require('react/lib/merge');
var mergeInto = require('react/lib/mergeInto');
var invariant = require('react/lib/invariant');
var warning = require('react/lib/warning');
var ExecutionEnvironment = require('react/lib/ExecutionEnvironment');
var path = require('./path');
var urlStore = require('./stores/url-store');

var _lookupTable = {};

/**
 * A Router specifies a component that will be rendered to the page when the URL
 * matches a given pattern. Routers may also be named, which makes it easy for
 * <Link> components to link to them.
 *
 * Routers are arranged in a nested tree structure. Likewise, when a router's component
 * is rendered, it is nested inside all components of its ancestor routers.
 *
 * Unlike Ember, a nested router's URL pattern does not build upon that of its parents.
 * This may seem like it creates more work up front in specifying URL patterns, but it
 * has the nice benefit of decoupling nested UI from nested URL segments.
 *
 *   var AppRouter = Router('/', App, function (route) {
 *     route('/posts', Posts, function (route) {
 *       route('/posts/new', 'newPost', NewPost);
 *       route('/posts/:id', 'showPost', Post);
 *     });
 *   });
 *
 *   AppRouter.match('/posts/123'); => [ { router: <AppRouter>, params: {} },
 *                                       { router: <PostsRouter>, params: {} },
 *                                       { router: <PostRouter>, params: { id: '123' } } ]
 *
 *   AppRouter.renderComponent(document.body);
 */
function Router(pattern, name, handler, callback) {
  // Support Router(<Route>) usage.
  if (React.isValidComponent(pattern))
    return Router.fromComponent(pattern);

  // Support Router(...) usage, without new.
  if (!(this instanceof Router))
    return new Router(pattern, name, handler, callback);

  // Support Router('/', App) usage, without a name.
  if (React.isValidComponent(name)) {
    callback = handler;
    handler = name;
    name = null;
  }

  pattern = pattern ? path.normalize(pattern) : '';

  // For now, the handler must be a React component. We could possibly
  // swap this out with a RouteHandler object for more advanced usage.
  invariant(
    React.isValidComponent(handler),
    'Router "' + name + '" must have a valid React component for a handler'
  );

  this.displayName = componentToString(handler) + 'Router';

  // If this router has a name, store it for lookup by <Link> components.
  if (name) {
    invariant(
      !_lookupTable[name],
      'You cannot use the name "' + name + '" for more than one router'
    );

    _lookupTable[name] = this;
  }

  this.pattern = pattern;
  this.name = name;
  this.handler = handler;
  this.childRouters = [];

  if (typeof callback === 'function') {
    invariant(
      callback.length === 1,
      'A Router callback should have one argument, a function that is usually named "route". ' +
      'You may have forgotten to include this argument when writing out nested routers like ' +
      'Router("/", App, function (/* missing "route" argument here! */) { ... })'
    );

    callback(this.route.bind(this));
  }
}

/**
 * Returns the router with the given name.
 */
Router.lookup = function (name) {
  return _lookupTable[name];
};

var Route = require('./components/route');

/**
 * A convenience method that creates a Router from a <Route> component. This allows
 * you to use JSX to describe your route hierarchy instead of the JavaScript API.
 *
 *   var AppRouter = Router.fromComponent(
 *     <Route handler={App}>
 *       <Route name="login" handler={Login}/>
 *       <Route name="logout" handler={Logout}/>
 *       <Route name="about" handler={About}/>
 *     </Route>
 *   );
 */
Router.fromComponent = function (routeComponent) {
  invariant(
    routeComponent.type === Route.type,
    'A Router may only be created from <Route> components'
  );

  var name = routeComponent.props.name;
  var pattern = routeComponent.props.path || name;
  var router = new Router(pattern, name, routeComponent.props.handler);

  // Hang on to any extra properties that were passed to the component.
  router._componentProps = Route.getUnreservedProps(routeComponent.props);

  React.Children.forEach(routeComponent.props.children, function (child) {
    router.childRouters.push(Router.fromComponent(child));
  });

  return router;
};

mergeInto(Router.prototype, {

  /**
   * Adds a child router with the given arguments to this router and returns the
   * newly created child router.
   */
  route: function (name, path, handler, callback) {
    var router = new Router(name, path, handler, callback);
    this.childRouters.push(router);
    return router;
  },

  /**
   * Searches this Router and its subtree depth-first for a Router that matches on
   * the given path. Returns an array of all routes in the tree leading to the one
   * that matched in the format { route, params } where params is an object that
   * contains the URL parameters relevant to that route. Returns null if no Router
   * in the tree matches the path.
   */
  match: function (currentPath) {
    var childRouters = this.childRouters, match;

    // Search the subtree first to find the most deeply-nested route.
    for (var i = 0, length = childRouters.length; i < length; ++i) {
      match = childRouters[i].match(currentPath);

      if (match) {
        var rootMatch = match[match.length - 1];
        var rootRouter = rootMatch.router;
        var rootParams = rootMatch.params;

        var paramNames = path.extractParamNames(this.pattern);
        var params = {};

        paramNames.forEach(function (paramName) {
          // Ensure the child route contains all dynamic segments in this route.
          // TODO: We should probably do this when routes are first declared.
          invariant(
            rootParams[paramName],
            'Router pattern "' + rootRouter.pattern + '" does not contain all parameters ' +
            'of its ancestor pattern "' + this.pattern + '", so they cannot be nested'
          );

          params[paramName] = rootParams[paramName];
        });

        match.unshift(makeMatch(this, params));

        return match;
      }
    }

    // No routes in the subtree matched, so check this route.
    var params = path.extractParams(this.pattern, currentPath);

    if (params)
      return [ makeMatch(this, params) ];

    return null;
  },

  /**
   * Returns a hash of props that should be passed to this router's component
   * given the current URL path.
   */
  getComponentProps: function (currentPath) {
    var match = this.match(path.withoutQuery(currentPath));
    var query = path.extractQuery(currentPath) || {};

    warning(
      !(currentPath && !match),
      'No routes matched path "' + currentPath + '"'
    );

    if (!match)
      return {};

    return match.reduceRight(function (childProps, m) {
      var props = makeProps(m.router, m.params, query);

      if (childProps && childProps.handler) {
        props.activeRoute = childProps.handler(childProps);
      } else {
        // Make sure transitioning to the same path with new
        // params causes an update.
        props.key = currentPath;
      }

      return props;
    }, null);
  },

  /**
   * Renders this router's component to the given DOM node.
   *
   *   AppRouter.renderComponent(document.body);
   */
  renderComponent: function (node) {
    if (!this._component) {
      if (!urlStore.isSetup() && ExecutionEnvironment.canUseDOM)
        urlStore.setup('hash');

      urlStore.addChangeListener(function () {
        this._updateComponentProps(urlStore.getCurrentPath());
      }.bind(this));
    }

    var component = this.handler(this.getComponentProps(urlStore.getCurrentPath()));

    this._component = React.renderComponent(component, node);
  },

  _updateComponentProps: function (currentPath) {
    this._component.setProps(this.getComponentProps(currentPath));
  },

  toString: function () {
    return '<' + this.displayName + '>';
  }

});

function makeMatch(router, params) {
  return { router: router, params: params };
}

function componentToString(component) {
  return component.type.displayName || 'UnnamedComponent';
}

function makeProps(router, params, query) {
  var props = {
    handler: router.handler,
    params: params,
    query: query
  };

  if (router._componentProps)
    return merge(router._componentProps, props);

  return props;
}

module.exports = Router;
<commit_msg>Update some docs and method names<commit_after>var React = require('react');
var merge = require('react/lib/merge');
var mergeInto = require('react/lib/mergeInto');
var invariant = require('react/lib/invariant');
var warning = require('react/lib/warning');
var ExecutionEnvironment = require('react/lib/ExecutionEnvironment');
var path = require('./path');
var urlStore = require('./stores/url-store');

var _lookupTable = {};

/**
 * A Router specifies a component that will be rendered to the page when the URL
 * matches a given pattern. Routers may also be named, which makes it easy for
 * <Link> components to link to them.
 *
 * Routers are arranged in a nested tree structure. Likewise, when a router's component
 * is rendered, it is nested inside all components of its ancestor routers.
 *
 * Unlike Ember, a nested router's URL pattern does not build upon that of its parents.
 * This may seem like it creates more work up front in specifying URL patterns, but it
 * has the nice benefit of decoupling nested UI from nested URL segments.
 *
 * The recommended usage is:
 *
 *   Router(
 *     <Route handler={App}>
 *       <Route name="login" handler={Login}/>
 *       <Route name="logout" handler={Logout}/>
 *       <Route name="about" handler={About}/>
 *     </Route>
 *   ).renderComponent(document.body);
 *
 * If you don't use JSX, you can also assemble a Router programmatically. The following
 * JavaScript produces an identical result to the JSX above:
 *
 *   Router('/', App, function (route) {
 *     route('/login', 'login', Login);
 *     route('/logout', 'logout', Logout);
 *     route('/about', 'about', About);
 *   }).renderComponent(document.body);
 */
function Router(pattern, name, handler, callback) {
  // Support Router(<Route>) usage.
  if (React.isValidComponent(pattern))
    return Router.fromRouteComponent(pattern);

  // Support Router(...) usage, without new.
  if (!(this instanceof Router))
    return new Router(pattern, name, handler, callback);

  // Support Router('/', App) usage, without a name.
  if (React.isValidComponent(name)) {
    callback = handler;
    handler = name;
    name = null;
  }

  pattern = pattern ? path.normalize(pattern) : '';

  // For now, the handler must be a React component. We could possibly
  // swap this out with a RouteHandler object for more advanced usage.
  invariant(
    React.isValidComponent(handler),
    'Router "' + name + '" must have a valid React component for a handler'
  );

  this.displayName = getComponentDisplayName(handler) + 'Router';

  // If this router has a name, store it for lookup by <Link> components.
  if (name) {
    invariant(
      !_lookupTable[name],
      'You cannot use the name "' + name + '" for more than one router'
    );

    _lookupTable[name] = this;
  }

  this.pattern = pattern;
  this.name = name;
  this.handler = handler;
  this.childRouters = [];

  if (typeof callback === 'function') {
    invariant(
      callback.length === 1,
      'A Router callback should have one argument, a function that is usually named "route". ' +
      'You may have forgotten to include this argument when writing out nested routers like ' +
      'Router("/", App, function (/* missing "route" argument here! */) { ... })'
    );

    callback(this.route.bind(this));
  }
}

/**
 * Returns the router with the given name.
 */
Router.lookup = function (name) {
  return _lookupTable[name];
};

var Route = require('./components/route');

/**
 * A convenience method that creates a Router from a <Route> component. This allows
 * you to use JSX to describe your route hierarchy instead of the JavaScript API.
 *
 *   var AppRouter = Router.fromRouteComponent(
 *     <Route handler={App}>
 *       <Route name="login" handler={Login}/>
 *       <Route name="logout" handler={Logout}/>
 *       <Route name="about" handler={About}/>
 *     </Route>
 *   );
 */
Router.fromRouteComponent = function (routeComponent) {
  invariant(
    routeComponent.type === Route.type,
    'A Router may only be created from <Route> components'
  );

  var name = routeComponent.props.name;
  var pattern = routeComponent.props.path || name;
  var router = new Router(pattern, name, routeComponent.props.handler);

  // Hang on to any extra properties that were passed to the component.
  router._componentProps = Route.getUnreservedProps(routeComponent.props);

  React.Children.forEach(routeComponent.props.children, function (child) {
    router.childRouters.push(Router.fromRouteComponent(child));
  });

  return router;
};

mergeInto(Router.prototype, {

  /**
   * Adds a child router with the given arguments to this router and returns the
   * newly created child router.
   */
  route: function (name, path, handler, callback) {
    var router = new Router(name, path, handler, callback);
    this.childRouters.push(router);
    return router;
  },

  /**
   * Searches this Router and its subtree depth-first for a Router that matches on
   * the given path. Returns an array of all routes in the tree leading to the one
   * that matched in the format { route, params } where params is an object that
   * contains the URL parameters relevant to that route. Returns null if no Router
   * in the tree matches the path.
   *
   *   var AppRouter = Router(
   *     <Route handler={App}>
   *       <Route name="posts" handler={Posts}>
   *         <Route name="newPost" path="/posts/new" handler={NewPost}/>
   *         <Route name="showPost" path="/posts/:id" handler={Post}/>
   *       </Route>
   *     </Route>
   *   );
   *
   *   AppRouter.match('/posts/123'); => [ { router: <AppRouter>, params: {} },
   *                                       { router: <PostsRouter>, params: {} },
   *                                       { router: <PostRouter>, params: { id: '123' } } ]
   */
  match: function (currentPath) {
    var childRouters = this.childRouters, match;

    // Search the subtree first to find the most deeply-nested route.
    for (var i = 0, length = childRouters.length; i < length; ++i) {
      match = childRouters[i].match(currentPath);

      if (match) {
        var rootMatch = match[match.length - 1];
        var rootRouter = rootMatch.router;
        var rootParams = rootMatch.params;

        var paramNames = path.extractParamNames(this.pattern);
        var params = {};

        paramNames.forEach(function (paramName) {
          // Ensure the child route contains all dynamic segments in this route.
          // TODO: We should probably do this when routes are first declared.
          invariant(
            rootParams[paramName],
            'Router pattern "' + rootRouter.pattern + '" does not contain all parameters ' +
            'of its ancestor pattern "' + this.pattern + '", so they cannot be nested'
          );

          params[paramName] = rootParams[paramName];
        });

        match.unshift(makeMatch(this, params));

        return match;
      }
    }

    // No routes in the subtree matched, so check this route.
    var params = path.extractParams(this.pattern, currentPath);

    if (params)
      return [ makeMatch(this, params) ];

    return null;
  },

  /**
   * Returns a hash of props that should be passed to this router's component
   * given the current URL path.
   */
  getComponentProps: function (currentPath) {
    var match = this.match(path.withoutQuery(currentPath));
    var query = path.extractQuery(currentPath) || {};

    warning(
      !(currentPath && !match),
      'No routes matched path "' + currentPath + '"'
    );

    if (!match)
      return {};

    return match.reduceRight(function (childProps, m) {
      var props = makeProps(m.router, m.params, query);

      if (childProps && childProps.handler) {
        props.activeRoute = childProps.handler(childProps);
      } else {
        // Make sure transitioning to the same path with new
        // params causes an update.
        props.key = currentPath;
      }

      return props;
    }, null);
  },

  /**
   * Renders this router's component to the given DOM node.
   */
  renderComponent: function (node) {
    if (!this._component) {
      if (!urlStore.isSetup() && ExecutionEnvironment.canUseDOM)
        urlStore.setup('hash');

      urlStore.addChangeListener(function () {
        this._updateComponentProps(urlStore.getCurrentPath());
      }.bind(this));
    }

    var component = this.handler(this.getComponentProps(urlStore.getCurrentPath()));

    this._component = React.renderComponent(component, node);
  },

  _updateComponentProps: function (currentPath) {
    this._component.setProps(this.getComponentProps(currentPath));
  },

  toString: function () {
    return '<' + this.displayName + '>';
  }

});

function getComponentDisplayName(component) {
  return component.type.displayName || 'UnnamedComponent';
}

function makeMatch(router, params) {
  return { router: router, params: params };
}

function makeProps(router, params, query) {
  var props = {
    handler: router.handler,
    params: params,
    query: query
  };

  if (router._componentProps)
    return merge(router._componentProps, props);

  return props;
}

module.exports = Router;
<|endoftext|>


<commit_before>// Packages
const { send } = require('micro')
const { valid, gt } = require('semver')
const { parse } = require('express-useragent')

// Utilities
const { loadCache } = require('./cache')

exports.download = (req, res) => {
  const userAgent = parse(req.headers['user-agent'])
  let platform

  if (userAgent.isMac) {
    platform = 'darwin'
  } else if (userAgent.isWindows) {
    platform = 'win32'
  }

  // Get the latest version from the cache
  const { platforms } = loadCache()

  if (!platform || !platforms || !platforms[platform]) {
    send(res, 200, 'No download available for your platform!')
    return
  }

  res.writeHead(302, {
    Location: platforms[platform]
  })

  res.end()
}

exports.downloadPlatform = (req, res) => {
  const { platform } = req.params

  // Get the latest version from the cache
  const latest = loadCache()

  if (!latest.platforms || !latest.platforms[platform]) {
    send(res, 404, 'Release not available yet!')
    return
  }

  res.writeHead(302, {
    Location: latest.platforms[platform]
  })

  res.end()
}

exports.update = (req, res) => {
  const { platform, version } = req.params

  if (!valid(version)) {
    send(res, 500, {
      error: 'version_invalid',
      message: 'The specified version is not SemVer-compatible'
    })

    return
  }

  // Get the latest version from the cache
  const latest = loadCache()

  if (!latest.platforms || !latest.platforms[platform]) {
    res.statusCode = 204
    res.end()

    return
  }

  if (gt(latest.version, version)) {
    const { notes, pub_date } = latest

    send(res, 200, {
      name: latest.version,
      notes,
      pub_date,
      url: latest.platforms[platform]
    })

    return
  }

  res.statusCode = 204
  res.end()
}
<commit_msg>Make /download and /download/:platform respond the same for empty cache<commit_after>// Packages
const { send } = require('micro')
const { valid, gt } = require('semver')
const { parse } = require('express-useragent')

// Utilities
const { loadCache } = require('./cache')

exports.download = (req, res) => {
  const userAgent = parse(req.headers['user-agent'])
  let platform

  if (userAgent.isMac) {
    platform = 'darwin'
  } else if (userAgent.isWindows) {
    platform = 'win32'
  }

  // Get the latest version from the cache
  const { platforms } = loadCache()

  if (!platform || !platforms || !platforms[platform]) {
    send(res, 404, 'No download available for your platform!')
    return
  }

  res.writeHead(302, {
    Location: platforms[platform]
  })

  res.end()
}

exports.downloadPlatform = (req, res) => {
  const { platform } = req.params

  // Get the latest version from the cache
  const latest = loadCache()

  if (!latest.platforms || !latest.platforms[platform]) {
    send(res, 404, 'No download available for your platform!')
    return
  }

  res.writeHead(302, {
    Location: latest.platforms[platform]
  })

  res.end()
}

exports.update = (req, res) => {
  const { platform, version } = req.params

  if (!valid(version)) {
    send(res, 500, {
      error: 'version_invalid',
      message: 'The specified version is not SemVer-compatible'
    })

    return
  }

  // Get the latest version from the cache
  const latest = loadCache()

  if (!latest.platforms || !latest.platforms[platform]) {
    res.statusCode = 204
    res.end()

    return
  }

  if (gt(latest.version, version)) {
    const { notes, pub_date } = latest

    send(res, 200, {
      name: latest.version,
      notes,
      pub_date,
      url: latest.platforms[platform]
    })

    return
  }

  res.statusCode = 204
  res.end()
}
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var surveys = require('./controllers/surveys');
var responses = require('./controllers/responses');
var forms = require('./controllers/forms');
var users = require('./controllers/users');
var features = require('./controllers/features');
var parcels = require('./controllers/parcels');
var orgs = require('./controllers/orgs');

function formatHelper(format) {
  return function setFormat(req, res, next) {
    res.locals.format = format;
    next();
  };
}

function enforceHTTPS(req, res, next) {
  if (!req.secure) {
    res.send(400);
    return;
  }
  next();
}

exports.setup = function setup(app) {
  // Surveys
  app.get('/api/surveys', users.ensureAuthenticated, surveys.list);
  app.get('/api/surveys/:surveyId', surveys.get);
  app.post('/api/surveys', users.ensureAuthenticated, surveys.post);
  app.put('/api/surveys/:surveyId', users.ensureAuthenticated, users.ensureSurveyAccess, surveys.put);
  app.get('/api/surveys/:surveyId/stats', surveys.stats);
  app.get('/api/slugs/:slug', surveys.getSlug);

  // Responses
  app.get('/api/surveys/:surveyId/responses', responses.list);
  app.get('/api/surveys/:surveyId/responses.geojson', formatHelper('geojson'), responses.list);
  app.get('/api/surveys/:surveyId/responses/:responseId', responses.get);
  app.del('/api/surveys/:surveyId/responses/:responseId', users.ensureAuthenticated, users.ensureSurveyAccess, responses.del);
  app.post('/api/surveys/:surveyId/responses', responses.post);
  app.get('/api/surveys/:surveyId/responses.csv', responses.sendCSV);
  app.get('/api/surveys/:surveyId/responses.kml', responses.sendKML);
  app.get('/api/surveys/:surveyId/responses.zip', responses.handleShapefile);

  // Forms
  app.get('/api/surveys/:surveyId/forms', forms.list);
  app.get('/api/surveys/:surveyId/forms/:formId', forms.get);
  app.post('/api/surveys/:surveyId/forms', users.ensureAuthenticated, users.ensureSurveyAccess,  forms.post);
  app.put('/api/surveys/:surveyId/forms/:formId', users.ensureAuthenticated, users.ensureSurveyAccess, forms.put);

  // Users
  app.get('/api/user', users.ensureAuthenticated, users.get);
  app.post('/api/user', enforceHTTPS, users.post);
  app.post('/api/login', enforceHTTPS, users.login);
  app.get('/logout', users.logout);
  app.get('/auth/return', users.auth_return);
  app.post('/api/user/forgot', users.forgotPassword);
  app.post('/api/user/reset', enforceHTTPS, users.resetPassword);

  // Orgs
  app.get('/api/orgs', orgs.list);
  app.get('/api/orgs/:orgId', users.ensureAuthenticated, orgs.get);
  app.post('/api/orgs', users.ensureAuthenticated, orgs.post);
  app.put('/api/orgs/:orgId', users.ensureAuthenticated, orgs.put);
  app.get('/api/users/:user/orgs', users.ensureAuthenticated, orgs.list);
  app.get('/api/user/orgs', users.ensureAuthenticated, orgs.listForCurrentUser);

  // Base geo features
  app.get('/api/features', features.useCache, features.get);
  app.get('/api/features.geojson', features.useCache, features.get);

  // Parcels
  app.get('/api/parcels', parcels.get);
  app.get('/api/parcels.geojson', parcels.useCache, parcels.getGeoJSON);

  // Dummy ping endpoint
  app.get('/ping', function (req, res) {
    req.session = null;
    res.send();
  });
};
<commit_msg>Enforce ownership on export<commit_after>/*jslint node: true */
'use strict';

var surveys = require('./controllers/surveys');
var responses = require('./controllers/responses');
var forms = require('./controllers/forms');
var users = require('./controllers/users');
var features = require('./controllers/features');
var parcels = require('./controllers/parcels');
var orgs = require('./controllers/orgs');

function formatHelper(format) {
  return function setFormat(req, res, next) {
    res.locals.format = format;
    next();
  };
}

function enforceHTTPS(req, res, next) {
  if (!req.secure) {
    res.send(400);
    return;
  }
  next();
}

exports.setup = function setup(app) {
  // Surveys
  app.get('/api/surveys', users.ensureAuthenticated, surveys.list);
  app.get('/api/surveys/:surveyId', surveys.get);
  app.post('/api/surveys', users.ensureAuthenticated, surveys.post);
  app.put('/api/surveys/:surveyId', users.ensureAuthenticated, users.ensureSurveyAccess, surveys.put);
  app.get('/api/surveys/:surveyId/stats', surveys.stats);
  app.get('/api/slugs/:slug', surveys.getSlug);

  // Responses
  app.get('/api/surveys/:surveyId/responses', responses.list);
  app.get('/api/surveys/:surveyId/responses.geojson', formatHelper('geojson'), responses.list);
  app.get('/api/surveys/:surveyId/responses/:responseId', responses.get);
  app.del('/api/surveys/:surveyId/responses/:responseId', users.ensureAuthenticated, users.ensureSurveyAccess, responses.del);
  app.post('/api/surveys/:surveyId/responses', responses.post);
  app.get('/api/surveys/:surveyId/responses.csv', users.ensureAuthenticated, users.ensureSurveyAccess, responses.sendCSV);
  app.get('/api/surveys/:surveyId/responses.kml', users.ensureAuthenticated, users.ensureSurveyAccess, responses.sendKML);
  app.get('/api/surveys/:surveyId/responses.zip', users.ensureAuthenticated, users.ensureSurveyAccess, responses.handleShapefile);

  // Forms
  app.get('/api/surveys/:surveyId/forms', forms.list);
  app.get('/api/surveys/:surveyId/forms/:formId', forms.get);
  app.post('/api/surveys/:surveyId/forms', users.ensureAuthenticated, users.ensureSurveyAccess,  forms.post);
  app.put('/api/surveys/:surveyId/forms/:formId', users.ensureAuthenticated, users.ensureSurveyAccess, forms.put);

  // Users
  app.get('/api/user', users.ensureAuthenticated, users.get);
  app.post('/api/user', enforceHTTPS, users.post);
  app.post('/api/login', enforceHTTPS, users.login);
  app.get('/logout', users.logout);
  app.get('/auth/return', users.auth_return);
  app.post('/api/user/forgot', users.forgotPassword);
  app.post('/api/user/reset', enforceHTTPS, users.resetPassword);

  // Orgs
  app.get('/api/orgs', orgs.list);
  app.get('/api/orgs/:orgId', users.ensureAuthenticated, orgs.get);
  app.post('/api/orgs', users.ensureAuthenticated, orgs.post);
  app.put('/api/orgs/:orgId', users.ensureAuthenticated, orgs.put);
  app.get('/api/users/:user/orgs', users.ensureAuthenticated, orgs.list);
  app.get('/api/user/orgs', users.ensureAuthenticated, orgs.listForCurrentUser);

  // Base geo features
  app.get('/api/features', features.useCache, features.get);
  app.get('/api/features.geojson', features.useCache, features.get);

  // Parcels
  app.get('/api/parcels', parcels.get);
  app.get('/api/parcels.geojson', parcels.useCache, parcels.getGeoJSON);

  // Dummy ping endpoint
  app.get('/ping', function (req, res) {
    req.session = null;
    res.send();
  });
};
<|endoftext|>


<commit_before>const request = require('request')
const Store = require('./store')

const env = process.env
const globalConfig = new Store

module.exports = CucumberRunner

function CucumberRunner() {
  var apitance = CucumberRunner.currentApitanceInstance

  // Register steps in Cucumber instance
  apitance.defineSteps(this.defineStep.bind(this))

  this.World = function (done) {
    apitance.world.extend(this)

    this.req = {}
    this.res = null
    this.error = null

    this.vars = new Store
    this.config = new Store
    this.global = globalConfig
    this.apitance = apitance
    this.http = request

    done()
  }
}

/**
 * We use this static member to pass the reference
 * between Cucumber and latest Apitance instance
 */

CucumberRunner.currentApitanceInstance = null
<commit_msg>feat(core): improve steps load, minor refactors<commit_after>const request = require('request')
const Store = require('./store')

const env = process.env
const globalConfig = new Store

module.exports = CucumberRunner

function CucumberRunner() {
  var apitance = CucumberRunner.currentApitanceInstance

  console.log(this)

  // Register steps in Cucumber instance
  apitance.defineSteps(this.defineStep.bind(this))

  this.World = function (done) {
    apitance.world.extend(this)

    this.req = {}
    this.res = null
    this.error = null

    this.vars = new Store
    this.config = new Store
    this.global = globalConfig
    this.apitance = apitance
    this.http = request

    done()
  }
}

/**
 * We use this static member to pass the reference
 * between Cucumber and latest Apitance instance
 */

CucumberRunner.currentApitanceInstance = null
<|endoftext|>


<commit_before>var fs    = require("fs"),
    _     = require("lodash"),
    async = require("async"),
    assert= require('assert'),
    registration = require('./registration.js'),
    jstat = require('jStat').jStat

var _testcaseTemplate;
var _suiteTemplate;
var _responseTimes = [];

var _suiteResults = {
  name : "Default",
  errorCount: 0,
  failureCount: 0,
  testCount: 0
}

exports.makeTimeLog = function(){
  var times = {}
  function log_time(key){ times[key] = new Date().getTime() }
  log_time("start")
  return {
    log:          log_time,
    clock:        function(k)  { return times[k] },
    fromStart:    function(k)  { return times[k] - times["start"] },
    diff:         function(f,s){ return times[s] - times[f] },
    keys:         function()   { return _.keys(times) }
  }
}

var getStats = function() {
  var arrlen = _responseTimes.length,
      arr = _responseTimes.slice().sort(function(a,b) { return a-b });

  if(arrlen == 0) { return {} }

  var jobj = jstat(arr);
  return {
    count:  arrlen,
    min:    arr[0],
    max:    arr[arrlen-1],
    avg:    jobj.mean(),
    stdev:  jobj.stdev(),
    meddev: jobj.meddev(),
    p50:    arr[ Math.round((arrlen) * 1 / 2) - 1 ],
    p75:    arr[ Math.round((arrlen) * 3 / 4) - 1 ],
    p90:    arr[ Math.round((arrlen) * 9 / 10) - 1 ],
    p95:    arr[ Math.round((arrlen) * 95 / 100) - 1 ],
    p99:    arr[ Math.round((arrlen) * 99 / 100) - 1 ]
  }
}

var red = function(str){return "\x1b[31m" + str + "\x1b[39m"};
var green = function(str){return "\x1b[32m" + str + "\x1b[39m"};
var bold = function(str){return "\x1b[1m" + str + "\x1b[22m"};

var _firstTestDefinition = true
exports.runTest = function(testDefinition, callback) {
  var time = exports.makeTimeLog()
  var runtimeDefinition = _.merge({}, exports.runOptions.defaultTestDefinition, testDefinition)

  // We're being really flexible here:
  //   testUrl or testUrls
  //   string or array of strings or function returning either a string or an array of strings
  //   a single string can even be multiple URLs, semicolon-delimited
  // As long as we end up with an array of URL strings, we're good
  var testUrls = runtimeDefinition.testUrls || runtimeDefinition.testUrl
  testUrls = (_.isFunction(runtimeDefinition.testUrls)) ? runtimeDefinition.testUrls() : runtimeDefinition.testUrls
  if(_.isString(runtimeDefinition.testUrls)) {
    testUrls = testUrls.split(';')
  }
  delete runtimeDefinition.testUrl
  runtimeDefinition.testUrls = testUrls

  if(exports.runOptions.disableAssertions) {
    delete runtimeDefinition.assert
  }

  // Now we can serialize runtimeDefinition to the repro log
  // console.log(runtimeDefinition)
  if(exports.loggers.reproLog) {
    var reproLine = "  " + JSON.stringify(runtimeDefinition)
    if(_firstTestDefinition) {
      _firstTestDefinition = false
    } else {
      reproLine = ",\n" + reproLine
    }
    exports.loggers.reproLog.write(reproLine)
  }

  var driverName = runtimeDefinition.driver || 'nodeRequest'
  var driver = registration.getDriver(driverName)

  var testcaseResult = {
    name: testDefinition.name || testUrls.join(" "),
    failures: [],
    errors: []
  }

  var verboseTrace = ""
  var endpointTasks = _.map( testUrls, function(url) {
    return function(cb) {
      driver.run(url, runtimeDefinition.driverOptions, time, exports.loggers, function(response) {
        _responseTimes.push(response.responseTime);

        if (runtimeDefinition.driverOptions.consoleTestDefinition){
          console.log(runtimeDefinition);
        }

        // Handle response assertions
        _.each(runtimeDefinition.assert, function(a) {
          // console.log("Asserting '" + a.check + "' - expecting: " + a.expect)
          try {
            registration.getAssertion(a.check)(response, a.expect, url)
          } catch(e) {
            if(e && e.message) {
              verboseTrace += red("FAILED: ") + "assert " + a.check + '\n'
              verboseTrace += url + '\n' + e.message + '\n'
              testcaseResult.failures.push({
                message: "FAILED assert " + a.check + ": " + url,
                type: 'assert:' + a.check,
                backtrace: e.stack
              })
            } else {
              verboseTrace += red("ERROR: ") + e + '\n'
              testcaseResult.errors.push({
                message: "ERROR: " + e ,
                type: 'assert:' + a.check,
                backtrace: "assert:" + a.check + ": " + url
              })

            }
          }
        })

        cb(null, response)
      })

    }
  })

  var endTime, startTime = new Date().getTime()

  async.parallel( endpointTasks, function(err, results) {
      // Compare results from multiple endpoints
      if( results.length > 1 ) {
        _.each(runtimeDefinition.compare, function(c){
          try {
            registration.getComparator(c)(results, runtimeDefinition.testUrls)
          } catch(e) {
            verboseTrace += red("FAILED: ") + "compare " + c + '\n' + testUrls.join("\n") + '\n'
            if(e && e.message) {
              verboseTrace += e.message + '\n'
              testcaseResult.failures.push({
                message: "FAILED compare:" + c + ": " + testUrls.join(" "),
                type: 'compare:' + c,
                backtrace: e.stack
              })
            } else {
              verboseTrace += red("ERROR: ") + e + '\n'
              testcaseResult.errors.push({
                message: "ERROR: " + e ,
                type: 'compare:' + c,
                backtrace: "compare:" + c + ": \n" + testUrls.join("\n")
              })
            }

          }
        })
      }

      endTime = new Date().getTime()
      testcaseResult.duration = endTime - startTime

      _suiteResults.testCount += 1
      if(testcaseResult.errors.length > 0) {
        _suiteResults.errorCount += 1
        console.log(red('✖ ') + testDefinition.name)
      } else if (testcaseResult.failures.length > 0) {
        _suiteResults.failureCount += 1
        console.log(red('✖ ') + testDefinition.name)
      } else {
        console.log(green('✔ ') + testDefinition.name)
      }
      if(verboseTrace) {
        console.log(verboseTrace)
      }

      // JUnit Logging
      if( exports.runOptions.junitLog) {
        exports.loggers.junitResults.write(_testcaseTemplate({testcase: testcaseResult}))
      }

      callback()
  })
}

exports.run = function(options, callback){
  _testcaseTemplate = _.template(fs.readFileSync(__dirname + '/templates/junit-testcase.xml').toString())
  _suiteTemplate = _.template(fs.readFileSync(__dirname + '/templates/junit-suite.xml').toString())

  _suiteResults.name = options.name;
  exports.runOptions = options;
  exports.loggers = {};

  exports.loggers.responsePerfFile = fs.createWriteStream(
    "output/perf/responsePerf.tsv",
    { flags: 'a'}
  )
  exports.loggers.domPerfFile = fs.createWriteStream(
    "output/perf/domPerf.tsv",
    { flags: 'a'}
  )

  if(options.reproLog) {
    exports.loggers.reproLog = fs.createWriteStream(
      options.reproLog,
      { flags: 'w+' }
    )
    exports.loggers.reproLog.write('[\n')
  }

  if(options.junitLog) {
    exports.loggers.junitResults = fs.createWriteStream(
      options.junitLog + '.tmp',
      { flags: 'w+' }
    )
  }

  var generator = registration.getGenerator(options.generatorContext.name)
  generator.init(options.generatorContext)

  var testsStarted = 0
  var concurrency = options.concurrency || 1
  var totalRequests, testsRemaining
  var startTime, endTime

  var q = async.queue( function(test, callback) {
    try {
      exports.runTest(test, callback)
    } catch(e) {
      console.log("RUNNER EXCEPTION during test execution:")
      console.log(test)
      console.log(e)
    }
  }, concurrency )

  var enqueueTests = function(tests) {
    if(tests.length === 0) {
      console.log("Nothing to enqueue")
      return;
    }
    var nextTests = tests.slice(0, testsRemaining)
    nextTests = _.map(nextTests, function(test) {
      // I'm not carrying around a bag of junk properties just cuz your generator doesn't follow spec
      return _.pick(test,
        'name',           // OPTIONAL: name of test case
        'testUrl',        // REQUIRED*: URL to test
        'testUrls',       // REQUIRED*: Alternative to testUrl
        'driver',         // OPTIONAL: driver responsible for issuing request (default = nodeRequest)
        'driverOptions',  // OPTIONAL: options passed through to the driver
        'assert',         // OPTIONAL: assertion to execute against the response object
        'compare'         // OPTIONAL: comparator to execute against a set of response objects (if testUrls.length > 1)
      )
    })

    testsStarted += nextTests.length
    testsRemaining = totalRequests - testsStarted

    console.log('Queueing ' + nextTests.length + ' tests now. Total queued so far: ' + testsStarted + ' of ' + totalRequests + ' tests.')
    q.push(nextTests)
  }

  // use to delay execution when the generator is starving us
  var withNextTests = function(cb) {
    if(!generator.hasNextTests()) {
      cb([])
    }

    var next = generator.getNextTests()
    if(next.length === 0) {
      setImmediate( function() { withNextTests(cb) } )
    } else {
      cb(next)
    }
  }

  q.empty = function(){
    if (testsRemaining > 0 && generator.hasNextTests()) {
      var tests = generator.getNextTests()

      if(tests.length === 0) {
        console.log("WARNING: concurrency dropping - test generator is starving the test runner")
        return withNextTests(enqueueTests)
      }

      enqueueTests(tests)
    }
  }

  q.drain = function(){
    if(testsRemaining > 0 && generator.hasNextTests()) {
      console.log("WARNING: test queue has been drained early - starving with 0 outstanding requests - waiting VERY patiently")
      return withNextTests(enqueueTests)
    }

    endTime = new Date().getTime()
    _suiteResults.duration = endTime - startTime

    if(options.reproLog) {
      exports.loggers.reproLog.write('\n]\n')
    }

    if(options.junitLog) {
      var loggedResults = fs.readFileSync(options.junitLog + '.tmp').toString()
      var junitLog = _suiteTemplate( { suite: _suiteResults, testcases: loggedResults } )
      fs.writeFileSync(options.junitLog, junitLog, { flags: 'w+' })
      fs.unlinkSync(options.junitLog + '.tmp')
    }

    _suiteResults.stats = getStats()

    var formatRollup = (_suiteResults.failureCount === 0 && _suiteResults.errorCount === 0) ? green : red
    console.log(formatRollup("Completed " + _suiteResults.testCount + " tests. " +
      _suiteResults.failureCount + " failures and "+ _suiteResults.errorCount + " errors in " +
      _suiteResults.duration/1000 + " seconds."))

    callback(_suiteResults)
  }

  // This is a bit ugly, but basically delays calling enqueueTests
  // until we've generated at least enough tests to feed the concurrency
  // otherwise we'll be starving the queue from the start
  if(generator.hasNextTests()) {
    var initialTests = []
    var buildInitialQueue = function(tests) {
      if(tests.length > 0) {
        initialTests = initialTests.concat(tests)
        console.log("Adding " + tests.length + " to initial tests. " + initialTests.length + " total ready.")
      }
      if(initialTests.length < options.concurrency && generator.hasNextTests()) {
        withNextTests( buildInitialQueue )
      } else {
        console.log("Ready to start testing.")

        totalRequests = options.totalRequests || initialTests.length
        testsRemaining = totalRequests
        startTime = new Date().getTime()
        enqueueTests(initialTests)
      }
    }
    buildInitialQueue([])
  }
}
<commit_msg>support shuffling tests in batches<commit_after>var fs    = require("fs"),
    _     = require("lodash"),
    async = require("async"),
    assert= require('assert'),
    registration = require('./registration.js'),
    jstat = require('jStat').jStat

var _testcaseTemplate;
var _suiteTemplate;
var _responseTimes = [];

var _suiteResults = {
  name : "Default",
  errorCount: 0,
  failureCount: 0,
  testCount: 0
}

exports.makeTimeLog = function(){
  var times = {}
  function log_time(key){ times[key] = new Date().getTime() }
  log_time("start")
  return {
    log:          log_time,
    clock:        function(k)  { return times[k] },
    fromStart:    function(k)  { return times[k] - times["start"] },
    diff:         function(f,s){ return times[s] - times[f] },
    keys:         function()   { return _.keys(times) }
  }
}

var getStats = function() {
  var arrlen = _responseTimes.length,
      arr = _responseTimes.slice().sort(function(a,b) { return a-b });

  if(arrlen == 0) { return {} }

  var jobj = jstat(arr);
  return {
    count:  arrlen,
    min:    arr[0],
    max:    arr[arrlen-1],
    avg:    jobj.mean(),
    stdev:  jobj.stdev(),
    meddev: jobj.meddev(),
    p50:    arr[ Math.round((arrlen) * 1 / 2) - 1 ],
    p75:    arr[ Math.round((arrlen) * 3 / 4) - 1 ],
    p90:    arr[ Math.round((arrlen) * 9 / 10) - 1 ],
    p95:    arr[ Math.round((arrlen) * 95 / 100) - 1 ],
    p99:    arr[ Math.round((arrlen) * 99 / 100) - 1 ]
  }
}

var red = function(str){return "\x1b[31m" + str + "\x1b[39m"};
var green = function(str){return "\x1b[32m" + str + "\x1b[39m"};
var bold = function(str){return "\x1b[1m" + str + "\x1b[22m"};

var _firstTestDefinition = true
exports.runTest = function(testDefinition, callback) {
  var time = exports.makeTimeLog()
  var runtimeDefinition = _.merge({}, exports.runOptions.defaultTestDefinition, testDefinition)

  // We're being really flexible here:
  //   testUrl or testUrls
  //   string or array of strings or function returning either a string or an array of strings
  //   a single string can even be multiple URLs, semicolon-delimited
  // As long as we end up with an array of URL strings, we're good
  var testUrls = runtimeDefinition.testUrls || runtimeDefinition.testUrl
  testUrls = (_.isFunction(runtimeDefinition.testUrls)) ? runtimeDefinition.testUrls() : runtimeDefinition.testUrls
  if(_.isString(runtimeDefinition.testUrls)) {
    testUrls = testUrls.split(';')
  }
  delete runtimeDefinition.testUrl
  runtimeDefinition.testUrls = testUrls

  if(exports.runOptions.disableAssertions) {
    delete runtimeDefinition.assert
  }

  // Now we can serialize runtimeDefinition to the repro log
  // console.log(runtimeDefinition)
  if(exports.loggers.reproLog) {
    var reproLine = "  " + JSON.stringify(runtimeDefinition)
    if(_firstTestDefinition) {
      _firstTestDefinition = false
    } else {
      reproLine = ",\n" + reproLine
    }
    exports.loggers.reproLog.write(reproLine)
  }

  var driverName = runtimeDefinition.driver || 'nodeRequest'
  var driver = registration.getDriver(driverName)

  var testcaseResult = {
    name: testDefinition.name || testUrls.join(" "),
    failures: [],
    errors: []
  }

  var verboseTrace = ""
  var endpointTasks = _.map( testUrls, function(url) {
    return function(cb) {
      driver.run(url, runtimeDefinition.driverOptions, time, exports.loggers, function(response) {
        _responseTimes.push(response.responseTime);

        if (runtimeDefinition.driverOptions.consoleTestDefinition){
          console.log(runtimeDefinition);
        }

        // Handle response assertions
        _.each(runtimeDefinition.assert, function(a) {
          // console.log("Asserting '" + a.check + "' - expecting: " + a.expect)
          try {
            registration.getAssertion(a.check)(response, a.expect, url)
          } catch(e) {
            if(e && e.message) {
              verboseTrace += red("FAILED: ") + "assert " + a.check + '\n'
              verboseTrace += url + '\n' + e.message + '\n'
              testcaseResult.failures.push({
                message: "FAILED assert " + a.check + ": " + url,
                type: 'assert:' + a.check,
                backtrace: e.stack
              })
            } else {
              verboseTrace += red("ERROR: ") + e + '\n'
              testcaseResult.errors.push({
                message: "ERROR: " + e ,
                type: 'assert:' + a.check,
                backtrace: "assert:" + a.check + ": " + url
              })

            }
          }
        })

        cb(null, response)
      })

    }
  })

  var endTime, startTime = new Date().getTime()

  async.parallel( endpointTasks, function(err, results) {
      // Compare results from multiple endpoints
      if( results.length > 1 ) {
        _.each(runtimeDefinition.compare, function(c){
          try {
            registration.getComparator(c)(results, runtimeDefinition.testUrls)
          } catch(e) {
            verboseTrace += red("FAILED: ") + "compare " + c + '\n' + testUrls.join("\n") + '\n'
            if(e && e.message) {
              verboseTrace += e.message + '\n'
              testcaseResult.failures.push({
                message: "FAILED compare:" + c + ": " + testUrls.join(" "),
                type: 'compare:' + c,
                backtrace: e.stack
              })
            } else {
              verboseTrace += red("ERROR: ") + e + '\n'
              testcaseResult.errors.push({
                message: "ERROR: " + e ,
                type: 'compare:' + c,
                backtrace: "compare:" + c + ": \n" + testUrls.join("\n")
              })
            }

          }
        })
      }

      endTime = new Date().getTime()
      testcaseResult.duration = endTime - startTime

      _suiteResults.testCount += 1
      if(testcaseResult.errors.length > 0) {
        _suiteResults.errorCount += 1
        console.log(red('✖ ') + testDefinition.name)
      } else if (testcaseResult.failures.length > 0) {
        _suiteResults.failureCount += 1
        console.log(red('✖ ') + testDefinition.name)
      } else {
        console.log(green('✔ ') + testDefinition.name)
      }
      if(verboseTrace) {
        console.log(verboseTrace)
      }

      // JUnit Logging
      if( exports.runOptions.junitLog) {
        exports.loggers.junitResults.write(_testcaseTemplate({testcase: testcaseResult}))
      }

      callback()
  })
}

exports.run = function(options, callback){
  _testcaseTemplate = _.template(fs.readFileSync(__dirname + '/templates/junit-testcase.xml').toString())
  _suiteTemplate = _.template(fs.readFileSync(__dirname + '/templates/junit-suite.xml').toString())

  _suiteResults.name = options.name;
  exports.runOptions = options;
  exports.loggers = {};

  exports.loggers.responsePerfFile = fs.createWriteStream(
    "output/perf/responsePerf.tsv",
    { flags: 'a'}
  )
  exports.loggers.domPerfFile = fs.createWriteStream(
    "output/perf/domPerf.tsv",
    { flags: 'a'}
  )

  if(options.reproLog) {
    exports.loggers.reproLog = fs.createWriteStream(
      options.reproLog,
      { flags: 'w+' }
    )
    exports.loggers.reproLog.write('[\n')
  }

  if(options.junitLog) {
    exports.loggers.junitResults = fs.createWriteStream(
      options.junitLog + '.tmp',
      { flags: 'w+' }
    )
  }

  var generator = registration.getGenerator(options.generatorContext.name)
  generator.init(options.generatorContext)

  var testsStarted = 0
  var concurrency = options.concurrency || 1
  var totalRequests, testsRemaining
  var startTime, endTime

  var q = async.queue( function(test, callback) {
    try {
      exports.runTest(test, callback)
    } catch(e) {
      console.log("RUNNER EXCEPTION during test execution:")
      console.log(test)
      console.log(e)
    }
  }, concurrency )

  var enqueueTests = function(tests) {
    if(tests.length === 0) {
      console.log("Nothing to enqueue")
      return;
    }
    var nextTests = tests.slice(0, testsRemaining)
    nextTests = _.map(nextTests, function(test) {
      // I'm not carrying around a bag of junk properties just cuz your generator doesn't follow spec
      return _.pick(test,
        'name',           // OPTIONAL: name of test case
        'testUrl',        // REQUIRED*: URL to test
        'testUrls',       // REQUIRED*: Alternative to testUrl
        'driver',         // OPTIONAL: driver responsible for issuing request (default = nodeRequest)
        'driverOptions',  // OPTIONAL: options passed through to the driver
        'assert',         // OPTIONAL: assertion to execute against the response object
        'compare'         // OPTIONAL: comparator to execute against a set of response objects (if testUrls.length > 1)
      )
    })

    testsStarted += nextTests.length
    testsRemaining = totalRequests - testsStarted

    console.log('Queueing ' + nextTests.length + ' tests now. Total queued so far: ' + testsStarted + ' of ' + totalRequests + ' tests.')
    q.push(nextTests)
  }

  var shuffle = function(arr) {
    var cursor = arr.length
    var temp, randIndex

    while(0 != cursor) {
      randIndex = Math.floor(Math.random() * cursor)
      cursor -= 1
      temp = arr[cursor]
      arr[cursor] = arr[randIndex]
      arr[randIndex] = temp
    }

    return arr
  }

  // use to delay execution when the generator is starving us
  var withNextTests = function(cb) {
    if(!generator.hasNextTests()) {
      cb([])
    }

    var next = generator.getNextTests()
    if(options.shuffle) {
      next = shuffle(next)
    }
    if(next.length === 0) {
      setImmediate( function() { withNextTests(cb) } )
    } else {
      cb(next)
    }
  }

  q.empty = function(){
    if (testsRemaining > 0 && generator.hasNextTests()) {
      var tests = generator.getNextTests()

      if(options.shuffle) {
        next = shuffle(next)
      }

      if(tests.length === 0) {
        console.log("WARNING: concurrency dropping - test generator is starving the test runner")
        return withNextTests(enqueueTests)
      }

      enqueueTests(tests)
    }
  }

  q.drain = function(){
    if(testsRemaining > 0 && generator.hasNextTests()) {
      console.log("WARNING: test queue has been drained early - starving with 0 outstanding requests - waiting VERY patiently")
      return withNextTests(enqueueTests)
    }

    endTime = new Date().getTime()
    _suiteResults.duration = endTime - startTime

    if(options.reproLog) {
      exports.loggers.reproLog.write('\n]\n')
    }

    if(options.junitLog) {
      var loggedResults = fs.readFileSync(options.junitLog + '.tmp').toString()
      var junitLog = _suiteTemplate( { suite: _suiteResults, testcases: loggedResults } )
      fs.writeFileSync(options.junitLog, junitLog, { flags: 'w+' })
      fs.unlinkSync(options.junitLog + '.tmp')
    }

    _suiteResults.stats = getStats()

    var formatRollup = (_suiteResults.failureCount === 0 && _suiteResults.errorCount === 0) ? green : red
    console.log(formatRollup("Completed " + _suiteResults.testCount + " tests. " +
      _suiteResults.failureCount + " failures and "+ _suiteResults.errorCount + " errors in " +
      _suiteResults.duration/1000 + " seconds."))

    callback(_suiteResults)
  }

  // This is a bit ugly, but basically delays calling enqueueTests
  // until we've generated at least enough tests to feed the concurrency
  // otherwise we'll be starving the queue from the start
  if(generator.hasNextTests()) {
    var initialTests = []
    var buildInitialQueue = function(tests) {
      if(tests.length > 0) {
        initialTests = initialTests.concat(tests)
        console.log("Adding " + tests.length + " to initial tests. " + initialTests.length + " total ready.")
      }
      if(initialTests.length < options.concurrency && generator.hasNextTests()) {
        withNextTests( buildInitialQueue )
      } else {
        console.log("Ready to start testing.")

        totalRequests = options.totalRequests || initialTests.length
        testsRemaining = totalRequests
        startTime = new Date().getTime()
        enqueueTests(initialTests)
      }
    }
    buildInitialQueue([])
  }
}
<|endoftext|>


<commit_before>var map;
var story_points_list;
var story_pk = 0;
var markers = [];
var waypoints;

 $(document).ready(function() {

  // Get the story ID from HTML
  story_pk = $("#story_data").attr("pk");

  // Use the story PK to get JSON for this story!

  $.getJSON('/story_points_json/' + story_pk + '/', function(jd) {
    story_points_json = jd;
    var story_points = JSON.parse( story_points_json );
    for (i = 0; i < story_points.length; i++) {
      var x = story_points[i].fields.location_name;
    }
    story_points_list = story_points;

  initialize_map(story_points);

  });

  //google.maps.event.addDomListener(window, 'load', initialize);

  // Add the Waypoints to enable scrolling moves the map
  console.log("Adding waypoints");
  waypoints = $(".story_point").waypoint(function() {
      console.log('Reached waypoint: ' + this.element.id);
      var marker_id = Number(this.element.id) - 1;
      marker = markers[marker_id];
      panMap(marker, map);

  }, {
      context: $(".story_points").parent(),
      offset: "10"
  });

});

function initialize_map(story_points) {
  console.log("creating map");
  /*
  TODO:
    * Set the map to load centered at the latitude an longitude
      of the first story point
    * Build a marker for each storypoint

  */

  var center_lat = parseFloat(story_points[0].fields.latitude);
  var center_lng = parseFloat(story_points[0].fields.longitude);
  map = new google.maps.Map(document.getElementById("map"), {
      center: {lat: center_lat, lng: center_lng},
      zoom: 12
    });
  var infowindow = new google.maps.InfoWindow();

  var bounds = new google.maps.LatLngBounds();

  for (i = 0; i < story_points.length; i++) {
    var lat = parseFloat(story_points[i].fields.latitude);
    var lng = parseFloat(story_points[i].fields.longitude);
    var title = story_points[i].fields.title;
    var loc_name = story_points[i].fields.location_name;
    var text = story_points[i].fields.text;
    var num = story_points[i].fields.num_order;

    var contentString = '
'+
      '
'+
      '
'+
      '
' + loc_name + '
'+
      '
' + title + '
'+
      '
'+
      '
' + text + '
'+
      '
'+
      '
';

    var marker = new google.maps.Marker({
      position: {lat: lat, lng: lng},
      map: map,
      animation: google.maps.Animation.DROP,
      contentString: contentString,
      icon: '//chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + num + '|FE6256|000000'
    });

    marker.setValues({type: "point", id: num});
    markers.push(marker);

    bounds.extend(marker.getPosition());

    /*google.maps.event.addListener(marker, 'click', function() {
        //infowindow.setContent(this.contentString);
        //infowindow.open(map,this);
        console.log(marker);
        $('.scrollable').scrollTo($('#7'),1500);
    });*/

    attachListener(marker, num);

  };

  map.fitBounds(bounds);

}

function attachListener(marker, num) {
  marker.addListener('click', function() {
        console.log(num);
        $('.scrollable').scrollTo($('#' + num),1500);
  });
}

function panMap(marker, map) {
  map.setZoom(12)
  var latLng = marker.getPosition(); // returns LatLng object
  map.panTo(latLng); // setCenter takes a LatLng object
}

<commit_msg>Switched to secure URL for google chart API<commit_after>var map;
var story_points_list;
var story_pk = 0;
var markers = [];
var waypoints;

 $(document).ready(function() {

  // Get the story ID from HTML
  story_pk = $("#story_data").attr("pk");

  // Use the story PK to get JSON for this story!

  $.getJSON('/story_points_json/' + story_pk + '/', function(jd) {
    story_points_json = jd;
    var story_points = JSON.parse( story_points_json );
    for (i = 0; i < story_points.length; i++) {
      var x = story_points[i].fields.location_name;
    }
    story_points_list = story_points;

  initialize_map(story_points);

  });

  //google.maps.event.addDomListener(window, 'load', initialize);
  // Add the Waypoints to enable scrolling moves the map
  console.log("Adding waypoints");
  waypoints = $(".story_point").waypoint(function() {
      console.log('Reached waypoint: ' + this.element.id);
      var marker_id = Number(this.element.id) - 1;
      marker = markers[marker_id];
      panMap(marker, map);

  }, {
      context: $(".story_points").parent(),
      offset: "10"
  });

});

function initialize_map(story_points) {
  console.log("creating map");
  /*
  TODO:
    * Set the map to load centered at the latitude an longitude
      of the first story point
    * Build a marker for each storypoint

  */

  var center_lat = parseFloat(story_points[0].fields.latitude);
  var center_lng = parseFloat(story_points[0].fields.longitude);
  map = new google.maps.Map(document.getElementById("map"), {
      center: {lat: center_lat, lng: center_lng},
      zoom: 12
    });
  var infowindow = new google.maps.InfoWindow();

  var bounds = new google.maps.LatLngBounds();

  for (i = 0; i < story_points.length; i++) {
    var lat = parseFloat(story_points[i].fields.latitude);
    var lng = parseFloat(story_points[i].fields.longitude);
    var title = story_points[i].fields.title;
    var loc_name = story_points[i].fields.location_name;
    var text = story_points[i].fields.text;
    var num = story_points[i].fields.num_order;

    var contentString = '
'+
      '
'+
      '
'+
      '
' + loc_name + '
'+
      '
' + title + '
'+
      '
'+
      '
' + text + '
'+
      '
'+
      '
';

    var marker = new google.maps.Marker({
      position: {lat: lat, lng: lng},
      map: map,
      animation: google.maps.Animation.DROP,
      contentString: contentString,
      icon: '//chart.googleapis.com/chart?chst=d_map_pin_letter&chld=' + num + '|FE6256|000000'
    });

    marker.setValues({type: "point", id: num});
    markers.push(marker);

    bounds.extend(marker.getPosition());

    /*google.maps.event.addListener(marker, 'click', function() {
        //infowindow.setContent(this.contentString);
        //infowindow.open(map,this);
        console.log(marker);
        $('.scrollable').scrollTo($('#7'),1500);
    });*/

    attachListener(marker, num);

  };

  map.fitBounds(bounds);

}

function attachListener(marker, num) {
  marker.addListener('click', function() {
        console.log(num);
        $('.scrollable').scrollTo($('#' + num),1500);
  });
}

function panMap(marker, map) {
  map.setZoom(12)
  var latLng = marker.getPosition(); // returns LatLng object
  map.panTo(latLng); // setCenter takes a LatLng object
}

<|endoftext|>


<commit_before>/*
 * lib/schema.js: JSON schemas for various Marlin records
 */

/*
 * Primitive schema components
 */

var sString = { 'type': 'string' };
var sObject = { 'type': 'object' };

var sStringRequired = {
	'type': 'string',
	'required': true
};

var sStringRequiredNonEmpty = {
	'type': 'string',
	'required': true,
	'minLength': 1
};

var sDateTime = {
	'type': 'string',
	'format': 'date-time'
};

var sDateTimeRequired = {
	'type': 'string',
	'format': 'date-time',
	'required': true
};

var sStringArray = {
	'type': 'array',
	'items': sString
};

var sStringArrayRequired = {
	'type': 'array',
	'required': true,
	'items': sString
};

var sNonNegativeIntegerRequired = {
	'type': 'integer',
	'required': true,
	'minimum': 0
};

var sTcpPortRequired = {
	'required': true,
	'type': 'integer',
	'minimum': 1,
	'maximum': 65535
};

var sIntervalRequired = {
	'required': true,
	'type': 'integer',
	'minimum': 0
};

/*
 * Marlin-specific reusable schema components
 */
var sJobPhase = {
	'type': 'object',
	'additionalProperties': false,
	'properties': {
		'type': {
			'type': 'string',
			'enum': [ 'generic', 'storage-map' ]
		},
		'assets': sStringArray,
		'exec': sStringRequiredNonEmpty,
		'uarg': sObject
	}
};

var sJobPhases = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': sJobPhase
};

var sInputKeys = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': sString
};

var sInputKeyRecords = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': {
		'type': 'object',
		'properties': {
			'key': sStringRequiredNonEmpty,
			'objectid': sStringRequiredNonEmpty,
			'zonename': sStringRequiredNonEmpty
		}
	}
};

var sOutputKeys = sStringArrayRequired;

var sError = {
	'type': 'object',
	'properties': {
		'code': sStringRequiredNonEmpty,
		'message': sStringRequired
	}
};

/*
 * Job record in Moray
 */
var sMorayJob = {
	'type': 'object',
	'properties': {
		/* immutable job definition */
		'jobId': sStringRequiredNonEmpty,
		'jobName': sStringRequired,
		'phases': sJobPhases,
		'inputKeys': sInputKeys,
		'createTime': sDateTimeRequired,

		/* public state (mediated by the web tier) */
		'state': {
			'type': 'string',
			'required': true,
			'enum': [ 'queued', 'running', 'done' ]
		},
		'outputKeys': sOutputKeys,
		'discardedKeys': sOutputKeys,
		'finishTime': sDateTime,

		/* internal Marlin state */
		'worker': sString
	}
};

/*
 * Job record submitted by user
 */
var sHttpJobInput = {
	'type': 'object',
	'additionalProperties': false,
	'properties': {
		'jobName': sStringRequired,
		'phases': sJobPhases,
		'inputKeys': sInputKeys
	}
};

/*
 * Task group record in Moray
 */
var sMorayTaskGroup = {
	'type': 'object',
	'properties': {
		'jobId': sStringRequiredNonEmpty,
		'taskGroupId': sStringRequiredNonEmpty,
		'host': sStringRequiredNonEmpty,
		'inputKeys': sInputKeyRecords,
		'phase': sJobPhase,
		'phaseNum': sNonNegativeIntegerRequired,
		'state': {
			'type': 'string',
			'required': true,
			'enum': [ 'dispatched', 'running', 'cancelled', 'done' ]
		},
 		'results': {
 			'type': 'array',
 			'required': true,
 			'items': {
 				'type': 'object',
 				'properties': {
 					'input': sStringRequiredNonEmpty,
 					'machine': sString,
 					'result': {
 						'type': 'string',
 						'required': true,
 						'enum': [ 'ok', 'fail' ]
 					},
 					'outputs': sOutputKeys,
 					'partials': sStringArray,
 					'discarded': sStringArray,
 					'startTime': sDateTime,
 					'doneTime': sDateTime,
 					'error': sError
 				}
 			}
 		}
	}
};

/*
 * Moray bucket schemas.  These schemas only tell Moray what indices to create.
 * Objects in these buckets must conform to the more constrained schemas above.
 */
var sBktSchemas = {};

sBktSchemas['job'] = {
        'jobId': {
    	        'type': 'string',
    	        'unique': true
        },
        'owner': { 'type': 'string' },
        'name': { 'type': 'string' },
        'state': { 'type': 'string' }
};

sBktSchemas['taskgroup'] = {
    'taskGroupId': {
    	'type': 'string',
    	'unique': true
    },
    'jobId': {
    	'type': 'string',
    	'unique': false
    },
    'host': {
	'type': 'string',
	'unique': false
    },
    'phaseNum': {
    	'type': 'number',
    	'unique': false
    }
};

/* Public interface */
exports.sMorayJob = sMorayJob;
exports.sHttpJobInput = sHttpJobInput;
exports.sMorayTaskGroup = sMorayTaskGroup;
exports.sBktSchemas = sBktSchemas;
exports.sTcpPortRequired = sTcpPortRequired;
exports.sStringRequired = sStringRequired;
exports.sStringRequiredNonEmpty = sStringRequiredNonEmpty;
exports.sIntervalRequired = sIntervalRequired;
<commit_msg>MANTA-42: grr...tabify...grr...<commit_after>/*
 * lib/schema.js: JSON schemas for various Marlin records
 */

/*
 * Primitive schema components
 */

var sString = { 'type': 'string' };
var sObject = { 'type': 'object' };

var sStringRequired = {
	'type': 'string',
	'required': true
};

var sStringRequiredNonEmpty = {
	'type': 'string',
	'required': true,
	'minLength': 1
};

var sDateTime = {
	'type': 'string',
	'format': 'date-time'
};

var sDateTimeRequired = {
	'type': 'string',
	'format': 'date-time',
	'required': true
};

var sStringArray = {
	'type': 'array',
	'items': sString
};

var sStringArrayRequired = {
	'type': 'array',
	'required': true,
	'items': sString
};

var sNonNegativeIntegerRequired = {
	'type': 'integer',
	'required': true,
	'minimum': 0
};

var sTcpPortRequired = {
	'required': true,
	'type': 'integer',
	'minimum': 1,
	'maximum': 65535
};

var sIntervalRequired = {
	'required': true,
	'type': 'integer',
	'minimum': 0
};

/*
 * Marlin-specific reusable schema components
 */
var sJobPhase = {
	'type': 'object',
	'additionalProperties': false,
	'properties': {
		'type': {
			'type': 'string',
			'enum': [ 'generic', 'storage-map' ]
		},
		'assets': sStringArray,
		'exec': sStringRequiredNonEmpty,
		'uarg': sObject
	}
};

var sJobPhases = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': sJobPhase
};

var sInputKeys = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': sString
};

var sInputKeyRecords = {
	'type': 'array',
	'required': true,
	'minItems': 1,
	'items': {
		'type': 'object',
		'properties': {
			'key': sStringRequiredNonEmpty,
			'objectid': sStringRequiredNonEmpty,
			'zonename': sStringRequiredNonEmpty
		}
	}
};

var sOutputKeys = sStringArrayRequired;

var sError = {
	'type': 'object',
	'properties': {
		'code': sStringRequiredNonEmpty,
		'message': sStringRequired
	}
};

/*
 * Job record in Moray
 */
var sMorayJob = {
	'type': 'object',
	'properties': {
		/* immutable job definition */
		'jobId': sStringRequiredNonEmpty,
		'jobName': sStringRequired,
		'phases': sJobPhases,
		'inputKeys': sInputKeys,
		'createTime': sDateTimeRequired,

		/* public state (mediated by the web tier) */
		'state': {
			'type': 'string',
			'required': true,
			'enum': [ 'queued', 'running', 'done' ]
		},
		'outputKeys': sOutputKeys,
		'discardedKeys': sOutputKeys,
		'finishTime': sDateTime,

		/* internal Marlin state */
		'worker': sString
	}
};

/*
 * Job record submitted by user
 */
var sHttpJobInput = {
	'type': 'object',
	'additionalProperties': false,
	'properties': {
		'jobName': sStringRequired,
		'phases': sJobPhases,
		'inputKeys': sInputKeys
	}
};

/*
 * Task group record in Moray
 */
var sMorayTaskGroup = {
	'type': 'object',
	'properties': {
		'jobId': sStringRequiredNonEmpty,
		'taskGroupId': sStringRequiredNonEmpty,
		'host': sStringRequiredNonEmpty,
		'inputKeys': sInputKeyRecords,
		'phase': sJobPhase,
		'phaseNum': sNonNegativeIntegerRequired,
		'state': {
			'type': 'string',
			'required': true,
			'enum': [ 'dispatched', 'running', 'cancelled', 'done' ]
		},
 		'results': {
 			'type': 'array',
 			'required': true,
 			'items': {
 				'type': 'object',
 				'properties': {
 					'input': sStringRequiredNonEmpty,
 					'machine': sString,
 					'result': {
 						'type': 'string',
 						'required': true,
 						'enum': [ 'ok', 'fail' ]
 					},
 					'outputs': sOutputKeys,
 					'partials': sStringArray,
 					'discarded': sStringArray,
 					'startTime': sDateTime,
 					'doneTime': sDateTime,
 					'error': sError
 				}
 			}
 		}
	}
};

/*
 * Moray bucket schemas.  These schemas only tell Moray what indices to create.
 * Objects in these buckets must conform to the more constrained schemas above.
 */
var sBktSchemas = {};

sBktSchemas['job'] = {
	'jobId': {
		'type': 'string',
		'unique': true
	},
	'owner': {
		'type': 'string'
	},
	'name': {
		'type': 'string'
	},
	'state': {
		'type': 'string'
	}
};

sBktSchemas['taskgroup'] = {
    'taskGroupId': {
    	'type': 'string',
    	'unique': true
    },
    'jobId': {
    	'type': 'string',
    	'unique': false
    },
    'host': {
	'type': 'string',
	'unique': false
    },
    'phaseNum': {
    	'type': 'number',
    	'unique': false
    }
};

/* Public interface */
exports.sMorayJob = sMorayJob;
exports.sHttpJobInput = sHttpJobInput;
exports.sMorayTaskGroup = sMorayTaskGroup;
exports.sBktSchemas = sBktSchemas;
exports.sTcpPortRequired = sTcpPortRequired;
exports.sStringRequired = sStringRequired;
exports.sStringRequiredNonEmpty = sStringRequiredNonEmpty;
exports.sIntervalRequired = sIntervalRequired;
<|endoftext|>


<commit_before>function fetch(url, successCallback, errorCallback) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);

  request.onload = function() {
    if (request.status >= 200 && request.status < 400) {
      successCallback(JSON.parse(request.responseText));
    } else {
      errorCallback();
    }
  };

  request.onerror = function(err) {
    errorCallback(err);
  };

  request.send();
}

function setOnEachFeature(feature, layer){

  layer.on({
    mouseover: function (e) {
      var layer = e.target;

      layer.setStyle({
        fillOpacity: 0.7,
      });

      if (!L.Browser.ie && !L.Browser.opera) {
        layer.bringToFront();
      }

      info.update(layer.feature.properties);
    },
    mouseout: function(e) {
      geojson.resetStyle(e.target);
      info.update();
    }
  });

  layer.bindPopup('' + feature.properties.GN + '
'
    + 'Open Data Portal: ' + feature.properties["Open Data Portal"] + '
'
    + 'Website: ' + feature.properties.Website + '
'
    + 'CKAN / DCAN: ' + feature.properties["CKAN\/DCAN"] + '
'
    + 'Maschinenlesbare Formate: ' + feature.properties["Maschinenlesbare Formate"] + '
'
    + 'Lizenz: ' + feature.properties["Lizenz"] + '
'
    + 'OGD-Metadaten Pflichtfelder: ' + feature.properties["OGD-Metadaten Pflichtfelder"] + '
'
    + 'Anbindung an Open.NRW Portal: ' + feature.properties["Anbindung Open.NRW Portal"]
    );

  info.update(layer.feature.properties);
}

function setStyleByFeature(feature) {
  console.log(feature.properties);

  var fillOpacity = 0.7;
  var color = 'green';

  if(feature.properties["Open Data Portal"] == "In Planung") {
    color = 'yellow';
  }

  if(feature.properties["Open Data Portal"] == "Nein"){
    fillOpacity = 0.5;
    color = 'red';
  }

  if(feature.properties["Open Data Portal"] == null){
    fillOpacity = 0.5;
    color = 'red';
  }

 if(feature.properties["GN"] == "Gelsenkirchen") {
    color = 'yellow';
 }

  return {
    weight: 1,
    opacity: 1,
    color: 'white',
    dashArray: '3',
    fillOpacity: fillOpacity,
    fillColor: color
  };
}

// 7.208449443900787, 51.537503853624365

var info = L.control();
var gemein = new L.LayerGroup();
var overlays = { "Open Data Verf&uumlgbarkeit": gemein};

var geojson;

var map = L.map('map', {
  zoomControl: false,
  scrollWheelZoom: false,
  doubleClickZoom: false,
  boxZoom: false
}).setView([51.52, 7.15], 10);

mapLink = 'OpenStreetMap';
usedDataLink = 'Open.NRW';

var tileLayer = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.{ext}', {
  attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
  subdomains: 'abcd',
  minZoom: 0,
  maxZoom: 20,
  ext: 'png'
});

tileLayer.addTo(map);

// Add legend

var legend = L.control({ position: 'bottomright' });

legend.onAdd = function (map) {
  var div = L.DomUtil.create('div', 'info legend'),
  labels = [];
  labels.push('

 ' + "Nein");
  labels.push('

 ' + "In Planung");
  labels.push('

 ' + "Ja");

  div.innerHTML = '
Open Data
' + labels.join('
');

  return div;
}

 legend.addTo(map);

// Setup Info box
info.onAdd = function (map) {
  this._div = L.DomUtil.create('div', 'info');
  this.update();
  return this._div;
};

info.update = function (props) {
  var text = '
Open Data Verf&uumlgbarkeit 2016
';

  if(props) {
    text += '' + props.GN + '
';
  } else {
    text += 'Weitere Daten werden durch
Klick angezeigt';
  }

  this._div.innerHTML = text;
};

info.addTo(map);

// Set scales
L.control.scale({
  metric: true,
  imperial: false,
  position: 'bottomleft'
}).addTo(map);

// Fetch Data and add to map
fetch('./data/map-data.json', function (data) {
  geojson = L.geoJson(data, {
    style: setStyleByFeature,
    onEachFeature: setOnEachFeature
  }).addTo(gemein);

  map.addLayer(gemein);

}, function (err) {
  console.error(err);
});
<commit_msg>Disable console logging<commit_after>function fetch(url, successCallback, errorCallback) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);

  request.onload = function() {
    if (request.status >= 200 && request.status < 400) {
      successCallback(JSON.parse(request.responseText));
    } else {
      errorCallback();
    }
  };

  request.onerror = function(err) {
    errorCallback(err);
  };

  request.send();
}

function setOnEachFeature(feature, layer){

  layer.on({
    mouseover: function (e) {
      var layer = e.target;

      layer.setStyle({
        fillOpacity: 0.7,
      });

      if (!L.Browser.ie && !L.Browser.opera) {
        layer.bringToFront();
      }

      info.update(layer.feature.properties);
    },
    mouseout: function(e) {
      geojson.resetStyle(e.target);
      info.update();
    }
  });

  layer.bindPopup('' + feature.properties.GN + '
'
    + 'Open Data Portal: ' + feature.properties["Open Data Portal"] + '
'
    + 'Website: ' + feature.properties.Website + '
'
    + 'CKAN / DCAN: ' + feature.properties["CKAN\/DCAN"] + '
'
    + 'Maschinenlesbare Formate: ' + feature.properties["Maschinenlesbare Formate"] + '
'
    + 'Lizenz: ' + feature.properties["Lizenz"] + '
'
    + 'OGD-Metadaten Pflichtfelder: ' + feature.properties["OGD-Metadaten Pflichtfelder"] + '
'
    + 'Anbindung an Open.NRW Portal: ' + feature.properties["Anbindung Open.NRW Portal"]
    );

  info.update(layer.feature.properties);
}

function setStyleByFeature(feature) {
  // console.log(feature.properties);

  var fillOpacity = 0.7;
  var color = 'green';

  if(feature.properties["Open Data Portal"] == "In Planung") {
    color = 'yellow';
  }

  if(feature.properties["Open Data Portal"] == "Nein"){
    fillOpacity = 0.5;
    color = 'red';
  }

  if(feature.properties["Open Data Portal"] == null){
    fillOpacity = 0.5;
    color = 'red';
  }

 if(feature.properties["GN"] == "Gelsenkirchen") {
    color = 'yellow';
 }

  return {
    weight: 1,
    opacity: 1,
    color: 'white',
    dashArray: '3',
    fillOpacity: fillOpacity,
    fillColor: color
  };
}

// 7.208449443900787, 51.537503853624365

var info = L.control();
var gemein = new L.LayerGroup();
var overlays = { "Open Data Verf&uumlgbarkeit": gemein};

var geojson;

var map = L.map('map', {
  zoomControl: false,
  scrollWheelZoom: false,
  doubleClickZoom: false,
  boxZoom: false
}).setView([51.52, 7.15], 10);

mapLink = 'OpenStreetMap';
usedDataLink = 'Open.NRW';

var tileLayer = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.{ext}', {
  attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
  subdomains: 'abcd',
  minZoom: 0,
  maxZoom: 20,
  ext: 'png'
});

tileLayer.addTo(map);

// Add legend

var legend = L.control({ position: 'bottomright' });

legend.onAdd = function (map) {
  var div = L.DomUtil.create('div', 'info legend'),
  labels = [];
  labels.push('

 ' + "Nein");
  labels.push('

 ' + "In Planung");
  labels.push('

 ' + "Ja");

  div.innerHTML = '
Open Data
' + labels.join('
');

  return div;
}

 legend.addTo(map);

// Setup Info box
info.onAdd = function (map) {
  this._div = L.DomUtil.create('div', 'info');
  this.update();
  return this._div;
};

info.update = function (props) {
  var text = '
Open Data Verf&uumlgbarkeit 2016
';

  if(props) {
    text += '' + props.GN + '
';
  } else {
    text += 'Weitere Daten werden durch
Klick angezeigt';
  }

  this._div.innerHTML = text;
};

info.addTo(map);

// Set scales
L.control.scale({
  metric: true,
  imperial: false,
  position: 'bottomleft'
}).addTo(map);

// Fetch Data and add to map
fetch('./data/map-data.json', function (data) {
  geojson = L.geoJson(data, {
    style: setStyleByFeature,
    onEachFeature: setOnEachFeature
  }).addTo(gemein);

  map.addLayer(gemein);

}, function (err) {
  console.error(err);
});
<|endoftext|>


<commit_before>const loaderUtils = require('loader-utils');

module.exports = (input) => {
  const { text } = loaderUtils.getOptions(this);

  return input + text;
};
module.exports.pitch = (
  remainingRequest, precedingRequest, input
) => {
  console.log(
    'remaining request', remainingRequest,
    'preceding request', precedingRequest,
    'input', input
  );

  return 'pitched';
};
<commit_msg>Use regular functions for loaders due to binding<commit_after>const loaderUtils = require('loader-utils');

module.exports = function(input) {
  const { text } = loaderUtils.getOptions(this);

  return input + text;
};
module.exports.pitch = function(
  remainingRequest, precedingRequest, input
) {
  console.log(
    'remaining request', remainingRequest,
    'preceding request', precedingRequest,
    'input', input
  );

  return 'pitched';
};
<|endoftext|>


<commit_before>import React, {
  PropTypes,
  StyleSheet,
  Component,
  TouchableWithoutFeedback,
  View,
  Text,
} from 'react-native';

const SELECT = 'SELECT';

const styles = StyleSheet.create({
  container: {
    borderWidth: 0,
    borderStyle: 'solid',
    borderBottomColor: 'rgba(0, 0, 0, 0.12)',
    borderBottomWidth: 1,
  },
});

const propTypes = {
  width: PropTypes.number,
  height: PropTypes.number,
  pickerRef: PropTypes.func.isRequired,
  selected: PropTypes.string.isRequired,
  style: PropTypes.object,
  styleText: PropTypes.object,
};

const defaultProps = {
  width: 200,
  height: 40,
};

class Select extends Component {

  constructor(props) {
    super(props);

    this.pageX = 0;
    this.pageY = 0;

    const selected = props.selected;

    this.state = {
      value: selected,
    };
  }

  componentWillReceiveProps(props) {
    this.setState({
      value: props.selected,
    });
  }

  render() {
    const { pickerRef, width, height, style, styleText } = this.props;
    const dimensions = { width, height };

    return (
      <TouchableWithoutFeedback onPress={() => { pickerRef().show(); }}>
        <View ref={SELECT} style={[styles.container, style, dimensions]}>
          <Text style={styleText} >{this.state.value}</Text>
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

Select.propTypes = propTypes;
Select.defaultProps = defaultProps;

export default Select;
<commit_msg>ADD disabled option to Select<commit_after>import React, {
  PropTypes,
  StyleSheet,
  Component,
  TouchableWithoutFeedback,
  View,
  Text,
} from 'react-native';

const SELECT = 'SELECT';

const styles = StyleSheet.create({
  container: {
    borderWidth: 0,
    borderStyle: 'solid',
    borderBottomColor: 'rgba(0, 0, 0, 0.12)',
    borderBottomWidth: 1,
  },
});

const propTypes = {
  width: PropTypes.number,
  height: PropTypes.number,
  pickerRef: PropTypes.func.isRequired,
  selected: PropTypes.string.isRequired,
  style: PropTypes.object,
  styleText: PropTypes.object,
  disabled: PropTypes.bool,
};

const defaultProps = {
  width: 200,
  height: 40,
};

class Select extends Component {

  constructor(props) {
    super(props);

    this.pageX = 0;
    this.pageY = 0;

    const selected = props.selected;

    this.state = {
      value: selected,
    };
  }

  componentWillReceiveProps(props) {
    this.setState({
      value: props.selected,
    });
  }

  render() {
    const { pickerRef, width, height, style, styleText } = this.props;
    const dimensions = { width, height };

    return (
      <TouchableWithoutFeedback
        onPress={() => { pickerRef().show(); }}
        disabled={this.props.disabled}
      >
        <View ref={SELECT} style={[styleEdit, style, dimensions]}>
          <Text style={styleText} >{this.state.value}</Text>
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

Select.propTypes = propTypes;
Select.defaultProps = defaultProps;

export default Select;
<|endoftext|>


<commit_before>var express = require('express');
var nroonga = require('./wrapped-nroonga');
var api = require('./api');
var dashboard = require('./dashboard');

exports.createServer = function (config) {
  var context = config.context || new nroonga.Context(config.databasePath);
  var application = express.createServer();
  application.use(express.bodyParser());
  application.set('views', __dirname + '/../views');
  application.use(express.static(__dirname + '/../public'));

  application.configure(function() {
    application.enable('jsonp callback');
  });

  application.configure('development', function(){
    application.use(express.logger('development'));
  })

  application.configure('production', function(){
    application.use(express.logger('default'));
  })

  api.versions.forEach(function(version) {
    api[version].registerHandlers(application, context, config);
  });

  application.get('/', dashboard.rootHandler);
  application.get('/javascripts/templates.js', dashboard.templatesHandler);

  return application;
};
<commit_msg>Fix development log format<commit_after>var express = require('express');
var nroonga = require('./wrapped-nroonga');
var api = require('./api');
var dashboard = require('./dashboard');

exports.createServer = function (config) {
  var context = config.context || new nroonga.Context(config.databasePath);
  var application = express.createServer();
  application.use(express.bodyParser());
  application.set('views', __dirname + '/../views');
  application.use(express.static(__dirname + '/../public'));

  application.configure(function() {
    application.enable('jsonp callback');
  });

  application.configure('development', function(){
    application.use(express.logger('dev'));
  })

  application.configure('production', function(){
    application.use(express.logger('default'));
  })

  api.versions.forEach(function(version) {
    api[version].registerHandlers(application, context, config);
  });

  application.get('/', dashboard.rootHandler);
  application.get('/javascripts/templates.js', dashboard.templatesHandler);

  return application;
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * An HTTP server to serve classification requests
 *
 * Usage:
 * % export MAPBOX_ACCESS_TOKEN="pk.foo" ./server.js
 * Routes:
 * GET /classify?tile=z/x/y
 *
 * NOTES:
 * - should run inside rodowi/inception_serving container
 * - listens in port 3000
 *
 */

const execFile = require('child_process').execFile
const express = require('express')
const app = express()

const port = 3000
const url = 'https://b.tiles.mapbox.com/v4/mapbox.satellite'
const token = process.env.MAPBOX_ACCESS_TOKEN

app.get('/', function (req, res) {
  var zxy = req.query.tile
  download(zxy, (err, filename) => {
    if (err) return res.send(err)
    predict(filename, (err, label) => {
      if (err) return res.send(err)
      res.send('CAT\n')
    })
  })
})

function download (tile, done) {
  var filename = `${process.env.PWD}/imagery/${tile.replace(/\//g, '-')}.jpg`
  var command = 'curl'
  var params = [
    `${url}/${tile}@2x.png?access_token=${token}`,
    '-o',
    filename
  ]
  execFile(command, params, (err, stdout, stderr) => {
    done(err, filename)
  })
}

function predict (filename, done) {
  var cmd = '/serving/bazel-bin/tensorflow_serving/example/inception_client'
  var params = [
    '--server=localhost:9000',
    '--image=' + filename
  ]
  execFile(cmd, params, (err, stdout, stderr) => {
    done(err, stderr + stdout)
  })
}

app.listen(port)
console.log('Listening for tile requests in port', port)
<commit_msg>Return predicted label<commit_after>#!/usr/bin/env node

/**
 * An HTTP server to serve classification requests
 *
 * Usage:
 * % export MAPBOX_ACCESS_TOKEN="pk.foo" ./server.js
 * Routes:
 * GET /classify?tile=z/x/y
 *
 * NOTES:
 * - should run inside rodowi/inception_serving container
 * - listens in port 3000
 *
 */

const execFile = require('child_process').execFile
const express = require('express')
const app = express()

const port = 3000
const url = 'https://b.tiles.mapbox.com/v4/mapbox.satellite'
const token = process.env.MAPBOX_ACCESS_TOKEN

app.get('/', function (req, res) {
  var zxy = req.query.tile
  download(zxy, (err, filename) => {
    if (err) return res.send(err)
    predict(filename, (err, label) => {
      if (err) return res.send(err)
      res.send(label)
    })
  })
})

function download (tile, done) {
  var filename = `${process.env.PWD}/imagery/${tile.replace(/\//g, '-')}.jpg`
  var command = 'curl'
  var params = [
    `${url}/${tile}@2x.png?access_token=${token}`,
    '-o',
    filename
  ]
  execFile(command, params, (err, stdout, stderr) => {
    done(err, filename)
  })
}

function predict (filename, done) {
  var cmd = '/serving/bazel-bin/tensorflow_serving/example/inception_client'
  var params = [
    '--server=localhost:9000',
    '--image=' + filename
  ]
  execFile(cmd, params, (err, stdout, stderr) => {
    done(err, stderr + stdout)
  })
}

app.listen(port)
console.log('Listening for tile requests in port', port)
<|endoftext|>


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

    var DIR_ROOT    = __dirname + '/..',

        path        = require('path'),

        join        = require('join-io'),
        mollify     = require('mollify'),
        restafary   = require('restafary'),
        socketFile  = require('socket-file'),
        readjson    = require('readjson'),
        HOME        = require('os-homedir')(),
        Edit        = require('../json/edit.json'),
        jshint      = readjson.sync(path.join(HOME, '.jshintrc')),
        Root,
        minifyFunc          = mollify({
            dir     : DIR_ROOT
        });

    if (!jshint)
        jshint = readjson.sync('../.jshintrc');

    module.exports          = function(options) {
        return serve.bind(null, options);
    };

    module.exports.listen   = function(socket, options) {
        var ret;

        if (!options)
            options = {};

        if (!options.prefix)
            options.prefix = '/dword';

        if (!options.root)
            options.root = '/';

        Root = options.root;
        ret = socketFile(socket, options);

        return ret;
    };

    function checkOption(isOption) {
        var is,
            type    = typeof isOption;

        switch(type) {
        case 'function':
            is = isOption();
            break;

        case 'undefined':
            is = true;
            break;

        default:
            is = isOption;
        }

        return is;
    }

    function copy(from, to) {
        Object.keys(from).forEach(function(name) {
            to[name] = from[name];
        });
    }

    function readEdit(callback) {
        var homePath = HOME + '/.dword.json';

        readjson(homePath, function(error, edit) {
            var data = {};

            copy(Edit, data);

            if (!error)
                copy(edit, data);
            else if (error.code !== 'ENOENT')
                error = Error('dword --config ' + homePath + ': ' + error.message);
            else
                error = null;

            callback(error, data);
        });
    }

    function serve(options, req, res, next) {
        var joinFunc, restafaryFunc, isJoin, isConfig, isEdit, isRestafary,
            isJsHint,
            o           = options || {},
            isMin       = checkOption(o.minify),
            isOnline    = checkOption(o.online),
            isDiff      = checkOption(o.diff),
            isZip       = checkOption(o.pack),

            url         = req.url,
            prefix      = o.prefix || '/dword',

            isEdward    = !url.indexOf(prefix),

            URL         = '/dword.js',
            CONFIG      = '/options.json',
            MODULES     = '/modules.json',
            PATH        = '/lib/client.js',
            EDIT        = '/edit.json',
            JSHINT      = '/jshint.json',
            sendFile    = function() {
                url = path.normalize(DIR_ROOT + url);
                res.sendFile(url);
            };

        if (!isEdward) {
            next();
        } else {
            url         = url.replace(prefix, '');

            isJoin      = !url.indexOf('/join');
            isConfig    = url === CONFIG;
            isEdit      = url === EDIT;
            isJsHint    = url === JSHINT;
            isRestafary = [
                '/api/v1/fs',
                '/restafary.js'].some(function(item) {
                    return !url.indexOf(item);
                });

            switch(url) {
            case URL:
                url = PATH;
                break;

            case MODULES:
                url = '/json' + url;
                break;
            }

            req.url = url;

            if (isEdit) {
                readEdit(function(error, data) {
                    if (error)
                        res.status(404)
                            .send(error.message);
                    else
                        res .type('json')
                            .send(data);
                });
            } else if (isConfig) {
                res .type('json')
                    .send({
                        diff: isDiff,
                        zip: isZip,
                        online: isOnline
                    });
            } else if (isJoin) {
                joinFunc = join({
                    dir     : DIR_ROOT,
                    minify  : isMin
                });

                joinFunc(req, res, next);
            } else if (isMin) {
                minifyFunc(req, res, sendFile);
            } else if (isRestafary) {
                restafaryFunc = restafary({
                    prefix: '/api/v1/fs',
                    root: Root
                });

                restafaryFunc(req, res, next);
            } else if (isJsHint) {
                res .type('json')
                    .send(jshint);
            } else {
                sendFile();
            }
        }
    }
})();
<commit_msg>fix(server) .jshintrc path<commit_after>(function() {
    'use strict';

    var DIR_ROOT    = __dirname + '/..',

        path        = require('path'),

        join        = require('join-io'),
        mollify     = require('mollify'),
        restafary   = require('restafary'),
        socketFile  = require('socket-file'),
        readjson    = require('readjson'),
        HOME        = require('os-homedir')(),
        Edit        = require('../json/edit.json'),
        jshint      = readjson.sync(path.join(HOME, '.jshintrc')),
        Root,
        minifyFunc          = mollify({
            dir     : DIR_ROOT
        });

    if (!jshint)
        jshint = readjson.sync(path.join(DIR_ROOT,'.jshintrc'));

    module.exports          = function(options) {
        return serve.bind(null, options);
    };

    module.exports.listen   = function(socket, options) {
        var ret;

        if (!options)
            options = {};

        if (!options.prefix)
            options.prefix = '/dword';

        if (!options.root)
            options.root = '/';

        Root = options.root;
        ret = socketFile(socket, options);

        return ret;
    };

    function checkOption(isOption) {
        var is,
            type    = typeof isOption;

        switch(type) {
        case 'function':
            is = isOption();
            break;

        case 'undefined':
            is = true;
            break;

        default:
            is = isOption;
        }

        return is;
    }

    function copy(from, to) {
        Object.keys(from).forEach(function(name) {
            to[name] = from[name];
        });
    }

    function readEdit(callback) {
        var homePath = HOME + '/.dword.json';

        readjson(homePath, function(error, edit) {
            var data = {};

            copy(Edit, data);

            if (!error)
                copy(edit, data);
            else if (error.code !== 'ENOENT')
                error = Error('dword --config ' + homePath + ': ' + error.message);
            else
                error = null;

            callback(error, data);
        });
    }

    function serve(options, req, res, next) {
        var joinFunc, restafaryFunc, isJoin, isConfig, isEdit, isRestafary,
            isJsHint,
            o           = options || {},
            isMin       = checkOption(o.minify),
            isOnline    = checkOption(o.online),
            isDiff      = checkOption(o.diff),
            isZip       = checkOption(o.pack),

            url         = req.url,
            prefix      = o.prefix || '/dword',

            isEdward    = !url.indexOf(prefix),

            URL         = '/dword.js',
            CONFIG      = '/options.json',
            MODULES     = '/modules.json',
            PATH        = '/lib/client.js',
            EDIT        = '/edit.json',
            JSHINT      = '/jshint.json',
            sendFile    = function() {
                url = path.normalize(DIR_ROOT + url);
                res.sendFile(url);
            };

        if (!isEdward) {
            next();
        } else {
            url         = url.replace(prefix, '');

            isJoin      = !url.indexOf('/join');
            isConfig    = url === CONFIG;
            isEdit      = url === EDIT;
            isJsHint    = url === JSHINT;
            isRestafary = [
                '/api/v1/fs',
                '/restafary.js'].some(function(item) {
                    return !url.indexOf(item);
                });

            switch(url) {
            case URL:
                url = PATH;
                break;

            case MODULES:
                url = '/json' + url;
                break;
            }

            req.url = url;

            if (isEdit) {
                readEdit(function(error, data) {
                    if (error)
                        res.status(404)
                            .send(error.message);
                    else
                        res .type('json')
                            .send(data);
                });
            } else if (isConfig) {
                res .type('json')
                    .send({
                        diff: isDiff,
                        zip: isZip,
                        online: isOnline
                    });
            } else if (isJoin) {
                joinFunc = join({
                    dir     : DIR_ROOT,
                    minify  : isMin
                });

                joinFunc(req, res, next);
            } else if (isMin) {
                minifyFunc(req, res, sendFile);
            } else if (isRestafary) {
                restafaryFunc = restafary({
                    prefix: '/api/v1/fs',
                    root: Root
                });

                restafaryFunc(req, res, next);
            } else if (isJsHint) {
                res .type('json')
                    .send(jshint);
            } else {
                sendFile();
            }
        }
    }
})();
<|endoftext|>