<commit_before>console.log( __dirname );

const express = require('express'),
      fs = require('fs'),
      path = require('path'),
      url = require('url'),
      app = express.createServer(),
      MongoStore = require('connect-mongo')(express),
      stylus = require('stylus'),
      CONFIG = require('config'),
      TEMPLATES_DIR =  CONFIG.dirs.templates,
      PUBLISH_DIR = CONFIG.dirs.publish,
      PUBLISH_PREFIX = CONFIG.dirs.hostname,
      WWW_ROOT = path.resolve( CONFIG.dirs.wwwRoot || path.join( __dirname, ".." ) ),
      VALID_TEMPLATES = CONFIG.templates,
      EXPORT_ASSETS = CONFIG.exportAssets;

var templateConfigs = {};

function readTemplateConfig( templateName, templatedPath ) {
  var configPath = templatedPath.replace( '{{templateBase}}', TEMPLATES_DIR + '/' );
  fs.readFile( configPath, 'utf8', function( err, conf ) {
    var configPathBase = configPath.substring( 0, configPath.lastIndexOf( '/' ) );
    conf = JSON.parse( conf );
    conf.template = configPathBase + '/' + conf.template;
    templateConfigs[ templateName ] = conf;
  });
}

// parse configs ahead of any action that has to happen with them
for ( var templateName in VALID_TEMPLATES ) {
  readTemplateConfig( templateName, VALID_TEMPLATES[ templateName ] );
}

var canStoreData = true;

console.log( "Templates Dir:", TEMPLATES_DIR );
console.log( "Publish Dir:", PUBLISH_DIR );

var mongoose = require('mongoose'),
    db = mongoose.connect('mongodb://localhost/test', function( err ) {
      if ( err ) {
        console.error( "MongoDB: " + err + "\n  You will not be able to store any data." );
        canStoreData = false;
      }
    }),
    Schema = mongoose.Schema,

    Project = new Schema({
      name: String,
      html: String,
      data: String,
      template: String,
      customData: String
    }),
    ProjectModel = mongoose.model( 'Project', Project ),

    User = new Schema({
      email: String,
      projects: [Project],
    }),
    UserModel = mongoose.model( 'User', User );

CONFIG.session.store = new MongoStore({ db: "test" });

if ( !path.existsSync( PUBLISH_DIR ) ) {
  fs.mkdirSync( PUBLISH_DIR );
}

app.configure( function() {
  app.use( express.logger( CONFIG.logger ) )
    .use( express.static( WWW_ROOT ) )
    .use( express.static( PUBLISH_DIR ) )
    .use( express.bodyParser() )
    .use( express.cookieParser() )
    .use( express.session( CONFIG.session ) )
    .use( stylus.middleware({
      src: WWW_ROOT
    }))
    /* Show Zeus who's boss
     * This only affects requests under /api and /browserid, not static files
     * because the static file writes the response header before we hit this middleware
     */
    .use( function( req, res, next ) {
      res.header( 'Cache-Control', 'no-store' );
      return next();
    })
    .set('view options', {layout: false});
});

app.configure( 'development', function() {
  app.use( express.directory( WWW_ROOT, { icons: true } ) );
});

require('express-browserid').plugAll(app);

function publishRoute( req, res ){
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var i;
    if ( err ) {
      res.json({ error: 'internal db error' }, 500);
      return;
    }

    if ( !doc ) {
      res.json({ error: 'user not found' }, 500);
      return;
    }

    var project;
    for ( i=0; i<doc.projects.length; ++i ) {
      if ( String( doc.projects[ i ]._id ) === id ) {
        project = doc.projects[ i ];
        break;
      }
    }

    if ( project ) {
      var template = project.template,
          customData = project.customData;

      if ( template && VALID_TEMPLATES[ template ] ) {
        var projectPath = PUBLISH_DIR + "/" + id + ".html",
            url = PUBLISH_PREFIX + "/" + id + ".html",
            projectData = JSON.parse( project.data ),
            templateBase = VALID_TEMPLATES[ template ].replace( '{{templateBase}}', TEMPLATES_DIR + '/' ),
            templateConfig = templateConfigs[ template ],
            templateFile = templateConfig.template;

        fs.readFile( templateFile, 'utf8', function( err, data ){
          var headEndTagIndex,
              bodyEndTagIndex,
              externalAssetsString = '',
              popcornString = '',
              currentMedia,
              currentTrack,
              currentTrackEvent,
              mediaPopcornOptions,
              templateURL,
              baseString,
              headStartTagIndex,
              templateScripts,
              startString,
              j, k;

          templateURL = templateFile.substring( templateFile.indexOf( '/templates' ), templateFile.lastIndexOf( '/' ) );
          baseString = '\n  <base href="' + PUBLISH_PREFIX + templateURL + '/"/>';

          // look for script tags with data-butter-exclude in particular (e.g. butter's js script)
          data = data.replace( /\s*\n';
          }

          // If the template has custom plugins defined in it's config, add them to our exported page
          if ( templateConfig.plugin && templateConfig.plugin.plugins ) {
            var plugins = templateConfig.plugin.plugins;

            for ( i = 0, len = plugins.length; i < len; i++ ) {
              externalAssetsString += '\n  ';
            }
            externalAssetsString += '\n';
          }

          popcornString += '\n';

          customDataString = '\n';

          data = startString + baseString + templateScripts + externalAssetsString + data.substring( headEndTagIndex, bodyEndTagIndex ) + customDataString + popcornString + data.substring( bodyEndTagIndex );

          fs.writeFile( projectPath, data, function(){
            if( err ){
              res.json({ error: 'internal file error' }, 500);
              return;
            }
            res.json({ error: 'okay', url: url });
          });
        });
      }
      else {
        res.json({ error: 'template not found' }, 500);
        return;
      }
    }
    else {
      res.json({ error: 'project not found' }, 500);
      return;
    }
  });
}

app.post('/api/publish/:id', publishRoute );

app.get('/dashboard', function(req, res) {
  var email = req.session.email;

  if ( !email ) {
    res.render( 'dashboard-unauthorized.jade' );
    return;
  }

  if ( !canStoreData ) {
    res.json( { error: 'storage service is not running' }, 500 );
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var userProjects = [],
        project;
    for ( var i = 0, l = doc.projects.length; i < l; ++i ) {
      project = doc.projects[ i ];
      if ( project.template && VALID_TEMPLATES[ project.template ] ) {
        userProjects.push({
          _id: project._id,
          name: project.name,
          template: project.template,
          href: templateConfigs[ project.template ].template +
            "?savedDataUrl=" + PUBLISH_PREFIX + "/api/project/" + project._id
        });
      }
    }

    res.render( 'dashboard.jade', {
      user: {
        email: email,
      },
      projects: userProjects
    });
  });
});

app.get('/api/projects', function(req, res) {
  var email = req.session.email;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {

    // Add a user record if they've never logged in yet
    if ( err === null && doc === null ) {
      doc = new UserModel({
        email: email
      });
      doc.save( function( err ) {
        if ( err ) {
          console.log( err );
        }
      });

      res.json({ error: 'okay', projects: [] });
      return;
    }

    if ( err ) {
      console.log( err );
      res.json({ error: err, projects: [] }, 500);
    }

    // We really only need to send the name and id for future use
    var projectData = [];
    doc.projects.forEach( function( value, index, arr ) {
      projectData.push( { name: value.name, id: value._id } );
    });

    res.json({ error: 'okay', projects: projectData });
  });
});

app.get('/api/project/:id?', function(req, res) {
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    for( var i=0; i<doc.projects.length; ++i ){
      if( String( doc.projects[ i ]._id ) === id ){
        res.json( JSON.parse( doc.projects[ i ].data ) );
        return;
      }
    }
    res.json( { error: "project not found" } );
  });
});

app.post('/api/project/:id?', function( req, res ) {
  var email = req.session.email,
      id = req.params.id;

  if ( !email ) {
    res.json( { error: 'unauthorized' }, 403 );
    return;
  }

  if( !req.body ){
    res.json( {error: 'no project data received' }, 500 );
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {

    if( err ){
      res.json( {error: 'internal db error' }, 500 );
      return;
    }

    if( !doc ){
      doc = new UserModel({
        email: email
      });
    }

    var proj;
    for( var i=0, l=doc.projects.length; i<l; ++i ){
      // purposeful lazy comparison here (String -> string)
      if( doc.projects[ i ]._id == req.body.id ){
        proj = doc.projects[ i ];
      }
    }

    if( !proj ){
      if( req.body.id ){
        res.json( {error: 'id specified but not found. data corruption or haxxors.'}, 500 );
        return;
      }
      var proj = new ProjectModel({
        name: req.body.name,
        html: req.body.html,
        template: req.body.template,
        data: JSON.stringify( req.body.data ),
        customData: JSON.stringify( req.body.customData, null, 2 )
      });
      doc.projects.push( proj );
    }
    else{
      proj.template = req.body.template;
      proj.name = req.body.name;
      proj.html = req.body.html;
      proj.data = JSON.stringify( req.body.data );
      proj.customData = JSON.stringify( req.body.customData, null, 2 );
    }

    doc.save();

    res.json({ error: 'okay', project: proj });
    return;

  });
});

app.get('/api/whoami', function( req, res ) {
  var email = req.session.email;

  if ( !email ) {
    res.json( { error: 'unauthorized' }, 403 );
    return;
  }

  res.json({
    email: email,
    name: email,
    username: email
  });
});

var port = process.env.PORT || CONFIG.server.bindPort;

app.listen(port, CONFIG.server.bindIP, function() {
  var addy = app.address();
  console.log('HTTP Server started on http://' + CONFIG.server.bindIP + ':' + addy.port);
  console.log('Press Ctrl+C to stop');
});
<commit_msg>[t1429] removed useless npm module, url<commit_after>console.log( __dirname );

const express = require('express'),
      fs = require('fs'),
      path = require('path'),
      app = express.createServer(),
      MongoStore = require('connect-mongo')(express),
      stylus = require('stylus'),
      CONFIG = require('config'),
      TEMPLATES_DIR =  CONFIG.dirs.templates,
      PUBLISH_DIR = CONFIG.dirs.publish,
      PUBLISH_PREFIX = CONFIG.dirs.hostname,
      WWW_ROOT = path.resolve( CONFIG.dirs.wwwRoot || path.join( __dirname, ".." ) ),
      VALID_TEMPLATES = CONFIG.templates,
      EXPORT_ASSETS = CONFIG.exportAssets;

var templateConfigs = {};

function readTemplateConfig( templateName, templatedPath ) {
  var configPath = templatedPath.replace( '{{templateBase}}', TEMPLATES_DIR + '/' );
  fs.readFile( configPath, 'utf8', function( err, conf ) {
    var configPathBase = configPath.substring( 0, configPath.lastIndexOf( '/' ) );
    conf = JSON.parse( conf );
    conf.template = configPathBase + '/' + conf.template;
    templateConfigs[ templateName ] = conf;
  });
}

// parse configs ahead of any action that has to happen with them
for ( var templateName in VALID_TEMPLATES ) {
  readTemplateConfig( templateName, VALID_TEMPLATES[ templateName ] );
}

var canStoreData = true;

console.log( "Templates Dir:", TEMPLATES_DIR );
console.log( "Publish Dir:", PUBLISH_DIR );

var mongoose = require('mongoose'),
    db = mongoose.connect('mongodb://localhost/test', function( err ) {
      if ( err ) {
        console.error( "MongoDB: " + err + "\n  You will not be able to store any data." );
        canStoreData = false;
      }
    }),
    Schema = mongoose.Schema,

    Project = new Schema({
      name: String,
      html: String,
      data: String,
      template: String,
      customData: String
    }),
    ProjectModel = mongoose.model( 'Project', Project ),

    User = new Schema({
      email: String,
      projects: [Project],
    }),
    UserModel = mongoose.model( 'User', User );

CONFIG.session.store = new MongoStore({ db: "test" });

if ( !path.existsSync( PUBLISH_DIR ) ) {
  fs.mkdirSync( PUBLISH_DIR );
}

app.configure( function() {
  app.use( express.logger( CONFIG.logger ) )
    .use( express.static( WWW_ROOT ) )
    .use( express.static( PUBLISH_DIR ) )
    .use( express.bodyParser() )
    .use( express.cookieParser() )
    .use( express.session( CONFIG.session ) )
    .use( stylus.middleware({
      src: WWW_ROOT
    }))
    /* Show Zeus who's boss
     * This only affects requests under /api and /browserid, not static files
     * because the static file writes the response header before we hit this middleware
     */
    .use( function( req, res, next ) {
      res.header( 'Cache-Control', 'no-store' );
      return next();
    })
    .set('view options', {layout: false});
});

app.configure( 'development', function() {
  app.use( express.directory( WWW_ROOT, { icons: true } ) );
});

require('express-browserid').plugAll(app);

function publishRoute( req, res ){
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var i;
    if ( err ) {
      res.json({ error: 'internal db error' }, 500);
      return;
    }

    if ( !doc ) {
      res.json({ error: 'user not found' }, 500);
      return;
    }

    var project;
    for ( i=0; i<doc.projects.length; ++i ) {
      if ( String( doc.projects[ i ]._id ) === id ) {
        project = doc.projects[ i ];
        break;
      }
    }

    if ( project ) {
      var template = project.template,
          customData = project.customData;

      if ( template && VALID_TEMPLATES[ template ] ) {
        var projectPath = PUBLISH_DIR + "/" + id + ".html",
            url = PUBLISH_PREFIX + "/" + id + ".html",
            projectData = JSON.parse( project.data ),
            templateBase = VALID_TEMPLATES[ template ].replace( '{{templateBase}}', TEMPLATES_DIR + '/' ),
            templateConfig = templateConfigs[ template ],
            templateFile = templateConfig.template;

        fs.readFile( templateFile, 'utf8', function( err, data ){
          var headEndTagIndex,
              bodyEndTagIndex,
              externalAssetsString = '',
              popcornString = '',
              currentMedia,
              currentTrack,
              currentTrackEvent,
              mediaPopcornOptions,
              templateURL,
              baseString,
              headStartTagIndex,
              templateScripts,
              startString,
              j, k;

          templateURL = templateFile.substring( templateFile.indexOf( '/templates' ), templateFile.lastIndexOf( '/' ) );
          baseString = '\n  <base href="' + PUBLISH_PREFIX + templateURL + '/"/>';

          // look for script tags with data-butter-exclude in particular (e.g. butter's js script)
          data = data.replace( /\s*\n';
          }

          // If the template has custom plugins defined in it's config, add them to our exported page
          if ( templateConfig.plugin && templateConfig.plugin.plugins ) {
            var plugins = templateConfig.plugin.plugins;

            for ( i = 0, len = plugins.length; i < len; i++ ) {
              externalAssetsString += '\n  ';
            }
            externalAssetsString += '\n';
          }

          popcornString += '\n';

          customDataString = '\n';

          data = startString + baseString + templateScripts + externalAssetsString + data.substring( headEndTagIndex, bodyEndTagIndex ) + customDataString + popcornString + data.substring( bodyEndTagIndex );

          fs.writeFile( projectPath, data, function(){
            if( err ){
              res.json({ error: 'internal file error' }, 500);
              return;
            }
            res.json({ error: 'okay', url: url });
          });
        });
      }
      else {
        res.json({ error: 'template not found' }, 500);
        return;
      }
    }
    else {
      res.json({ error: 'project not found' }, 500);
      return;
    }
  });
}

app.post('/api/publish/:id', publishRoute );

app.get('/dashboard', function(req, res) {
  var email = req.session.email;

  if ( !email ) {
    res.render( 'dashboard-unauthorized.jade' );
    return;
  }

  if ( !canStoreData ) {
    res.json( { error: 'storage service is not running' }, 500 );
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var userProjects = [],
        project;
    for ( var i = 0, l = doc.projects.length; i < l; ++i ) {
      project = doc.projects[ i ];
      if ( project.template && VALID_TEMPLATES[ project.template ] ) {
        userProjects.push({
          _id: project._id,
          name: project.name,
          template: project.template,
          href: templateConfigs[ project.template ].template +
            "?savedDataUrl=" + PUBLISH_PREFIX + "/api/project/" + project._id
        });
      }
    }

    res.render( 'dashboard.jade', {
      user: {
        email: email,
      },
      projects: userProjects
    });
  });
});

app.get('/api/projects', function(req, res) {
  var email = req.session.email;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {

    // Add a user record if they've never logged in yet
    if ( err === null && doc === null ) {
      doc = new UserModel({
        email: email
      });
      doc.save( function( err ) {
        if ( err ) {
          console.log( err );
        }
      });

      res.json({ error: 'okay', projects: [] });
      return;
    }

    if ( err ) {
      console.log( err );
      res.json({ error: err, projects: [] }, 500);
    }

    // We really only need to send the name and id for future use
    var projectData = [];
    doc.projects.forEach( function( value, index, arr ) {
      projectData.push( { name: value.name, id: value._id } );
    });

    res.json({ error: 'okay', projects: projectData });
  });
});

app.get('/api/project/:id?', function(req, res) {
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    for( var i=0; i<doc.projects.length; ++i ){
      if( String( doc.projects[ i ]._id ) === id ){
        res.json( JSON.parse( doc.projects[ i ].data ) );
        return;
      }
    }
    res.json( { error: "project not found" } );
  });
});

app.post('/api/project/:id?', function( req, res ) {
  var email = req.session.email,
      id = req.params.id;

  if ( !email ) {
    res.json( { error: 'unauthorized' }, 403 );
    return;
  }

  if( !req.body ){
    res.json( {error: 'no project data received' }, 500 );
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {

    if( err ){
      res.json( {error: 'internal db error' }, 500 );
      return;
    }

    if( !doc ){
      doc = new UserModel({
        email: email
      });
    }

    var proj;
    for( var i=0, l=doc.projects.length; i<l; ++i ){
      // purposeful lazy comparison here (String -> string)
      if( doc.projects[ i ]._id == req.body.id ){
        proj = doc.projects[ i ];
      }
    }

    if( !proj ){
      if( req.body.id ){
        res.json( {error: 'id specified but not found. data corruption or haxxors.'}, 500 );
        return;
      }
      var proj = new ProjectModel({
        name: req.body.name,
        html: req.body.html,
        template: req.body.template,
        data: JSON.stringify( req.body.data ),
        customData: JSON.stringify( req.body.customData, null, 2 )
      });
      doc.projects.push( proj );
    }
    else{
      proj.template = req.body.template;
      proj.name = req.body.name;
      proj.html = req.body.html;
      proj.data = JSON.stringify( req.body.data );
      proj.customData = JSON.stringify( req.body.customData, null, 2 );
    }

    doc.save();

    res.json({ error: 'okay', project: proj });
    return;

  });
});

app.get('/api/whoami', function( req, res ) {
  var email = req.session.email;

  if ( !email ) {
    res.json( { error: 'unauthorized' }, 403 );
    return;
  }

  res.json({
    email: email,
    name: email,
    username: email
  });
});

var port = process.env.PORT || CONFIG.server.bindPort;

app.listen(port, CONFIG.server.bindIP, function() {
  var addy = app.address();
  console.log('HTTP Server started on http://' + CONFIG.server.bindIP + ':' + addy.port);
  console.log('Press Ctrl+C to stop');
});
<|endoftext|>


<commit_before>import CoreClient from './core-client';
import request from 'request';
import {
  AuthenticationError
}
from '../errors';
import config from '../config';
const conf = config();
const timeout = conf.upstreamTimeoutMs;
const {username, password} = conf.soda;

class Auth extends CoreClient {
  constructor(message, zk, logger) {
    super(zk);
    // why is the auth stuff stored in the file-type?
    // why is it escaped 3 times, so we need to JSON.parse it 3 times?
    // because reasons???????
    this._underlying = message['file-type'].auth;
    this._userId = message.user;
    this.log = logger;
  }

  get reqId() {
    return this._underlying.reqId;
  }

  get host() {
    return this._underlying.host;
  }

  get basic() {
    return this._underlying.auth;
  }

  get spoofee() {
    return this._spoofee;
  }

  headers() {
    return {
      'X-Socrata-Host': this.host,
      'X-Socrata-RequestId': this.reqId,
      'Cookie': this.cookie,
      'Content-Type': 'application/json',
      'User-Agent': 'geo-import'
    };
  }

  spoof(onComplete) {
    return this.url((err, url) => {
      if(err) return onComplete(err);

      request({
        method: 'GET',
        url: `${url}/users/${this._userId}`,
        auth: {
          user: username,
          pass: password
        },
        timeout,
        headers: {
          'X-Socrata-Host': this.host
        },
        json: true
      }, (err, response, {email}) => {
        if(err) return onComplete(err);
        this.log.info(`Authenticating as ${email} using ${username}`);

        request({
          method: 'POST',
          url: `${url}/authenticate`,
          timeout,
          form: {
            username: `${email} ${username}`,
            password
          },
          headers: {
            'X-Socrata-Host': this.host
          }
        }, (err, response, body) => {
          if(err) onComplete(new AuthenticationError(response.statusCode, body));
          this.cookie = response.headers['set-cookie'];
          this.log.info(`Successfully spoofed ${email}`);
          onComplete();
        });
      });
    });

  }
}

export default Auth;
<commit_msg>fix error handling in spoofing<commit_after>import CoreClient from './core-client';
import request from 'request';
import {
  AuthenticationError
}
from '../errors';
import config from '../config';
const conf = config();
const timeout = conf.upstreamTimeoutMs;
const {username, password} = conf.soda;

class Auth extends CoreClient {
  constructor(message, zk, logger) {
    super(zk);
    // why is the auth stuff stored in the file-type?
    // why is it escaped 3 times, so we need to JSON.parse it 3 times?
    // because reasons???????
    this._underlying = message['file-type'].auth;
    this._userId = message.user;
    this.log = logger;
  }

  get reqId() {
    return this._underlying.reqId;
  }

  get host() {
    return this._underlying.host;
  }

  get basic() {
    return this._underlying.auth;
  }

  get spoofee() {
    return this._spoofee;
  }

  headers() {
    return {
      'X-Socrata-Host': this.host,
      'X-Socrata-RequestId': this.reqId,
      'Cookie': this.cookie,
      'Content-Type': 'application/json',
      'User-Agent': 'geo-import'
    };
  }

  spoof(onComplete) {
    return this.url((err, url) => {
      if(err) return onComplete(err);

      request({
        method: 'GET',
        url: `${url}/users/${this._userId}`,
        auth: {
          user: username,
          pass: password
        },
        timeout,
        headers: {
          'X-Socrata-Host': this.host
        },
        json: true
      }, (err, response, result) => {
        if(err) return onComplete(err);
        const email = result.email;
        this.log.info(`Authenticating as ${email} using ${username}`);

        request({
          method: 'POST',
          url: `${url}/authenticate`,
          timeout,
          form: {
            username: `${email} ${username}`,
            password
          },
          headers: {
            'X-Socrata-Host': this.host
          }
        }, (err, response, body) => {
          if(err) onComplete(new AuthenticationError(response.statusCode, body));
          this.cookie = response.headers['set-cookie'];
          this.log.info(`Successfully spoofed ${email}`);
          onComplete();
        });
      });
    });

  }
}

export default Auth;
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Sankarsan Kampa
 *                    https://sankarsankampa.com/contact
 *
 * This file is a part of Bastion Discord BOT.
 *                        https://github.com/snkrsnkampa/Bastion
 *
 * This code is licensed under the SNKRSN Shared License. It is free to
 * download, copy, compile, use, study and refer under the terms of the
 * SNKRSN Shared License. You can modify the code only for personal or
 * internal use only. However, you can not redistribute the code without
 * explicitly getting permission fot it.
 *
 * Bastion BOT is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY. See the SNKRSN Shared License for
 * more details.
 *
 * You should have received a copy of the SNKRSN Shared License along
 * with this program. If not, see <https://github.com/snkrsnkampa/Bastion/LICENSE>.
 */

const sql = require('sqlite');
sql.open('./data/Bastion.sqlite');

module.exports = member => {
  sql.get(`SELECT greet, greetMessage, greetChannelID, greetTimeout FROM guildSettings WHERE guildID=${member.guild.id}`).then(row => {
    if (!row) return;

    if (row.greet == 'true') {
      let greetMsg = row.greetMessage;
      greetMsg = greetMsg.replace(/\$user/ig, `<@${member.id}>`);
      greetMsg = greetMsg.replace(/\$server/ig, member.guild.name);
      greetMsg = greetMsg.replace(/\$username/ig, member.displayName);
      greetMsg = greetMsg.replace(/\$prefix/ig, member.client.config.prefix);

      member.guild.channels.get(row.greetChannelID).sendMessage('', {embed: {
        color: member.client.colors.green,
        title: `Hello ${member.displayName}`,
        description: greetMsg
      }}).then(m => {
        if (row.greetTimeout > 0) {
          m.delete(1000*parseInt(row.greetTimeout)).catch(e => {
            member.client.log.error(e.stack);
          });
        }
      }).catch(e => {
        member.client.log.error(e.stack);
      });
    }
  }).catch(e => {
    member.client.log.error(e.stack);
  });

  sql.get(`SELECT log, logChannelID FROM guildSettings WHERE guildID=${member.guild.id}`).then(row => {
    if (!row) return;
    if (row.log == 'false') return;

    member.guild.channels.get(row.logChannelID).sendMessage('', {embed: {
      color: member.client.colors.green,
      title: 'User Joined',
      fields: [
        {
          name: 'Username',
          value: `**${member.user.username}**#${member.user.discriminator}`,
          inline: true
        },
        {
          name: 'ID',
          value: member.id,
          inline: true
        },
        {
          name: 'Joined At',
          value: member.joinedAt.toUTCString(),
          inline: false
        }
      ]
    }}).catch(e => {
      member.client.log.error(e.stack);
    });
  }).catch(e => {
    member.client.log.error(e.stack);
  });
};
<commit_msg>Added auto assignable roles module<commit_after>/*
 * Copyright (C) 2017 Sankarsan Kampa
 *                    https://sankarsankampa.com/contact
 *
 * This file is a part of Bastion Discord BOT.
 *                        https://github.com/snkrsnkampa/Bastion
 *
 * This code is licensed under the SNKRSN Shared License. It is free to
 * download, copy, compile, use, study and refer under the terms of the
 * SNKRSN Shared License. You can modify the code only for personal or
 * internal use only. However, you can not redistribute the code without
 * explicitly getting permission fot it.
 *
 * Bastion BOT is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY. See the SNKRSN Shared License for
 * more details.
 *
 * You should have received a copy of the SNKRSN Shared License along
 * with this program. If not, see <https://github.com/snkrsnkampa/Bastion/LICENSE>.
 */

const sql = require('sqlite');
sql.open('./data/Bastion.sqlite');

module.exports = member => {
  sql.get(`SELECT greet, greetMessage, greetChannelID, greetTimeout FROM guildSettings WHERE guildID=${member.guild.id}`).then(row => {
    if (!row) return;

    if (row.greet == 'true') {
      let greetMsg = row.greetMessage;
      greetMsg = greetMsg.replace(/\$user/ig, `<@${member.id}>`);
      greetMsg = greetMsg.replace(/\$server/ig, member.guild.name);
      greetMsg = greetMsg.replace(/\$username/ig, member.displayName);
      greetMsg = greetMsg.replace(/\$prefix/ig, member.client.config.prefix);

      member.guild.channels.get(row.greetChannelID).sendMessage('', {embed: {
        color: member.client.colors.green,
        title: `Hello ${member.displayName}`,
        description: greetMsg
      }}).then(m => {
        if (row.greetTimeout > 0) {
          m.delete(1000*parseInt(row.greetTimeout)).catch(e => {
            member.client.log.error(e.stack);
          });
        }
      }).catch(e => {
        member.client.log.error(e.stack);
      });
    }
  }).catch(e => {
    member.client.log.error(e.stack);
  });

  sql.get(`SELECT log, logChannelID FROM guildSettings WHERE guildID=${member.guild.id}`).then(row => {
    if (!row) return;
    if (row.log == 'false') return;

    member.guild.channels.get(row.logChannelID).sendMessage('', {embed: {
      color: member.client.colors.green,
      title: 'User Joined',
      fields: [
        {
          name: 'Username',
          value: `**${member.user.username}**#${member.user.discriminator}`,
          inline: true
        },
        {
          name: 'ID',
          value: member.id,
          inline: true
        },
        {
          name: 'Joined At',
          value: member.joinedAt.toUTCString(),
          inline: false
        }
      ]
    }}).catch(e => {
      member.client.log.error(e.stack);
    });
  }).catch(e => {
    member.client.log.error(e.stack);
  });

  sql.get(`SELECT autoAssignableRoles FROM guildSettings WHERE guildID=${member.guild.id}`).then(row => {
    if (!row) return;

    autoAssignableRoles = JSON.parse(row.autoAssignableRoles);
    autoAssignableRoles = autoAssignableRoles.filter(r => member.guild.roles.get(r));
    member.guild.members.get(member.id).addRoles(autoAssignableRoles).catch(e => {
      member.client.log.error(e.stack);
    });
  }).catch(e => {
    member.client.log.error(e.stack);
  });
};
<|endoftext|>


<commit_before>/**
 * @file presenceUpdate event
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

module.exports = async (oldMember, newMember) => {
  try {
    if (newMember.user.bot) return;
    if (newMember.roles.size < 2) return;
    if (newMember.user.presence.status === 'offline') return;
    if (oldMember.frozenPresence.game && newMember.user.presence.game && oldMember.frozenPresence.game.type === newMember.user.presence.game.type) return;

    let guildSettings = await newMember.client.db.get(`SELECT streamerRole FROM guildSettings WHERE guildID=${newMember.guild.id}`);
    if (!guildSettings || !guildSettings.streamerRole) return;

    let streamerRole = newMember.guild.roles.get(guildSettings.streamerRole);
    if (!streamerRole) return;

    if (!newMember.user.presence.game || newMember.user.presence.game.type !== 1) {
      if (!newMember.roles.has(streamerRole.id)) return;
      await newMember.removeRole(streamerRole, 'Stopped streaming').catch(() => {});
    }

    await newMember.addRole(streamerRole, 'Started streaming').catch(() => {});
  }
  catch (e) {
    newMember.client.log.error(e);
  }
};
<commit_msg>events: fixed streamer role being readded after being removed<commit_after>/**
 * @file presenceUpdate event
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

module.exports = async (oldMember, newMember) => {
  try {
    if (newMember.user.bot) return;
    if (newMember.roles.size < 2) return;
    if (newMember.user.presence.status === 'offline') return;
    if (oldMember.frozenPresence.game && newMember.user.presence.game && oldMember.frozenPresence.game.type === newMember.user.presence.game.type) return;

    let guildSettings = await newMember.client.db.get(`SELECT streamerRole FROM guildSettings WHERE guildID=${newMember.guild.id}`);
    if (!guildSettings || !guildSettings.streamerRole) return;

    let streamerRole = newMember.guild.roles.get(guildSettings.streamerRole);
    if (!streamerRole) return;

    if (!newMember.user.presence.game || newMember.user.presence.game.type !== 1) {
      if (!newMember.roles.has(streamerRole.id)) return;
      await newMember.removeRole(streamerRole, 'Stopped streaming').catch(() => {});
    }
    else {
      await newMember.addRole(streamerRole, 'Started streaming').catch(() => {});
    }
  }
  catch (e) {
    newMember.client.log.error(e);
  }
};
<|endoftext|>


<commit_before>'use strict';

var spi = require('bindings')('spi');

// Determine the temperature using a TMP36 analog temperature sensor wired to
// channel 5 on an MCP3008 SPI A/D converter

// The MCP3008 is on bus 0 and it's device 0
var mcp3008 = spi.open(0, 0, function (err) {
  // An SPI message is an array of one or read+write transfers
  var message = [{
    sendBuffer: new Buffer([0x01, 0xd0, 0x00]), // Sent to read channel 5
    receiveBuffer: new Buffer(3),               // Raw data read from channel 5
    byteLength: 3,
    speed: 20000 // Use a low bus speed to get a good reading from the TMP36
  }];

  if (err) {
    throw err;
  }

  mcp3008.transfer(message, function (err, message) {
    var rawValue;
    var voltage;
    var celcius;

    if (err) {
      throw err;
    }

    // Convert raw value from sensor to celcius and log to console
    rawValue = (message[0].receiveBuffer[1] << 8) +
      message[0].receiveBuffer[2];
    voltage = rawValue * 3.3 / 1024;
    celcius = (voltage - 0.5) * 100;

    console.log(celcius);
  });
});

<commit_msg>fixed typo<commit_after>'use strict';

var spi = require('bindings')('spi');

// Determine the temperature using a TMP36 analog temperature sensor wired to
// channel 5 on an MCP3008 SPI A/D converter

// The MCP3008 is on bus 0 and it's device 0
var mcp3008 = spi.open(0, 0, function (err) {
  // An SPI message is an array of one or more read+write transfers
  var message = [{
    sendBuffer: new Buffer([0x01, 0xd0, 0x00]), // Sent to read channel 5
    receiveBuffer: new Buffer(3),               // Raw data read from channel 5
    byteLength: 3,
    speed: 20000 // Use a low bus speed to get a good reading from the TMP36
  }];

  if (err) {
    throw err;
  }

  mcp3008.transfer(message, function (err, message) {
    var rawValue;
    var voltage;
    var celcius;

    if (err) {
      throw err;
    }

    // Convert raw value from sensor to celcius and log to console
    rawValue = (message[0].receiveBuffer[1] << 8) +
      message[0].receiveBuffer[2];
    voltage = rawValue * 3.3 / 1024;
    celcius = (voltage - 0.5) * 100;

    console.log(celcius);
  });
});

<|endoftext|>


<commit_before>/* global require */

var cloak = require('../../src/server/cloak');
var _ = require('underscore');

cloak.configure({
  // 3 hour room life
  roomLife: 1000*60*60*3,

  messages: {
    requestCard: function(arg, user) {
      var card = user.room.deck.draw(user.team);
      user.room.lastCard = card;
      user.message('card', card);
    },

    turnDone: function(targetId, user) {
      // If it's currently the turn of the user and they say they're done, advance the turn
      if (user.team === user.room.turn) {
        user.room.turn = (user.room.turn === 'red') ? 'black' : 'red';
      }
      // let the other player know
      var otherPlayer = _.reject(user.room.members, function(member) {
        return member.id === user.id;
      });
      otherPlayer[0].message('placedTarget', [targetId, user.room.lastCard]);
      // let the users know what turn it is
      user.room.messageMembers('turn', user.room.turn);
    }
  },

  room: {
    init: function() {
      this.turn = 'red';
      this.lastCard = {};

      this.teams = {
        red: '',
        black: ''
      };

      this.deck = {
        red: [],
        black: [],
        draw: function(suit) {
          var index = Math.floor(Math.random()*this[suit].length);
          return this[suit].splice(index,1)[0];
        }
      };

      var nums = ['▲', '1', '2', '3', '4', '5', '6', '7', '8', '9', '●', '●', '●', '●'];

      _.each(nums, function(num) {
        this.deck.black.push({ suit: 'black', val: num });
        this.deck.black.push({ suit: 'black', val: num });
        this.deck.red.push({ suit: 'red', val: num });
        this.deck.red.push({ suit: 'red', val: num });
      }.bind(this));

      console.log('created room ' + this.id);
      this.data.lastReportedAge = 0;
    },

    newMember: function(user) {
      if (this.teams.red === '') {
        this.teams.red = user.id;
        user.team = 'red';
        user.message('userMessage', 'your team is red and your id is ' + user.id);
      }
      else if (this.teams.black === '') {
        this.teams.black = user.id;
        user.team = 'black';
        user.message('userMessage', 'your team is black and your id is ' + user.id);
      }
      else {
        var msg = 'Um, we tried to assign a team member but all teams were taken for this room.';
        console.log(msg);
        user.team = 'none';
        user.message('userMessage', msg);
      }
      user.message('assignTeam', user.team);
      user.message('turn', this.turn);
      console.log(this.teams);
    },

    pulse: function() {
      // add timed turn stuff here
    },

    close: function() {
      this.messageMembers('you have left ' + this.name);
    }

  }

});

cloak.createRoom('room', 2);

cloak.run();
<commit_msg>correct deck<commit_after>/* global require */

var cloak = require('../../src/server/cloak');
var _ = require('underscore');

cloak.configure({
  // 3 hour room life
  roomLife: 1000*60*60*3,

  messages: {
    requestCard: function(arg, user) {
      var card = user.room.deck.draw(user.team);
      user.room.lastCard = card;
      user.message('card', card);
    },

    turnDone: function(targetId, user) {
      // If it's currently the turn of the user and they say they're done, advance the turn
      if (user.team === user.room.turn) {
        user.room.turn = (user.room.turn === 'red') ? 'black' : 'red';
      }
      // let the other player know
      var otherPlayer = _.reject(user.room.members, function(member) {
        return member.id === user.id;
      });
      otherPlayer[0].message('placedTarget', [targetId, user.room.lastCard]);
      // let the users know what turn it is
      user.room.messageMembers('turn', user.room.turn);
    }
  },

  room: {
    init: function() {
      this.turn = 'red';
      this.lastCard = {};

      this.teams = {
        red: '',
        black: ''
      };

      this.deck = {
        red: [],
        black: [],
        draw: function(suit) {
          var index = Math.floor(Math.random()*this[suit].length);
          return this[suit].splice(index,1)[0];
        }
      };

      var nums = ['▲', '2', '3', '4', '5', '6', '7', '8', '9', '●', '●', '●', '●'];

      _.each(nums, function(num) {
        this.deck.black.push({ suit: 'black', val: num });
        this.deck.black.push({ suit: 'black', val: num });
        this.deck.red.push({ suit: 'red', val: num });
        this.deck.red.push({ suit: 'red', val: num });
      }.bind(this));

      console.log('created room ' + this.id);
      this.data.lastReportedAge = 0;
    },

    newMember: function(user) {
      if (this.teams.red === '') {
        this.teams.red = user.id;
        user.team = 'red';
        user.message('userMessage', 'your team is red and your id is ' + user.id);
      }
      else if (this.teams.black === '') {
        this.teams.black = user.id;
        user.team = 'black';
        user.message('userMessage', 'your team is black and your id is ' + user.id);
      }
      else {
        var msg = 'Um, we tried to assign a team member but all teams were taken for this room.';
        console.log(msg);
        user.team = 'none';
        user.message('userMessage', msg);
      }
      user.message('assignTeam', user.team);
      user.message('turn', this.turn);
      console.log(this.teams);
    },

    pulse: function() {
      // add timed turn stuff here
    },

    close: function() {
      this.messageMembers('you have left ' + this.name);
    }

  }

});

cloak.createRoom('room', 2);

cloak.run();
<|endoftext|>


<commit_before>var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language;

var device = function(name, lang = 'en') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip) {
  deviceAddress = ip;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'us';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

var notify = function(message, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getSpeechUrl(message, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getSpeechUrl(message, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var play = function(mp3_url, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getPlayUrl(mp3_url, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getPlayUrl(mp3_url, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var getSpeechUrl = function(text, host, callback) {
  googletts(text, language, 1, 1000, googlettsaccent).then(function (url) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
  }).catch(function (err) {
    console.error(err.stack);
  });
};

var getPlayUrl = function(url, host, callback) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
};

var onDeviceUp = function(host, url, callback) {
  var client = new Client();
  client.connect(host, function() {
    client.launch(DefaultMediaReceiver, function(err, player) {

      var media = {
        contentId: url,
        contentType: 'audio/mp3',
        streamType: 'BUFFERED' // or LIVE
      };
      player.load(media, { autoplay: true }, function(err, status) {
        client.close();
        callback('Device notified');
      });
    });
  });

  client.on('error', function(err) {
    console.log('Error: %s', err.message);
    client.close();
    callback('error');
  });
};

exports.ip = ip;
exports.device = device;
exports.accent = accent;
exports.notify = notify;
exports.play = play;
<commit_msg>fix ip function<commit_after>var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
var deviceAddress;
var language;

var device = function(name, lang = 'en') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip, lang = 'en') {
  deviceAddress = ip;
  language = lang;
  return this;
}

var googletts = require('google-tts-api');
var googlettsaccent = 'us';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

var notify = function(message, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getSpeechUrl(message, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getSpeechUrl(message, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var play = function(mp3_url, callback) {
  if (!deviceAddress){
    browser.start();
    browser.on('serviceUp', function(service) {
      console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
      if (service.name.includes(device.replace(' ', '-'))){
        deviceAddress = service.addresses[0];
        getPlayUrl(mp3_url, deviceAddress, function(res) {
          callback(res);
        });
      }
      browser.stop();
    });
  }else {
    getPlayUrl(mp3_url, deviceAddress, function(res) {
      callback(res);
    });
  }
};

var getSpeechUrl = function(text, host, callback) {
  googletts(text, language, 1, 1000, googlettsaccent).then(function (url) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
  }).catch(function (err) {
    console.error(err.stack);
  });
};

var getPlayUrl = function(url, host, callback) {
    onDeviceUp(host, url, function(res){
      callback(res)
    });
};

var onDeviceUp = function(host, url, callback) {
  var client = new Client();
  client.connect(host, function() {
    client.launch(DefaultMediaReceiver, function(err, player) {

      var media = {
        contentId: url,
        contentType: 'audio/mp3',
        streamType: 'BUFFERED' // or LIVE
      };
      player.load(media, { autoplay: true }, function(err, status) {
        client.close();
        callback('Device notified');
      });
    });
  });

  client.on('error', function(err) {
    console.log('Error: %s', err.message);
    client.close();
    callback('error');
  });
};

exports.ip = ip;
exports.device = device;
exports.accent = accent;
exports.notify = notify;
exports.play = play;
<|endoftext|>


<commit_before>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {
	attributionControl: false,
	scrollWheelZoom: false
}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.baselayer_land/{z}/{x}/{y}.png', {
	minZoom: 5,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var southWest = new L.LatLng(30.8, -85.7),
	northEast = new L.LatLng(47.58, -67),
	bounds = new L.LatLngBounds(southWest, northEast);

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://amzncache.boston.com/partners/maps/snowfall.png', bounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

// Get the time right now.
var date = new Date();

// Construct a new date with no minutes or seconds.
var hourDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());

// Populate the 'updated' element.
$('.updated-timestamp').html('Updated ' + [APDateTime.time(hourDate), APDateTime.date(hourDate)].join(', '));<commit_msg>switch to static image for now<commit_after>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {
	attributionControl: false,
	scrollWheelZoom: false
}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.baselayer_land/{z}/{x}/{y}.png', {
	minZoom: 5,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var southWest = new L.LatLng(30.8, -85.7),
	northEast = new L.LatLng(47.58, -67),
	bounds = new L.LatLngBounds(southWest, northEast);

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://cache.boston.com/multimedia/graphics/projectFiles/2015/snowfall/snowfall.png', bounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

// Get the time right now.
var date = new Date();

// Construct a new date with no minutes or seconds.
var hourDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());

// Populate the 'updated' element.
// $('.updated-timestamp').html('Updated ' + [APDateTime.time(hourDate), APDateTime.date(hourDate)].join(', '));

// Populate the 'updated' element.
$('.updated-timestamp').html('Updated 6 p.m., Jan. 27, 2015');

<|endoftext|>


<commit_before>  var PEG, coffee, grammar, parser, r;

  PEG = require('pegjs');

  grammar = 'start = a:\'a\'i ';

  parser = PEG.buildParser(grammar);

  r = parser.parse('A');

  console.log(r);

  parser = PEG.buildParser(grammar);

  r = parser.parse('a');

  console.log(r);

<commit_msg>ignorecase<commit_after>"use strict"
const PEG, grammar, parser;
let r;

PEG = require('pegjs');

grammar = `start = a: 'a'i `;

parser = PEG.buildParser(grammar);
r = parser.parse('A');
console.log(r);

parser = PEG.buildParser(grammar);
r = parser.parse('a');
console.log(r);

<|endoftext|>


<commit_before>import React from 'react'
import {
  Container,
  Divider,
  Dropdown,
  Grid,
  Header,
  Image,
  List,
  Menu,
  Segment,
} from 'semantic-ui-react'

const FixedMenuLayout = () => (

    <Menu fixed='top' inverted>
      <Container>
        <Menu.Item as='a' header>
          <Image size='mini' src='/logo.png' style={{ marginRight: '1.5em' }} />
          Project Name
        </Menu.Item>
        <Menu.Item as='a'>Home</Menu.Item>

        <Dropdown item simple text='Dropdown'>
          <Dropdown.Menu>
            <Dropdown.Item>List Item</Dropdown.Item>
            <Dropdown.Item>List Item</Dropdown.Item>
            <Dropdown.Divider />
            <Dropdown.Header>Header Item</Dropdown.Header>
            <Dropdown.Item>

              Submenu
              <Dropdown.Menu>
                <Dropdown.Item>List Item</Dropdown.Item>
                <Dropdown.Item>List Item</Dropdown.Item>
              </Dropdown.Menu>
            </Dropdown.Item>
            <Dropdown.Item>List Item</Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown>
      </Container>
    </Menu>

    <Container text style={{ marginTop: '7em' }}>
      Semantic UI React Fixed Template

This is a basic fixed menu template using fixed size containers.

        A text container is used for the main container, which is useful for single column layouts.

      <Image src='/images/wireframe/media-paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
    </Container>

    <Segment inverted vertical style={{ margin: '5em 0em 0em', padding: '5em 0em' }}>
      <Container textAlign='center'>
        <Grid divided inverted stackable>
          <Grid.Row>
            <Grid.Column width={3}>

              <List link inverted>
                <List.Item as='a'>Link One</List.Item>
                <List.Item as='a'>Link Two</List.Item>
                <List.Item as='a'>Link Three</List.Item>
                <List.Item as='a'>Link Four</List.Item>
              </List>
            </Grid.Column>
            <Grid.Column width={3}>

              <List link inverted>
                <List.Item as='a'>Link One</List.Item>
                <List.Item as='a'>Link Two</List.Item>
                <List.Item as='a'>Link Three</List.Item>
                <List.Item as='a'>Link Four</List.Item>
              </List>
            </Grid.Column>
            <Grid.Column width={3}>

              <List link inverted>
                <List.Item as='a'>Link One</List.Item>
                <List.Item as='a'>Link Two</List.Item>
                <List.Item as='a'>Link Three</List.Item>
                <List.Item as='a'>Link Four</List.Item>
              </List>
            </Grid.Column>
            <Grid.Column width={7}>

                Extra space for a call to action inside the footer that could help re-engage users.

            </Grid.Column>
          </Grid.Row>
        </Grid>

        <Divider inverted section />
        <Image centered size='mini' src='/logo.png' />
        <List horizontal inverted divided link>
          <List.Item as='a' href='#'>
            Site Map
          </List.Item>
          <List.Item as='a' href='#'>
            Contact Us
          </List.Item>
          <List.Item as='a' href='#'>
            Terms and Conditions
          </List.Item>
          <List.Item as='a' href='#'>
            Privacy Policy
          </List.Item>
        </List>
      </Container>
    </Segment>

)

export default FixedMenuLayout
<commit_msg>docs(Layouts): update FixedMenuLayout (#3316)<commit_after>import React from 'react'
import {
  Container,
  Divider,
  Dropdown,
  Grid,
  Header,
  Image,
  List,
  Menu,
  Segment,
} from 'semantic-ui-react'

const FixedMenuLayout = () => (

    <Menu fixed='top' inverted>
      <Container>
        <Menu.Item as='a' header>
          <Image size='mini' src='/logo.png' style={{ marginRight: '1.5em' }} />
          Project Name
        </Menu.Item>
        <Menu.Item as='a'>Home</Menu.Item>

        <Dropdown item simple text='Dropdown'>
          <Dropdown.Menu>
            <Dropdown.Item>List Item</Dropdown.Item>
            <Dropdown.Item>List Item</Dropdown.Item>
            <Dropdown.Divider />
            <Dropdown.Header>Header Item</Dropdown.Header>
            <Dropdown.Item>

              Submenu
              <Dropdown.Menu>
                <Dropdown.Item>List Item</Dropdown.Item>
                <Dropdown.Item>List Item</Dropdown.Item>
              </Dropdown.Menu>
            </Dropdown.Item>
            <Dropdown.Item>List Item</Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown>
      </Container>
    </Menu>

    <Container text style={{ marginTop: '7em' }}>
      Semantic UI React Fixed Template

This is a basic fixed menu template using fixed size containers.

        A text container is used for the main container, which is useful for single column layouts.

      <Image src='/images/wireframe/media-paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
      <Image src='/images/wireframe/paragraph.png' style={{ marginTop: '2em' }} />
    </Container>

    <Segment inverted vertical style={{ margin: '5em 0em 0em', padding: '5em 0em' }}>
      <Container textAlign='center'>
        <Grid divided inverted stackable>
          <Grid.Column width={3}>

            <List link inverted>
              <List.Item as='a'>Link One</List.Item>
              <List.Item as='a'>Link Two</List.Item>
              <List.Item as='a'>Link Three</List.Item>
              <List.Item as='a'>Link Four</List.Item>
            </List>
          </Grid.Column>
          <Grid.Column width={3}>

            <List link inverted>
              <List.Item as='a'>Link One</List.Item>
              <List.Item as='a'>Link Two</List.Item>
              <List.Item as='a'>Link Three</List.Item>
              <List.Item as='a'>Link Four</List.Item>
            </List>
          </Grid.Column>
          <Grid.Column width={3}>

            <List link inverted>
              <List.Item as='a'>Link One</List.Item>
              <List.Item as='a'>Link Two</List.Item>
              <List.Item as='a'>Link Three</List.Item>
              <List.Item as='a'>Link Four</List.Item>
            </List>
          </Grid.Column>
          <Grid.Column width={7}>

              Extra space for a call to action inside the footer that could help re-engage users.

          </Grid.Column>
        </Grid>

        <Divider inverted section />
        <Image centered size='mini' src='/logo.png' />
        <List horizontal inverted divided link size='small'>
          <List.Item as='a' href='#'>
            Site Map
          </List.Item>
          <List.Item as='a' href='#'>
            Contact Us
          </List.Item>
          <List.Item as='a' href='#'>
            Terms and Conditions
          </List.Item>
          <List.Item as='a' href='#'>
            Privacy Policy
          </List.Item>
        </List>
      </Container>
    </Segment>

)

export default FixedMenuLayout
<|endoftext|>


<commit_before>goog.require('ol.Attribution');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.extent');
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.MapQuest');
goog.require('ol.source.TileImage');
goog.require('ol.source.TileWMS');
goog.require('ol.source.WMTS');
goog.require('ol.source.XYZ');
goog.require('ol.tilegrid.TileGrid');

proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
    '+x_0=400000 +y_0=-100000 +ellps=airy ' +
    '+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
    '+units=m +no_defs');
var proj27700 = ol.proj.get('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);

proj4.defs('EPSG:23032', '+proj=utm +zone=32 +ellps=intl ' +
    '+towgs84=-87,-98,-121,0,0,0,0 +units=m +no_defs');
var proj23032 = ol.proj.get('EPSG:23032');
proj23032.setExtent([-1206118.71, 4021309.92, 1295389.00, 8051813.28]);

proj4.defs('EPSG:5479', '+proj=lcc +lat_1=-76.66666666666667 +lat_2=' +
    '-79.33333333333333 +lat_0=-78 +lon_0=163 +x_0=7000000 +y_0=5000000 ' +
    '+ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
var proj5479 = ol.proj.get('EPSG:5479');
proj5479.setExtent([6825737.53, 4189159.80, 9633741.96, 5782472.71]);

proj4.defs('EPSG:21781', '+proj=somerc +lat_0=46.95240555555556 ' +
    '+lon_0=7.439583333333333 +k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel ' +
    '+towgs84=674.4,15.1,405.3,0,0,0,0 +units=m +no_defs');
var proj21781 = ol.proj.get('EPSG:21781');
proj21781.setExtent([485071.54, 75346.36, 828515.78, 299941.84]);

proj4.defs('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 ' +
    '+x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
var proj3413 = ol.proj.get('EPSG:3413');
proj3413.setExtent([-4194304, -4194304, 4194304, 4194304]);

proj4.defs('EPSG:2163', '+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 ' +
    '+a=6370997 +b=6370997 +units=m +no_defs');
var proj2163 = ol.proj.get('EPSG:2163');
proj2163.setExtent([-8040784.5135, -2577524.9210, 3668901.4484, 4785105.1096]);

proj4.defs('ESRI:54009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 ' +
    '+units=m +no_defs');
var proj54009 = ol.proj.get('ESRI:54009');
proj54009.setExtent([-18e6, -9e6, 18e6, 9e6]);

var layers = [];

layers['bng'] = new ol.layer.Tile({
  source: new ol.source.XYZ({
    projection: 'EPSG:27700',
    url: 'http://tileserver.maptiler.com/miniscale/{z}/{x}/{y}.png',
    crossOrigin: '',
    maxZoom: 6
  })
});

layers['mapquest'] = new ol.layer.Tile({
  source: new ol.source.MapQuest({layer: 'osm'})
});

layers['wms4326'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.boundlessgeo.com/geoserver/wms',
    crossOrigin: '',
    params: {
      'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
    },
    projection: 'EPSG:4326'
  })
});

layers['wms21781'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    attributions: [new ol.Attribution({
      html: '© ' +
          '' +
          'Pixelmap 1:1000000 / geo.admin.ch'
    })],
    crossOrigin: 'anonymous',
    params: {
      'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
      'FORMAT': 'image/jpeg'
    },
    url: 'http://wms.geo.admin.ch/',
    projection: 'EPSG:21781'
  })
});

var parser = new ol.format.WMTSCapabilities();
$.ajax('http://map1.vis.earthdata.nasa.gov/wmts-arctic/' +
    'wmts.cgi?SERVICE=WMTS&request=GetCapabilities').then(function(response) {
  var result = parser.read(response);
  var options = ol.source.WMTS.optionsFromCapabilities(result,
      {layer: 'OSM_Land_Mask', matrixSet: 'EPSG3413_250m'});
  options.crossOrigin = '';
  options.projection = 'EPSG:3413';
  options.wrapX = false;
  layers['wmts3413'] = new ol.layer.Tile({
    source: new ol.source.WMTS(options)
  });
});

layers['grandcanyon'] = new ol.layer.Tile({
  source: new ol.source.XYZ({
    url: 'http://tileserver.maptiler.com/grandcanyon@2x/{z}/{x}/{y}.png',
    crossOrigin: '',
    tilePixelRatio: 2,
    maxZoom: 15,
    attributions: [new ol.Attribution({
      html: 'Tiles © USGS, rendered with ' +
          'MapTiler'
    })]
  })
});

var startResolution =
    ol.extent.getWidth(ol.proj.get('EPSG:3857').getExtent()) / 256;
var resolutions = new Array(22);
for (var i = 0, ii = resolutions.length; i < ii; ++i) {
  resolutions[i] = startResolution / Math.pow(2, i);
}

layers['states'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.boundlessgeo.com/geoserver/wms',
    crossOrigin: '',
    params: {'LAYERS': 'topp:states', 'TILED': true},
    serverType: 'geoserver',
    tileGrid: new ol.tilegrid.TileGrid({
      extent: [-13884991, 2870341, -7455066, 6338219],
      resolutions: resolutions,
      tileSize: [512, 256]
    }),
    projection: 'EPSG:3857'
  })
});

var map = new ol.Map({
  layers: [
    layers['mapquest'],
    layers['bng']
  ],
  renderer: common.getRendererFromQueryString(),
  target: 'map',
  view: new ol.View({
    projection: 'EPSG:3857',
    center: [0, 0],
    zoom: 2
  })
});

var baseLayerSelect = document.getElementById('base-layer');
var overlayLayerSelect = document.getElementById('overlay-layer');
var viewProjSelect = document.getElementById('view-projection');
var renderEdgesCheckbox = document.getElementById('render-edges');
var renderEdges = false;

function updateViewProjection() {
  var newProj = ol.proj.get(viewProjSelect.value);
  var newProjExtent = newProj.getExtent();
  var newView = new ol.View({
    projection: newProj,
    center: ol.extent.getCenter(newProjExtent || [0, 0, 0, 0]),
    zoom: 0,
    extent: newProjExtent || undefined
  });
  map.setView(newView);
}

/**
 * @param {Event} e Change event.
 */
viewProjSelect.onchange = function(e) {
  updateViewProjection();
};

updateViewProjection();

var updateRenderEdgesOnLayer = function(layer) {
  if (layer instanceof ol.layer.Tile) {
    var source = layer.getSource();
    if (source instanceof ol.source.TileImage) {
      source.setRenderReprojectionEdges(renderEdges);
    }
  }
};

/**
 * @param {Event} e Change event.
 */
baseLayerSelect.onchange = function(e) {
  var layer = layers[baseLayerSelect.value];
  if (layer) {
    layer.setOpacity(1);
    updateRenderEdgesOnLayer(layer);
    map.getLayers().setAt(0, layer);
  }
};

/**
 * @param {Event} e Change event.
 */
overlayLayerSelect.onchange = function(e) {
  var layer = layers[overlayLayerSelect.value];
  if (layer) {
    layer.setOpacity(0.7);
    updateRenderEdgesOnLayer(layer);
    map.getLayers().setAt(1, layer);
  }
};

/**
 * @param {Event} e Change event.
 */
renderEdgesCheckbox.onchange = function(e) {
  renderEdges = renderEdgesCheckbox.checked;
  map.getLayers().forEach(function(layer) {
    updateRenderEdgesOnLayer(layer);
  });
};
<commit_msg>Add demonstration of layer extent setting to reprojection example<commit_after>goog.require('ol.Attribution');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.extent');
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.MapQuest');
goog.require('ol.source.TileImage');
goog.require('ol.source.TileWMS');
goog.require('ol.source.WMTS');
goog.require('ol.source.XYZ');
goog.require('ol.tilegrid.TileGrid');

proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
    '+x_0=400000 +y_0=-100000 +ellps=airy ' +
    '+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
    '+units=m +no_defs');
var proj27700 = ol.proj.get('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);

proj4.defs('EPSG:23032', '+proj=utm +zone=32 +ellps=intl ' +
    '+towgs84=-87,-98,-121,0,0,0,0 +units=m +no_defs');
var proj23032 = ol.proj.get('EPSG:23032');
proj23032.setExtent([-1206118.71, 4021309.92, 1295389.00, 8051813.28]);

proj4.defs('EPSG:5479', '+proj=lcc +lat_1=-76.66666666666667 +lat_2=' +
    '-79.33333333333333 +lat_0=-78 +lon_0=163 +x_0=7000000 +y_0=5000000 ' +
    '+ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
var proj5479 = ol.proj.get('EPSG:5479');
proj5479.setExtent([6825737.53, 4189159.80, 9633741.96, 5782472.71]);

proj4.defs('EPSG:21781', '+proj=somerc +lat_0=46.95240555555556 ' +
    '+lon_0=7.439583333333333 +k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel ' +
    '+towgs84=674.4,15.1,405.3,0,0,0,0 +units=m +no_defs');
var proj21781 = ol.proj.get('EPSG:21781');
proj21781.setExtent([485071.54, 75346.36, 828515.78, 299941.84]);

proj4.defs('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 ' +
    '+x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
var proj3413 = ol.proj.get('EPSG:3413');
proj3413.setExtent([-4194304, -4194304, 4194304, 4194304]);

proj4.defs('EPSG:2163', '+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 ' +
    '+a=6370997 +b=6370997 +units=m +no_defs');
var proj2163 = ol.proj.get('EPSG:2163');
proj2163.setExtent([-8040784.5135, -2577524.9210, 3668901.4484, 4785105.1096]);

proj4.defs('ESRI:54009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 ' +
    '+units=m +no_defs');
var proj54009 = ol.proj.get('ESRI:54009');
proj54009.setExtent([-18e6, -9e6, 18e6, 9e6]);

var layers = [];

layers['bng'] = new ol.layer.Tile({
  source: new ol.source.XYZ({
    projection: 'EPSG:27700',
    url: 'http://tileserver.maptiler.com/miniscale/{z}/{x}/{y}.png',
    crossOrigin: '',
    maxZoom: 6
  })
});

layers['mapquest'] = new ol.layer.Tile({
  source: new ol.source.MapQuest({layer: 'osm'})
});

layers['wms4326'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.boundlessgeo.com/geoserver/wms',
    crossOrigin: '',
    params: {
      'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
    },
    projection: 'EPSG:4326'
  })
});

layers['wms21781'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    attributions: [new ol.Attribution({
      html: '© ' +
          '' +
          'Pixelmap 1:1000000 / geo.admin.ch'
    })],
    crossOrigin: 'anonymous',
    params: {
      'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
      'FORMAT': 'image/jpeg'
    },
    url: 'http://wms.geo.admin.ch/',
    projection: 'EPSG:21781'
  })
});

var parser = new ol.format.WMTSCapabilities();
$.ajax('http://map1.vis.earthdata.nasa.gov/wmts-arctic/' +
    'wmts.cgi?SERVICE=WMTS&request=GetCapabilities').then(function(response) {
  var result = parser.read(response);
  var options = ol.source.WMTS.optionsFromCapabilities(result,
      {layer: 'OSM_Land_Mask', matrixSet: 'EPSG3413_250m'});
  options.crossOrigin = '';
  options.projection = 'EPSG:3413';
  options.wrapX = false;
  layers['wmts3413'] = new ol.layer.Tile({
    source: new ol.source.WMTS(options)
  });
});

layers['grandcanyon'] = new ol.layer.Tile({
  source: new ol.source.XYZ({
    url: 'http://tileserver.maptiler.com/grandcanyon@2x/{z}/{x}/{y}.png',
    crossOrigin: '',
    tilePixelRatio: 2,
    maxZoom: 15,
    attributions: [new ol.Attribution({
      html: 'Tiles © USGS, rendered with ' +
          'MapTiler'
    })]
  })
});

var startResolution =
    ol.extent.getWidth(ol.proj.get('EPSG:3857').getExtent()) / 256;
var resolutions = new Array(22);
for (var i = 0, ii = resolutions.length; i < ii; ++i) {
  resolutions[i] = startResolution / Math.pow(2, i);
}

layers['states'] = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'http://demo.boundlessgeo.com/geoserver/wms',
    crossOrigin: '',
    params: {'LAYERS': 'topp:states', 'TILED': true},
    serverType: 'geoserver',
    tileGrid: new ol.tilegrid.TileGrid({
      extent: [-13884991, 2870341, -7455066, 6338219],
      resolutions: resolutions,
      tileSize: [512, 256]
    }),
    projection: 'EPSG:3857'
  })
});

var map = new ol.Map({
  layers: [
    layers['mapquest'],
    layers['bng']
  ],
  renderer: common.getRendererFromQueryString(),
  target: 'map',
  view: new ol.View({
    projection: 'EPSG:3857',
    center: [0, 0],
    zoom: 2
  })
});

var baseLayerSelect = document.getElementById('base-layer');
var overlayLayerSelect = document.getElementById('overlay-layer');
var viewProjSelect = document.getElementById('view-projection');
var renderEdgesCheckbox = document.getElementById('render-edges');
var renderEdges = false;

function updateViewProjection() {
  var newProj = ol.proj.get(viewProjSelect.value);
  var newProjExtent = newProj.getExtent();
  var newView = new ol.View({
    projection: newProj,
    center: ol.extent.getCenter(newProjExtent || [0, 0, 0, 0]),
    zoom: 0,
    extent: newProjExtent || undefined
  });
  map.setView(newView);

  // Example how to prevent double occurence of map by limiting layer extent
  if (newProj == ol.proj.get('EPSG:3857')) {
    layers['bng'].setExtent([-1057216, 6405988, 404315, 8759696]);
  } else {
    layers['bng'].setExtent(undefined);
  }
}

/**
 * @param {Event} e Change event.
 */
viewProjSelect.onchange = function(e) {
  updateViewProjection();
};

updateViewProjection();

var updateRenderEdgesOnLayer = function(layer) {
  if (layer instanceof ol.layer.Tile) {
    var source = layer.getSource();
    if (source instanceof ol.source.TileImage) {
      source.setRenderReprojectionEdges(renderEdges);
    }
  }
};

/**
 * @param {Event} e Change event.
 */
baseLayerSelect.onchange = function(e) {
  var layer = layers[baseLayerSelect.value];
  if (layer) {
    layer.setOpacity(1);
    updateRenderEdgesOnLayer(layer);
    map.getLayers().setAt(0, layer);
  }
};

/**
 * @param {Event} e Change event.
 */
overlayLayerSelect.onchange = function(e) {
  var layer = layers[overlayLayerSelect.value];
  if (layer) {
    layer.setOpacity(0.7);
    updateRenderEdgesOnLayer(layer);
    map.getLayers().setAt(1, layer);
  }
};

/**
 * @param {Event} e Change event.
 */
renderEdgesCheckbox.onchange = function(e) {
  renderEdges = renderEdgesCheckbox.checked;
  map.getLayers().forEach(function(layer) {
    updateRenderEdgesOnLayer(layer);
  });
};
<|endoftext|>


<commit_before>import Application from '../../packages/oors-presets/src/applications/Standard';

const app = new Application();

app.get('/', (req, res) => {
  res.send('Hello from oors!');
});

app.listen().catch(console.log.bind(console));
<commit_msg>simple example<commit_after>import Application from '../../packages/oors-presets/src/applications/Standard';
import Module from '../../packages/oors/src/libs/Module';

class SimpleModule extends Module {
  hooks = {
    'oors.graphQL.load': ({ addTypeDefs }) => {
      addTypeDefs(`
        extend type Query {
          sayHi(name: String!): String!
        }

        type Subscription {
          tick: Int!
        }
      `);
    },
  };

  async setup() {
    const { addResolvers, pubsub } = await this.dependency('oors.graphQL');

    addResolvers({
      Query: {
        sayHi: (_, { name }) => `Hi ${name}!!!`,
      },
      Subscription: {
        tick: {
          subscribe: () => pubsub.asyncIterator('tick'),
        },
      },
    });

    let counter = 0;
    setInterval(() => {
      pubsub.publish('tick', {
        tick: counter,
      });
      counter += 1;
    }, 1000);
  }
}

const app = new Application();

app.addModules(new SimpleModule());

app.get('/', (req, res) => {
  res.send('Hello from oors!');
});

app.listen().catch(console.log.bind(console));
<|endoftext|>


<commit_before>
import { Editor } from 'slate-react'
import { State } from 'slate'

import React from 'react'
import initialState from './state.json'

/**
 * The tables example.
 *
 * @type {Component}
 */

class Tables extends React.Component {

  /**
   * Deserialize the raw initial state.
   *
   * @type {Object}
   */

  state = {
    state: State.fromJSON(initialState)
  }

  /**
   * On backspace, do nothing if at the start of a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onBackspace = (event, change) => {
    const { state } = change
    if (state.startOffset != 0) return
    event.preventDefault()
    return true
  }

  /**
   * On change.
   *
   * @param {Change} change
   */

  onChange = ({ state }) => {
    this.setState({ state })
  }

  /**
   * On delete, do nothing if at the end of a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onDelete = (event, change) => {
    const { state } = change
    if (state.endOffset != state.startText.text.length) return
    event.preventDefault()
    return true
  }

  /**
   * On return, do nothing if inside a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onEnter = (event, change) => {
    event.preventDefault()
    return true
  }

  /**
   * On key down, check for our specific key shortcuts.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onKeyDown = (event, change) => {
    const { state } = change
    const { document, selection } = state
    const { startKey } = selection
    const startNode = document.getDescendant(startKey)

    if (selection.isAtStartOf(startNode)) {
      const previous = document.getPreviousText(startNode.key)
      const prevBlock = document.getClosestBlock(previous.key)

      if (prevBlock.type == 'table-cell') {
        event.preventDefault()
        return true
      }
    }

    if (state.startBlock.type != 'table-cell') {
      return
    }

    switch (event.key) {
      case 'Backspace': return this.onBackspace(event, state)
      case 'Delete': return this.onDelete(event, state)
      case 'Enter': return this.onEnter(event, state)
    }
  }

  /**
   * Render the example.
   *
   * @return {Component} component
   */

  render() {
    return (

        <Editor
          placeholder="Enter some text..."
          state={this.state.state}
          onChange={this.onChange}
          onKeyDown={this.onKeyDown}
          renderNode={this.renderNode}
          renderMark={this.renderMark}
        />

    )
  }

  /**
   * Render a Slate node.
   *
   * @param {Object} props
   * @return {Element}
   */

  renderNode = (props) => {
    const { attributes, children, node } = props
    switch (node.type) {
      case 'table': return

{children}

      case 'table-row': return
{children}

      case 'table-cell': return {children}
    }
  }

  /**
   * Render a Slate mark.
   *
   * @param {Object} props
   * @return {Element}
   */

  renderMark = (props) => {
    const { children, mark } = props
    switch (mark.type) {
      case 'bold': return {children}
    }
  }

}

/**
 * Export.
 */

export default Tables
<commit_msg>fix table handler args (#1292)<commit_after>
import { Editor } from 'slate-react'
import { State } from 'slate'

import React from 'react'
import initialState from './state.json'

/**
 * The tables example.
 *
 * @type {Component}
 */

class Tables extends React.Component {

  /**
   * Deserialize the raw initial state.
   *
   * @type {Object}
   */

  state = {
    state: State.fromJSON(initialState)
  }

  /**
   * On backspace, do nothing if at the start of a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onBackspace = (event, change) => {
    const { state } = change
    if (state.startOffset != 0) return
    event.preventDefault()
    return true
  }

  /**
   * On change.
   *
   * @param {Change} change
   */

  onChange = ({ state }) => {
    this.setState({ state })
  }

  /**
   * On delete, do nothing if at the end of a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onDelete = (event, change) => {
    const { state } = change
    if (state.endOffset != state.startText.text.length) return
    event.preventDefault()
    return true
  }

  /**
   * On return, do nothing if inside a table cell.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onEnter = (event, change) => {
    event.preventDefault()
    return true
  }

  /**
   * On key down, check for our specific key shortcuts.
   *
   * @param {Event} event
   * @param {Change} change
   */

  onKeyDown = (event, change) => {
    const { state } = change
    const { document, selection } = state
    const { startKey } = selection
    const startNode = document.getDescendant(startKey)

    if (selection.isAtStartOf(startNode)) {
      const previous = document.getPreviousText(startNode.key)
      const prevBlock = document.getClosestBlock(previous.key)

      if (prevBlock.type == 'table-cell') {
        event.preventDefault()
        return true
      }
    }

    if (state.startBlock.type != 'table-cell') {
      return
    }

    switch (event.key) {
      case 'Backspace': return this.onBackspace(event, change)
      case 'Delete': return this.onDelete(event, change)
      case 'Enter': return this.onEnter(event, change)
    }
  }

  /**
   * Render the example.
   *
   * @return {Component} component
   */

  render() {
    return (

        <Editor
          placeholder="Enter some text..."
          state={this.state.state}
          onChange={this.onChange}
          onKeyDown={this.onKeyDown}
          renderNode={this.renderNode}
          renderMark={this.renderMark}
        />

    )
  }

  /**
   * Render a Slate node.
   *
   * @param {Object} props
   * @return {Element}
   */

  renderNode = (props) => {
    const { attributes, children, node } = props
    switch (node.type) {
      case 'table': return

{children}

      case 'table-row': return
{children}

      case 'table-cell': return {children}
    }
  }

  /**
   * Render a Slate mark.
   *
   * @param {Object} props
   * @return {Element}
   */

  renderMark = (props) => {
    const { children, mark } = props
    switch (mark.type) {
      case 'bold': return {children}
    }
  }

}

/**
 * Export.
 */

export default Tables
<|endoftext|>


<commit_before>/*
 * @package jsDAV
 * @subpackage DAV
 * @copyright Copyright(c) 2011 Ajax.org B.V. <info AT ajax DOT org>
 * @author Sergi Mansilla <sergi AT ajax DOT org>
 * @license http://github.com/mikedeboer/jsDAV/blob/master/LICENSE MIT License
 */

var jsDAV               = require("../../jsdav");
var jsDAV_Tree          = require("../tree").jsDAV_Tree;
var jsDAV_Ftp_Directory = require("../ftp/directory").jsDAV_Ftp_Directory;
var jsDAV_Ftp_File      = require("../ftp/file").jsDAV_Ftp_File;

var Ftp                 = require("../../../support/jsftp/jsftp");
var Util                = require("../util");
var Exc                 = require("../exceptions");
var Path                = require('path');

var PWD_RE = /.*"(.*)".*/;

/**
 * jsDAV_Tree_Ftp
 *
 * Creates the FTP tree.
 *
 * @param {Object} options
 * @contructor
 */

Ftp.debugMode = require("../../jsdav").debugMode;

function jsDAV_Tree_Ftp(options) {
    this.options  = options.ftp;
    this.basePath = this.options.path || "./";
    this.setup();
}

exports.jsDAV_Tree_Ftp = jsDAV_Tree_Ftp;

(function() {

    this.setup = function() {
        this.ftp = new Ftp(this.options);
        this.ftp.$cache = {};
    };

    /**
     * Returns a new node for the given path
     *
     * @param {String} path
     * @return void
     */
    this.getNodeForPath = function(path, next) {
        var ftp = this.ftp;
        var self = this;

        if (path == "" || path == " " || path == "/")
            path = this.basePath;

        if (ftp.$cache[path])
            return next(null, ftp.$cache[path]);

        // Root node requires special treatment because it will not be listed
        if (path === this.basePath) {
            var baseDir = new jsDAV_Ftp_Directory(path, ftp);
            baseDir.isRoot = true;
            return next(null, ftp.$cache[path] = baseDir);
        }

        var baseName = Path.basename(path).replace("/", "");
        ftp.ls(Path.dirname(path), function(err, res) {
            if (err) {
                if (res.code === 530) // Not logged in
                    ftp.auth(self.options.user, self.options.pass, function(err, res) {
                        if (!err)
                            self.getNodeForPath(path, next);
                        else
                            console.log(err);
                    });
                else
                    return next(new Exc.jsDAV_Exception_FileNotFound(err));
            }
            else {
                var file;
                for (var i = 0; i < res.length; i++) {
                    var stat = res[i];

                    if (stat.name === baseName) {
                        file = stat;
                        break;
                    }
                }

                if (file) {
                    if (file.type === 1) // Is it a directory?
                        ftp.$cache[path] = new jsDAV_Ftp_Directory(path, ftp);
                    else if (file.type === 0)
                        ftp.$cache[path] = new jsDAV_Ftp_File(path, ftp);

                    if (ftp.$cache[path]) {
                        ftp.$cache[path].$stat = file;
                        next(null, ftp.$cache[path]);
                    }
                    else {
                        next(new Error("Unrecognized type of file: " + path));
                    }

                }
                else {
                    next(new Exc.jsDAV_Exception_FileNotFound(err));
                }
            }
        });
    };

    /**
     * Returns the real filesystem path for a webdav url.
     *
     * @param {String} publicPath
     * @return {String}
     */
    this.getRealPath = function(path) {
        return Path.normalize(Path.join(this.basePath, path));
    };

    /**
     * Copies a file or directory.
     *
     * This method must work recursively and delete the destination
     * if it exists
     *
     * @param string source
     * @param string destination
     * @return void
     */
    this.copy = function(source, destination, next) {
        next(new Exc.jsDAV_Exception_NotImplemented(
            "Could not copy from " + source + " to " + destination + ". " +
            + "COPY/DUPLICATE not implemented.")
        );
    };

    /**
     * Moves a file or directory recursively.
     * In case the ide crashed, the nodes cache was cleared and the source's parent will have to be pre-cached
     * and so will have its children using $getParentNodeRecall(), this way we will be able to come back to this method
     * to rename the source effectively.
     * Once the MOVE has been executed, the node need's to be updated in the cache, and if it's a Directory type its
     * children will have to be updated in the cache as well, so the new keys correspond to the new path.
     *
     * If the destination exists, delete it first.
     *
     * @param string source
     * @param string destination
     * @return void
     */
    this.move = function(source, destination, next) {
        var node = this.ftp.$cache[source];
        var self = this;
        var ftp = this.ftp;

        if (!node) // This should only happen if the server crashed.
            return this.$getParentNodeRecall(source);

        node.setName(destination, function(err) {
            if (err)
                return next(err);

            ftp.$cache[destination] = node;
            delete ftp.$cache[source];
            if (node.hasFeature(jsDAV.__ICOLLECTION__))
                repathChildren(source, destination);

            next();
        });

        function repathChildren(oldParentPath, newParentPath) {
            var paths = Object.keys(ftp.$cache);
            var re = new RegExp("^" + oldParentPath.replace(/\//g, "\\/") + ".+$");

            paths.forEach(function(path) {
                if (ftp.$cache[path] && re.test(path)) {
                    var newPath = newParentPath + path.substring(oldParentPath.length);
                    if (!ftp.$cache[newPath])
                        ftp.$cache[newPath] = ftp.$cache[path];
                    else
                        // Not sure why the line below is useful for
                        ftp.$cache[newPath] && (ftp.$cache[newPath].path = newPath);

                    delete ftp.$cache[path];
                }
            });
        }
    };

    /**
     * Caches a path's parent path and its children, then goes back to the caller function with the
     * same previous arguments.
     *
     * @param string path
     * @return void
     */
    this.$getParentNodeRecall = function(path) {
        var caller = arguments.callee.caller;
        var callerArgs = caller.arguments;
        var next = callback = callerArgs[callerArgs.length-1];
        var parentPath = Util.splitPath(path)[0];
        var _self = this;

        this.getNodeForPath(parentPath.substring(this.basePath.length), function(err, node) {
            if (err)
                return next(err);

            node.getChildren(function(err, nodes) {
                if (err)
                    return next(err);

                if (nodes.length && typeof caller === 'function') {
                    nodes.forEach(function(child) {
                        if (child.path === path)
                            callback = caller.bind.apply(caller, [_self].concat([].slice.call(callerArgs)));
                    });
                    callback();
                } else {
                    next();
                }
            });
        });
    };

    this.unmount = function() {
        console.log("\r\nClosed connection to the server. Unmounting FTP tree.");
        this.ftp.destroy();
    };

}).call(jsDAV_Tree_Ftp.prototype = new jsDAV_Tree());

<commit_msg>[BACKLOG-1693] FTP directory listing and file opening doesn't work for some users<commit_after>/*
 * @package jsDAV
 * @subpackage DAV
 * @copyright Copyright(c) 2011 Ajax.org B.V. <info AT ajax DOT org>
 * @author Sergi Mansilla <sergi AT ajax DOT org>
 * @license http://github.com/mikedeboer/jsDAV/blob/master/LICENSE MIT License
 */

var jsDAV               = require("../../jsdav");
var jsDAV_Tree          = require("../tree").jsDAV_Tree;
var jsDAV_Ftp_Directory = require("../ftp/directory").jsDAV_Ftp_Directory;
var jsDAV_Ftp_File      = require("../ftp/file").jsDAV_Ftp_File;

var Ftp                 = require("../../../support/jsftp/jsftp");
var Util                = require("../util");
var Exc                 = require("../exceptions");
var Path                = require('path');

var PWD_RE = /.*"(.*)".*/;

/**
 * jsDAV_Tree_Ftp
 *
 * Creates the FTP tree.
 *
 * @param {Object} options
 * @contructor
 */

Ftp.debugMode = require("../../jsdav").debugMode;

function jsDAV_Tree_Ftp(options) {
    this.options  = options.ftp;
    this.basePath = this.options.path || ".";
    this.setup();
}

exports.jsDAV_Tree_Ftp = jsDAV_Tree_Ftp;

(function() {

    this.setup = function() {
        this.ftp = new Ftp(this.options);
        this.ftp.$cache = {};
    };

    /**
     * Returns a new node for the given path
     *
     * @param {String} path
     * @return void
     */
    this.getNodeForPath = function(path, next) {
        var ftp = this.ftp;
        var self = this;

        if (path == "" || path == " " || path == "/")
            path = this.basePath;

        if (ftp.$cache[path])
            return next(null, ftp.$cache[path]);

        // Root node requires special treatment because it will not be listed
        if (path === this.basePath) {
            var baseDir = new jsDAV_Ftp_Directory(path, ftp);
            baseDir.isRoot = true;
            return next(null, ftp.$cache[path] = baseDir);
        }

        var baseName = Path.basename(path).replace("/", "");
        ftp.ls(Path.dirname(path), function(err, res) {
            if (err) {
                if (res.code === 530) // Not logged in
                    ftp.auth(self.options.user, self.options.pass, function(err, res) {
                        if (!err)
                            self.getNodeForPath(path, next);
                        else
                            console.log(err);
                    });
                else
                    return next(new Exc.jsDAV_Exception_FileNotFound(err));
            }
            else {
                var file;
                for (var i = 0; i < res.length; i++) {
                    var stat = res[i];

                    if (stat.name === baseName) {
                        file = stat;
                        break;
                    }
                }

                if (file) {
                    if (file.type === 1) // Is it a directory?
                        ftp.$cache[path] = new jsDAV_Ftp_Directory(path, ftp);
                    else if (file.type === 0)
                        ftp.$cache[path] = new jsDAV_Ftp_File(path, ftp);

                    if (ftp.$cache[path]) {
                        ftp.$cache[path].$stat = file;
                        next(null, ftp.$cache[path]);
                    }
                    else {
                        next(new Error("Unrecognized type of file: " + path));
                    }

                }
                else {
                    next(new Exc.jsDAV_Exception_FileNotFound(err));
                }
            }
        });
    };

    /**
     * Returns the real filesystem path for a webdav url.
     *
     * @param {String} publicPath
     * @return {String}
     */
    this.getRealPath = function(path) {
        return Path.normalize(Path.join(this.basePath, path));
    };

    /**
     * Copies a file or directory.
     *
     * This method must work recursively and delete the destination
     * if it exists
     *
     * @param string source
     * @param string destination
     * @return void
     */
    this.copy = function(source, destination, next) {
        next(new Exc.jsDAV_Exception_NotImplemented(
            "Could not copy from " + source + " to " + destination + ". " +
            + "COPY/DUPLICATE not implemented.")
        );
    };

    /**
     * Moves a file or directory recursively.
     * In case the ide crashed, the nodes cache was cleared and the source's parent will have to be pre-cached
     * and so will have its children using $getParentNodeRecall(), this way we will be able to come back to this method
     * to rename the source effectively.
     * Once the MOVE has been executed, the node need's to be updated in the cache, and if it's a Directory type its
     * children will have to be updated in the cache as well, so the new keys correspond to the new path.
     *
     * If the destination exists, delete it first.
     *
     * @param string source
     * @param string destination
     * @return void
     */
    this.move = function(source, destination, next) {
        var node = this.ftp.$cache[source];
        var self = this;
        var ftp = this.ftp;

        if (!node) // This should only happen if the server crashed.
            return this.$getParentNodeRecall(source);

        node.setName(destination, function(err) {
            if (err)
                return next(err);

            ftp.$cache[destination] = node;
            delete ftp.$cache[source];
            if (node.hasFeature(jsDAV.__ICOLLECTION__))
                repathChildren(source, destination);

            next();
        });

        function repathChildren(oldParentPath, newParentPath) {
            var paths = Object.keys(ftp.$cache);
            var re = new RegExp("^" + oldParentPath.replace(/\//g, "\\/") + ".+$");

            paths.forEach(function(path) {
                if (ftp.$cache[path] && re.test(path)) {
                    var newPath = newParentPath + path.substring(oldParentPath.length);
                    if (!ftp.$cache[newPath])
                        ftp.$cache[newPath] = ftp.$cache[path];
                    else
                        // Not sure why the line below is useful for
                        ftp.$cache[newPath] && (ftp.$cache[newPath].path = newPath);

                    delete ftp.$cache[path];
                }
            });
        }
    };

    /**
     * Caches a path's parent path and its children, then goes back to the caller function with the
     * same previous arguments.
     *
     * @param string path
     * @return void
     */
    this.$getParentNodeRecall = function(path) {
        var caller = arguments.callee.caller;
        var callerArgs = caller.arguments;
        var next = callback = callerArgs[callerArgs.length-1];
        var parentPath = Util.splitPath(path)[0];
        var _self = this;

        this.getNodeForPath(parentPath.substring(this.basePath.length), function(err, node) {
            if (err)
                return next(err);

            node.getChildren(function(err, nodes) {
                if (err)
                    return next(err);

                if (nodes.length && typeof caller === 'function') {
                    nodes.forEach(function(child) {
                        if (child.path === path)
                            callback = caller.bind.apply(caller, [_self].concat([].slice.call(callerArgs)));
                    });
                    callback();
                } else {
                    next();
                }
            });
        });
    };

    this.unmount = function() {
        console.log("\r\nClosed connection to the server. Unmounting FTP tree.");
        this.ftp.destroy();
    };

}).call(jsDAV_Tree_Ftp.prototype = new jsDAV_Tree());

<|endoftext|>