<commit_before>var width = 500,
    height = 500,
    radius = Math.min(width, height) / 2,
    innerRadius = 0.3 * radius;

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.width; });

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([0, 0])
  .html(function(d) {
    return d.data.label + ": " + d.data.score + "";
  });

var arc = d3.svg.arc()
  .innerRadius(innerRadius)
  .outerRadius(function (d) {
    return (radius - innerRadius) * (d.data.score / 100.0) + innerRadius;
  });

var outlineArc = d3.svg.arc()
        .innerRadius(innerRadius)
        .outerRadius(radius);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.call(tip);

d3.csv('aster_data.csv', function(error, data) {

  data.forEach(function(d) {
    d.id     =  d.id;
    d.order  = +d.order;
    d.color  =  d.color;
    d.weight = +d.weight;
    d.score  = +d.score;
    d.width  = +d.weight;
    d.label  =  d.label;
  });
  // for (var i = 0; i < data.score; i++) { console.log(data[i].id) }

  var path = svg.selectAll(".solidArc")
      .data(pie(data))
    .enter().append("path")
      .attr("fill", function(d) { return d.data.color; })
      .attr("class", "solidArc")
      .attr("stroke", "gray")
      .attr("d", arc)
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide);

  var outerPath = svg.selectAll(".outlineArc")
      .data(pie(data))
    .enter().append("path")
      .attr("fill", "none")
      .attr("stroke", "gray")
      .attr("class", "outlineArc")
      .attr("d", outlineArc);

  // calculate the weighted mean score
  var score =
    data.reduce(function(a, b) {
      //console.log('a:' + a + ', b.score: ' + b.score + ', b.weight: ' + b.weight);
      return a + (b.score * b.weight);
    }, 0) /
    data.reduce(function(a, b) {
      return a + b.weight;
    }, 0);

  svg.append("svg:text")
    .attr("class", "aster-score")
    .attr("dy", ".35em")
    .attr("text-anchor", "middle") // text-align: right
    .text(Math.round(score));

});<commit_msg>Delete draw.js<commit_after><|endoftext|>


<commit_before>/*
 * navelgazer
 * https://github.com/shama/navelgazer
 *
 * Copyright (c) 2014 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

var EE = require('events').EventEmitter;
var fs = require('graceful-fs');
var inherits = require('util').inherits;
var statpoll = require('./statpoll.js');
var nextback = require('nextback');

// on purpose globals
var renameWaiting = null;
var renameWaitingFile = null;

var path = require('path');
var v8 = 'v8-' + /[0-9]+\.[0-9]+/.exec(process.versions.v8)[0];
var pathwatcherPath = path.join(__dirname, '..', 'bin', process.platform + '-' + process.arch + '-' + v8, 'pathwatcher.node');

var binding = require(pathwatcherPath);
var handleWatchers = new binding.HandleMap;
binding.setCallback(function(event, handle, filePath, oldFilePath) {
  if (handleWatchers.has(handle)) {
    return handleWatchers.get(handle).onEvent(event, filePath, oldFilePath);
  }
});

function HandleWatcher(p) {
  EE.call(this);
  this.setMaxListeners(0);
  this.path = p;
  this.start();
}
inherits(HandleWatcher, EE);

HandleWatcher.prototype.onEvent = function(event, filePath, oldFilePath) {
  var self = this;
  switch (event) {
    case 'rename':
      this.close();
      return setTimeout(function() {
        return fs.stat(self.path, function(err) {
          if (err) {
            self.path = filePath;
            self.start();
            return self.emit('change', 'rename', filePath);
          } else {
            self.start();
            return self.emit('change', 'change', null);
          }
        });
      }, 100);
    case 'delete':
      this.emit('change', 'delete', null);
      return this.close();
    case 'unknown':
      throw new Error('Received unknown event for path: ' + this.path);
      break;
    default:
      return this.emit('change', event, filePath, oldFilePath);
  }
};

HandleWatcher.prototype.start = function() {
  this.handle = binding.watch(this.path);
  if (handleWatchers.has(this.handle)) {
    handleWatchers.get(this.handle).close();
  }
  return handleWatchers.add(this.handle, this);
};

HandleWatcher.prototype.closeIfNoListener = function() {
  if (this.listeners('change').length === 0) {
    return this.close();
  }
};

HandleWatcher.prototype.close = function() {
  if (handleWatchers.has(this.handle)) {
    binding.unwatch(this.handle);
    return handleWatchers.remove(this.handle);
  }
};

PathWatcher.prototype.isWatchingParent = false;

PathWatcher.prototype.path = null;

PathWatcher.prototype.handleWatcher = null;

function PathWatcher(filePath, callback) {
  EE.call(this);
  this.setMaxListeners(0);
  var self = this;
  this.path = filePath;
  if (process.platform === 'win32') {
    var stats = fs.statSync(filePath);
    this.isWatchingParent = !stats.isDirectory();
  }
  if (this.isWatchingParent) {
    filePath = path.dirname(filePath);
  }
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    var watcher = values[i];
    if (watcher.path === filePath) {
      this.handleWatcher = watcher;
      break;
    }
  }
  if (this.handleWatcher == null) {
    this.handleWatcher = new HandleWatcher(filePath);
  }
  this.onChange = function(event, newFilePath, oldFilePath) {
    switch (event) {
      case 'rename':
      case 'change':
      case 'delete':
        if (event === 'rename') {
          self.path = newFilePath;
        }
        if (typeof callback === 'function') {
          callback.call(self, event, newFilePath);
        }
        return self.emit('change', event, newFilePath);
      case 'child-rename':
        if (self.isWatchingParent) {
          if (self.path === oldFilePath) {
            return self.onChange('rename', newFilePath);
          }
        } else {
          return self.onChange('change', '');
        }
        break;
      case 'child-delete':
        if (self.isWatchingParent) {
          if (self.path === newFilePath) {
            return self.onChange('delete', null);
          }
        } else {
          return self.onChange('change', '');
        }
        break;
      case 'child-change':
        if (self.isWatchingParent && self.path === newFilePath) {
          return self.onChange('change', '');
        }
        break;
      case 'child-create':
        if (!self.isWatchingParent) {
          return self.onChange('change', '');
        }
    }
  };
  this.handleWatcher.on('change', this.onChange);
}
inherits(PathWatcher, EE);

PathWatcher.prototype.close = function() {
  this.handleWatcher.removeListener('change', this.onChange);
  return this.handleWatcher.closeIfNoListener();
};

var platform = module.exports = function(file, cb, done) {
  // Ignore non-existent files
  if (!fs.existsSync(file)) return;

  // Mark every folder
  file = markDir(file);

  // Also watch all folders, needed to catch change for detecting added files
  if (!isDir(file)) {
    //platform(path.dirname(file), cb, done);
  }

  // Helper for when to use statpoll
  function useStatPoll() {
    return statpoll(file, function(event) {
      var filepath = file;
      if (process.platform === 'linux') {
        var go = linuxWorkarounds(event, filepath, cb);
        if (go === false) { return; }
      }
      cb(null, event, filepath);
    });
  }

  // By default try using native OS watchers
  if (platform.mode === 'auto' || platform.mode === 'watch') {
    // Delay adding files to watch
    // Fixes the duplicate handle race condition when renaming files
    // ie: (The handle(26) returned by watching [filename] is the same with an already watched path([filename]))
    setTimeout(function() {
      if (!fs.existsSync(file)) {
        return;
      }
      // Workaround for lack of rename support on linux
      if (process.platform === 'linux' && renameWaiting) {
        clearTimeout(renameWaiting);
        cb(null, 'rename', renameWaitingFile, file);
        renameWaiting = renameWaitingFile = null;
        return;
      }
      try {
        return done(new PathWatcher(path.resolve(file), function(event, newFile) {
          var filepath = file;
          console.log('hit', event, filepath)
          if (process.platform === 'linux') {
            var go = linuxWorkarounds(event, filepath, cb);
            if (go === false) { return; }
          }
          cb(null, event, filepath, newFile);
        }));
      } catch (error) {
        // If we hit EMFILE, use stat poll
        if (error.message.slice(0, 6) === 'EMFILE') { error.code = 'EMFILE'; }
        if (error.code === 'EMFILE') {
          // Only fallback to stat poll if not forced in watch mode
          if (platform.mode !== 'watch') {
            return done(useStatPoll());
          }
          // Format the error message for EMFILE a bit better
          error.message = 'Too many open files.\nUnable to watch "' + file + '"\nusing native OS events so falling back to slower stat polling.\n';
        }
        cb(error);
      }
    }, 10);
  } else {
    return done(useStatPoll());
  }
};

platform.mode = 'auto';

platform.closeAll = function() {
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    values[i].close();
  }
  statpoll.closeAll();
  return handleWatchers.clear();
};

// Close up a single watcher
platform.close = function(filepath, cb) {
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    if (values[i].path === filepath) {
      values[i].close();
      break;
    }
  }
  statpoll.close(filepath);
  if (typeof cb === 'function') {
    cb(null);
  }
};

platform.getWatchedPaths = function() {
  var paths = [];
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    paths.push(markDir(values[i].path));
  }
  return paths.concat(statpoll.getWatchedPaths());
};

// Run the stat poller
// NOTE: Run at minimum of 500ms to adequately capture change event
// to folders when adding files
platform.tick = statpoll.tick.bind(statpoll);

// Mark folders if not marked
function markDir(file) {
  if (file.slice(-1) !== path.sep) {
    if (fs.lstatSync(file).isDirectory()) {
      file += path.sep;
    }
  }
  return file;
}

// Workarounds for lack of rename support on linux and folders emit before files
// https://github.com/atom/node-pathwatcher/commit/004a202dea89f4303cdef33912902ed5caf67b23
var linuxQueue = Object.create(null);
var linuxQueueInterval = null;
function linuxProcessQueue(cb) {
  var len = Object.keys(linuxQueue).length;
  if (len === 1) {
    var key = Object.keys(linuxQueue).slice(0, 1)[0];
    cb(null, key, linuxQueue[key]);
  } else if (len > 1) {
    // If change and delete events fired simultaneously, use delete
    if (linuxQueue['delete'] && linuxQueue['change']) {
      console.log('HIT WORKAROUND', linuxQueue)
      cb(null, 'delete', linuxQueue['delete']);
    }
  }
  linuxQueue = Object.create(null);
}
function linuxWorkarounds(event, filepath, cb) {
  linuxQueue[event] = filepath;
  clearTimeout(linuxQueueInterval);
  linuxQueueInterval = setTimeout(function() {
    linuxProcessQueue(cb);
  }, 100);
  return false;
}

// Returns boolean whether filepath is dir terminated
function isDir(dir) {
  if (typeof dir !== 'string') { return false; }
  return (dir.slice(-(path.sep.length)) === path.sep) || (dir.slice(-1) === '/');
};
<commit_msg>Maybe it needs more time on travis?<commit_after>/*
 * navelgazer
 * https://github.com/shama/navelgazer
 *
 * Copyright (c) 2014 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

var EE = require('events').EventEmitter;
var fs = require('graceful-fs');
var inherits = require('util').inherits;
var statpoll = require('./statpoll.js');
var nextback = require('nextback');

// on purpose globals
var renameWaiting = null;
var renameWaitingFile = null;

var path = require('path');
var v8 = 'v8-' + /[0-9]+\.[0-9]+/.exec(process.versions.v8)[0];
var pathwatcherPath = path.join(__dirname, '..', 'bin', process.platform + '-' + process.arch + '-' + v8, 'pathwatcher.node');

var binding = require(pathwatcherPath);
var handleWatchers = new binding.HandleMap;
binding.setCallback(function(event, handle, filePath, oldFilePath) {
  if (handleWatchers.has(handle)) {
    return handleWatchers.get(handle).onEvent(event, filePath, oldFilePath);
  }
});

function HandleWatcher(p) {
  EE.call(this);
  this.setMaxListeners(0);
  this.path = p;
  this.start();
}
inherits(HandleWatcher, EE);

HandleWatcher.prototype.onEvent = function(event, filePath, oldFilePath) {
  var self = this;
  switch (event) {
    case 'rename':
      this.close();
      return setTimeout(function() {
        return fs.stat(self.path, function(err) {
          if (err) {
            self.path = filePath;
            self.start();
            return self.emit('change', 'rename', filePath);
          } else {
            self.start();
            return self.emit('change', 'change', null);
          }
        });
      }, 100);
    case 'delete':
      this.emit('change', 'delete', null);
      return this.close();
    case 'unknown':
      throw new Error('Received unknown event for path: ' + this.path);
      break;
    default:
      return this.emit('change', event, filePath, oldFilePath);
  }
};

HandleWatcher.prototype.start = function() {
  this.handle = binding.watch(this.path);
  if (handleWatchers.has(this.handle)) {
    handleWatchers.get(this.handle).close();
  }
  return handleWatchers.add(this.handle, this);
};

HandleWatcher.prototype.closeIfNoListener = function() {
  if (this.listeners('change').length === 0) {
    return this.close();
  }
};

HandleWatcher.prototype.close = function() {
  if (handleWatchers.has(this.handle)) {
    binding.unwatch(this.handle);
    return handleWatchers.remove(this.handle);
  }
};

PathWatcher.prototype.isWatchingParent = false;

PathWatcher.prototype.path = null;

PathWatcher.prototype.handleWatcher = null;

function PathWatcher(filePath, callback) {
  EE.call(this);
  this.setMaxListeners(0);
  var self = this;
  this.path = filePath;
  if (process.platform === 'win32') {
    var stats = fs.statSync(filePath);
    this.isWatchingParent = !stats.isDirectory();
  }
  if (this.isWatchingParent) {
    filePath = path.dirname(filePath);
  }
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    var watcher = values[i];
    if (watcher.path === filePath) {
      this.handleWatcher = watcher;
      break;
    }
  }
  if (this.handleWatcher == null) {
    this.handleWatcher = new HandleWatcher(filePath);
  }
  this.onChange = function(event, newFilePath, oldFilePath) {
    switch (event) {
      case 'rename':
      case 'change':
      case 'delete':
        if (event === 'rename') {
          self.path = newFilePath;
        }
        if (typeof callback === 'function') {
          callback.call(self, event, newFilePath);
        }
        return self.emit('change', event, newFilePath);
      case 'child-rename':
        if (self.isWatchingParent) {
          if (self.path === oldFilePath) {
            return self.onChange('rename', newFilePath);
          }
        } else {
          return self.onChange('change', '');
        }
        break;
      case 'child-delete':
        if (self.isWatchingParent) {
          if (self.path === newFilePath) {
            return self.onChange('delete', null);
          }
        } else {
          return self.onChange('change', '');
        }
        break;
      case 'child-change':
        if (self.isWatchingParent && self.path === newFilePath) {
          return self.onChange('change', '');
        }
        break;
      case 'child-create':
        if (!self.isWatchingParent) {
          return self.onChange('change', '');
        }
    }
  };
  this.handleWatcher.on('change', this.onChange);
}
inherits(PathWatcher, EE);

PathWatcher.prototype.close = function() {
  this.handleWatcher.removeListener('change', this.onChange);
  return this.handleWatcher.closeIfNoListener();
};

var platform = module.exports = function(file, cb, done) {
  // Ignore non-existent files
  if (!fs.existsSync(file)) return;

  // Mark every folder
  file = markDir(file);

  // Also watch all folders, needed to catch change for detecting added files
  if (!isDir(file)) {
    //platform(path.dirname(file), cb, done);
  }

  // Helper for when to use statpoll
  function useStatPoll() {
    return statpoll(file, function(event) {
      var filepath = file;
      if (process.platform === 'linux') {
        var go = linuxWorkarounds(event, filepath, cb);
        if (go === false) { return; }
      }
      cb(null, event, filepath);
    });
  }

  // By default try using native OS watchers
  if (platform.mode === 'auto' || platform.mode === 'watch') {
    // Delay adding files to watch
    // Fixes the duplicate handle race condition when renaming files
    // ie: (The handle(26) returned by watching [filename] is the same with an already watched path([filename]))
    setTimeout(function() {
      if (!fs.existsSync(file)) {
        return;
      }
      // Workaround for lack of rename support on linux
      if (process.platform === 'linux' && renameWaiting) {
        clearTimeout(renameWaiting);
        cb(null, 'rename', renameWaitingFile, file);
        renameWaiting = renameWaitingFile = null;
        return;
      }
      try {
        return done(new PathWatcher(path.resolve(file), function(event, newFile) {
          var filepath = file;
          console.log('hit', event, filepath)
          if (process.platform === 'linux') {
            var go = linuxWorkarounds(event, filepath, cb);
            if (go === false) { return; }
          }
          cb(null, event, filepath, newFile);
        }));
      } catch (error) {
        // If we hit EMFILE, use stat poll
        if (error.message.slice(0, 6) === 'EMFILE') { error.code = 'EMFILE'; }
        if (error.code === 'EMFILE') {
          // Only fallback to stat poll if not forced in watch mode
          if (platform.mode !== 'watch') {
            return done(useStatPoll());
          }
          // Format the error message for EMFILE a bit better
          error.message = 'Too many open files.\nUnable to watch "' + file + '"\nusing native OS events so falling back to slower stat polling.\n';
        }
        cb(error);
      }
    }, 10);
  } else {
    return done(useStatPoll());
  }
};

platform.mode = 'auto';

platform.closeAll = function() {
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    values[i].close();
  }
  statpoll.closeAll();
  return handleWatchers.clear();
};

// Close up a single watcher
platform.close = function(filepath, cb) {
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    if (values[i].path === filepath) {
      values[i].close();
      break;
    }
  }
  statpoll.close(filepath);
  if (typeof cb === 'function') {
    cb(null);
  }
};

platform.getWatchedPaths = function() {
  var paths = [];
  var values = handleWatchers.values();
  for (var i = 0; i < values.length; i++) {
    paths.push(markDir(values[i].path));
  }
  return paths.concat(statpoll.getWatchedPaths());
};

// Run the stat poller
// NOTE: Run at minimum of 500ms to adequately capture change event
// to folders when adding files
platform.tick = statpoll.tick.bind(statpoll);

// Mark folders if not marked
function markDir(file) {
  if (file.slice(-1) !== path.sep) {
    if (fs.lstatSync(file).isDirectory()) {
      file += path.sep;
    }
  }
  return file;
}

// Workarounds for lack of rename support on linux and folders emit before files
// https://github.com/atom/node-pathwatcher/commit/004a202dea89f4303cdef33912902ed5caf67b23
var linuxQueue = Object.create(null);
var linuxQueueInterval = null;
function linuxProcessQueue(cb) {
  var len = Object.keys(linuxQueue).length;
  if (len === 1) {
    var key = Object.keys(linuxQueue).slice(0, 1)[0];
    cb(null, key, linuxQueue[key]);
  } else if (len > 1) {
    // If change and delete events fired simultaneously, use delete
    if (linuxQueue['delete'] && linuxQueue['change']) {
      console.log('HIT WORKAROUND', linuxQueue)
      cb(null, 'delete', linuxQueue['delete']);
    }
  }
  linuxQueue = Object.create(null);
}
function linuxWorkarounds(event, filepath, cb) {
  linuxQueue[event] = filepath;
  clearTimeout(linuxQueueInterval);
  linuxQueueInterval = setTimeout(function() {
    linuxProcessQueue(cb);
  }, 500);
  return false;
}

// Returns boolean whether filepath is dir terminated
function isDir(dir) {
  if (typeof dir !== 'string') { return false; }
  return (dir.slice(-(path.sep.length)) === path.sep) || (dir.slice(-1) === '/');
};
<|endoftext|>


<commit_before>/** HTTP-based NTP implementation for Node.js and AJAX clients */
"use strict";

var util = require('util');

/** Build event handler for debuging */
function debug_event_handler(name) {
	return function() {
		var args = Array.prototype.slice.call(arguments);
		var now = (new Date()).getTime();
		util.debug( '[' + now + '] ' + name + ' (' + args.map(function(a) { return util.inspect(a); }).join(', ') + ')' );
	};
}

/* Get time in milliseconds */
function get_time() {
	return (new Date()).getTime();
}

/* Module builder */
function _request_creator(mod_opts) {
	mod_opts = mod_opts || {};
	//var _http = mod_opts.http || require('http');

	var _path = mod_opts.path || '';
	var _id = 0;
	var _cache = {};

	/** */
	function _cache_has_id(id) {
		return Object.prototype.hasOwnProperty.call(_cache, id) ? true : false;
	}

	/** */
	function _cache_cleanup(id) {
		if(_cache_has_id(id)) {
			delete _cache[id];
		}
	}

	/** HTTP request runner */
	function request_handler(req, res) {
		var server_start_time = get_time();
		var cache, params, id;

		params = require('url').parse(req.url, true).query;

		if(req.url === _path + '/time') {
			_id = Math.floor(Math.random()*100000000000000000);
			cache = {'id':_id, 'start': server_start_time, 'end':undefined};
			_cache[_id] = cache;

			req.on('close', _cache_cleanup.bind(undefined, _id) );

			req.on('end', function() {
				cache.status = true;
				cache.end = get_time();
			});

			setTimeout(_cache_cleanup.bind(undefined, _id), 1000*30);

			res.writeHead(200, {'Content-Type': 'application/json'});
			res.end(JSON.stringify(_id));
		} else if(req.url.substr(0, _path.length + 6) === _path + '/fetch') {
			id = parseInt(params.id, 10);
			if(_cache_has_id(id)) {
				res.writeHead(200, {'Content-Type': 'application/json'});

				res.end(JSON.stringify(_cache[id]));
				_cache_cleanup(id);
			} else {
				res.writeHead(404, {'Content-Type': 'application/json'});
				res.end(JSON.stringify("404 - Not Found"));
			}
		} else {
			res.writeHead(404, {'Content-Type': 'application/json'});
			res.end(JSON.stringify("404 - Not Found"));
		}
	}

	/** Create instance of NTP HTTP Server */
	/*
	function Server(opts) {
		opts = opts || {};
		this._server = http.createServer(request_handler);
		var port = opts.listen || opts.port;
		if(port) {
			this._server.listen(port);
		}
	}
	*/

	/** Returns the internal value of HTTP server */
	/*
	Server.prototype.server = function() {
		return this._server;
	};
	*/

	/** Start listening */
	/*
	Server.prototype.listen = function(host, port) {
		if(port === undefined) {
			port = host;
			host = undefined;
		}
		if(host === undefined) {
			this._server.listen(port);
		} else {
			this._server.listen(host, port);
		}
		return this;
	};
	*/

	/** Creates HTTP-based NTP server */
	/*
	Server.create = function(opts) {
		return new Server(opts);
	};
	*/

	/* Alias for `Server.create` */
	//Server.createServer = Server.create;

	return request_handler;
}

// Exports
module.exports = _request_creator;

/* EOF */
<commit_msg>Fixed url parsing<commit_after>/** HTTP-based NTP implementation for Node.js and AJAX clients */
"use strict";

var util = require('util');

/** Build event handler for debuging */
function debug_event_handler(name) {
	return function() {
		var args = Array.prototype.slice.call(arguments);
		var now = (new Date()).getTime();
		util.debug( '[' + now + '] ' + name + ' (' + args.map(function(a) { return util.inspect(a); }).join(', ') + ')' );
	};
}

/* Get time in milliseconds */
function get_time() {
	return (new Date()).getTime();
}

/* Module builder */
function _request_creator(mod_opts) {
	mod_opts = mod_opts || {};
	//var _http = mod_opts.http || require('http');

	var _path = mod_opts.path || '';
	var _id = 0;
	var _cache = {};

	/** */
	function _cache_has_id(id) {
		return Object.prototype.hasOwnProperty.call(_cache, id) ? true : false;
	}

	/** */
	function _cache_cleanup(id) {
		if(_cache_has_id(id)) {
			delete _cache[id];
		}
	}

	/** HTTP request runner */
	function request_handler(req, res) {
		var server_start_time = get_time();
		var cache, url, id;

		url = require('url').parse(req.url, true);

		if(url.pathname === _path + '/time') {
			_id = Math.floor(Math.random()*100000000000000000);
			cache = {'id':_id, 'start': server_start_time, 'end':undefined};
			_cache[_id] = cache;

			req.on('close', _cache_cleanup.bind(undefined, _id) );

			req.on('end', function() {
				cache.status = true;
				cache.end = get_time();
			});

			setTimeout(_cache_cleanup.bind(undefined, _id), 1000*30);

			res.writeHead(200, {'Content-Type': 'application/json'});
			res.end(JSON.stringify(_id));
		} else if(url.pathname.substr(0, _path.length + 6) === _path + '/fetch') {
			id = parseInt(url.query.id, 10);
			if(_cache_has_id(id)) {
				res.writeHead(200, {'Content-Type': 'application/json'});

				res.end(JSON.stringify(_cache[id]));
				_cache_cleanup(id);
			} else {
				res.writeHead(404, {'Content-Type': 'application/json'});
				res.end(JSON.stringify("404 - Not Found"));
			}
		} else {
			res.writeHead(404, {'Content-Type': 'application/json'});
			res.end(JSON.stringify("404 - Not Found"));
		}
	}

	/** Create instance of NTP HTTP Server */
	/*
	function Server(opts) {
		opts = opts || {};
		this._server = http.createServer(request_handler);
		var port = opts.listen || opts.port;
		if(port) {
			this._server.listen(port);
		}
	}
	*/

	/** Returns the internal value of HTTP server */
	/*
	Server.prototype.server = function() {
		return this._server;
	};
	*/

	/** Start listening */
	/*
	Server.prototype.listen = function(host, port) {
		if(port === undefined) {
			port = host;
			host = undefined;
		}
		if(host === undefined) {
			this._server.listen(port);
		} else {
			this._server.listen(host, port);
		}
		return this;
	};
	*/

	/** Creates HTTP-based NTP server */
	/*
	Server.create = function(opts) {
		return new Server(opts);
	};
	*/

	/* Alias for `Server.create` */
	//Server.createServer = Server.create;

	return request_handler;
}

// Exports
module.exports = _request_creator;

/* EOF */
<|endoftext|>


<commit_before>/* @flow */

import { CompositeDisposable } from 'atom'
import { WORKSPACE_URI } from '../helpers'

let React
let ReactDOM
let Component

// eslint-disable-next-line no-use-before-define
function getPaneContainer(item: PanelDock) {
  const paneContainer = atom.workspace.paneContainerForItem(item)
  // NOTE: This is an internal API access
  // It's necessary because there's no Public API for it yet
  if (paneContainer && typeof paneContainer.state === 'object' && typeof paneContainer.state.size === 'number' && typeof paneContainer.render === 'function') {
    return paneContainer
  }
  return null
}

class PanelDock {
  element: HTMLElement;
  subscriptions: CompositeDisposable;
  panelHeight: number;
  alwaysTakeMinimumSpace: boolean;
  lastSetPaneHeight: number | null

  constructor(delegate: Object) {
    this.element = document.createElement('div')
    this.subscriptions = new CompositeDisposable()

    this.lastSetPaneHeight = null
    this.subscriptions.add(atom.config.observe('linter-ui-default.panelHeight', (panelHeight) => {
      const changed = typeof this.panelHeight === 'number'
      this.panelHeight = panelHeight
      if (changed) {
        this.doPanelResize(true)
      }
    }))
    this.subscriptions.add(atom.config.observe('linter-ui-default.alwaysTakeMinimumSpace', (alwaysTakeMinimumSpace) => {
      this.alwaysTakeMinimumSpace = alwaysTakeMinimumSpace
    }))
    this.doPanelResize()

    if (!React) {
      React = require('react')
    }
    if (!ReactDOM) {
      ReactDOM = require('react-dom')
    }
    if (!Component) {
      Component = require('./component')
    }

    ReactDOM.render(<Component delegate={delegate} />, this.element)
  }
  // NOTE: Chose a name that won't conflict with Dock APIs
  doPanelResize(forConfigHeight: boolean = false) {
    const paneContainer = getPaneContainer(this)
    let minimumHeight: number | null = null
    const paneContainerView = atom.views.getView(paneContainer)
    if (paneContainerView && this.alwaysTakeMinimumSpace) {
      // NOTE: Super horrible hack but the only possible way I could find :((
      const dockNamesElement = paneContainerView.querySelector('.list-inline.tab-bar.inset-panel')
      const dockNamesRects = dockNamesElement ? dockNamesElement.getClientRects()[0] : null
      const tableElement = this.element.querySelector('table')
      const panelRects = tableElement ? tableElement.getClientRects()[0] : null
      if (dockNamesRects && panelRects) {
        minimumHeight = dockNamesRects.height + panelRects.height + 1
      }
    }

    if (paneContainer) {
      let updateConfigHeight: number | null = null
      const heightSet = minimumHeight !== null && !forConfigHeight ? Math.min(minimumHeight, this.panelHeight) : this.panelHeight

      // Person resized the panel, save new resized value to config
      if (this.lastSetPaneHeight !== null && paneContainer.state.size !== this.lastSetPaneHeight) {
        updateConfigHeight = paneContainer.state.size
      }

      this.lastSetPaneHeight = heightSet
      paneContainer.state.size = heightSet
      paneContainer.render(paneContainer.state)

      if (updateConfigHeight !== null) {
        atom.config.set('linter-ui-default.panelHeight', updateConfigHeight)
      }
    }
  }
  getURI() {
    return WORKSPACE_URI
  }
  getTitle() {
    return 'Linter'
  }
  getDefaultLocation() {
    return 'bottom'
  }
  getAllowedLocations() {
    return ['center', 'bottom', 'top']
  }
  getPreferredHeight() {
    return atom.config.get('linter-ui-default.panelHeight')
  }
  dispose() {
    this.subscriptions.dispose()
    const paneContainer = getPaneContainer(this)
    if (paneContainer && !this.alwaysTakeMinimumSpace && paneContainer.state.size !== this.panelHeight) {
      atom.config.set('linter-ui-default.panelHeight', paneContainer.state.size)
      paneContainer.paneForItem(this).destroyItem(this, true)
    }
  }
}

module.exports = PanelDock
<commit_msg>:bug: Fix behavior where changing config doesn't work<commit_after>/* @flow */

import { CompositeDisposable } from 'atom'
import { WORKSPACE_URI } from '../helpers'

let React
let ReactDOM
let Component

// eslint-disable-next-line no-use-before-define
function getPaneContainer(item: PanelDock) {
  const paneContainer = atom.workspace.paneContainerForItem(item)
  // NOTE: This is an internal API access
  // It's necessary because there's no Public API for it yet
  if (paneContainer && typeof paneContainer.state === 'object' && typeof paneContainer.state.size === 'number' && typeof paneContainer.render === 'function') {
    return paneContainer
  }
  return null
}

class PanelDock {
  element: HTMLElement;
  subscriptions: CompositeDisposable;
  panelHeight: number;
  alwaysTakeMinimumSpace: boolean;
  lastSetPaneHeight: number | null

  constructor(delegate: Object) {
    this.element = document.createElement('div')
    this.subscriptions = new CompositeDisposable()

    this.lastSetPaneHeight = null
    this.subscriptions.add(atom.config.observe('linter-ui-default.panelHeight', (panelHeight) => {
      const changed = typeof this.panelHeight === 'number'
      this.panelHeight = panelHeight
      if (changed) {
        this.doPanelResize(true)
      }
    }))
    this.subscriptions.add(atom.config.observe('linter-ui-default.alwaysTakeMinimumSpace', (alwaysTakeMinimumSpace) => {
      this.alwaysTakeMinimumSpace = alwaysTakeMinimumSpace
    }))
    this.doPanelResize()

    if (!React) {
      React = require('react')
    }
    if (!ReactDOM) {
      ReactDOM = require('react-dom')
    }
    if (!Component) {
      Component = require('./component')
    }

    ReactDOM.render(<Component delegate={delegate} />, this.element)
  }
  // NOTE: Chose a name that won't conflict with Dock APIs
  doPanelResize(forConfigHeight: boolean = false) {
    const paneContainer = getPaneContainer(this)
    let minimumHeight: number | null = null
    const paneContainerView = atom.views.getView(paneContainer)
    if (paneContainerView && this.alwaysTakeMinimumSpace) {
      // NOTE: Super horrible hack but the only possible way I could find :((
      const dockNamesElement = paneContainerView.querySelector('.list-inline.tab-bar.inset-panel')
      const dockNamesRects = dockNamesElement ? dockNamesElement.getClientRects()[0] : null
      const tableElement = this.element.querySelector('table')
      const panelRects = tableElement ? tableElement.getClientRects()[0] : null
      if (dockNamesRects && panelRects) {
        minimumHeight = dockNamesRects.height + panelRects.height + 1
      }
    }

    if (paneContainer) {
      let updateConfigHeight: number | null = null
      const heightSet = minimumHeight !== null && !forConfigHeight ? Math.min(minimumHeight, this.panelHeight) : this.panelHeight

      // Person resized the panel, save new resized value to config
      if (this.lastSetPaneHeight !== null && paneContainer.state.size !== this.lastSetPaneHeight && !forConfigHeight) {
        updateConfigHeight = paneContainer.state.size
      }

      this.lastSetPaneHeight = heightSet
      paneContainer.state.size = heightSet
      paneContainer.render(paneContainer.state)

      if (updateConfigHeight !== null) {
        atom.config.set('linter-ui-default.panelHeight', updateConfigHeight)
      }
    }
  }
  getURI() {
    return WORKSPACE_URI
  }
  getTitle() {
    return 'Linter'
  }
  getDefaultLocation() {
    return 'bottom'
  }
  getAllowedLocations() {
    return ['center', 'bottom', 'top']
  }
  getPreferredHeight() {
    return atom.config.get('linter-ui-default.panelHeight')
  }
  dispose() {
    this.subscriptions.dispose()
    const paneContainer = getPaneContainer(this)
    if (paneContainer && !this.alwaysTakeMinimumSpace && paneContainer.state.size !== this.panelHeight) {
      atom.config.set('linter-ui-default.panelHeight', paneContainer.state.size)
      paneContainer.paneForItem(this).destroyItem(this, true)
    }
  }
}

module.exports = PanelDock
<|endoftext|>


<commit_before>/* eslint-disable*/

/**
 * Sample formatting library
 */

/**
 * Format money
 * Source: http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript
 *
 * @param  {[type]} n [description]
 * @param  {[type]} c [description]
 * @param  {[type]} d [description]
 * @param  {[type]} t [description]
 * @return {[type]}   [description]
 */
exports.formatMoney = function(n, c, d, t) {
  var c = isNaN(c = Math.abs(c)) ? 2 : c,
    d = d === undefined ? '.' : d,
    t = t === undefined ? ',' : t,
    s = n < 0 ? '-' : '',
    i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + '',
    j = (j = i.length) > 3 ? j % 3 : 0;
  return s + (j ? i.substr(0, j) + t : '') +
         i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) +
         (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
};

/**
 * Money To Words
 * Source: https://eglador.wordpress.com/2013/02/27/conversion-de-numeros-a-letras-con-javascript/
 * @param  {Int}    num Number
 * @return {String}     Number
 */
exports.moneyToWords = function(num) {

  var unidades = function(num) {

    switch (num) {
      case 1:
        return 'UN';
      case 2:
        return 'DOS';
      case 3:
        return 'TRES';
      case 4:
        return 'CUATRO';
      case 5:
        return 'CINCO';
      case 6:
        return 'SEIS';
      case 7:
        return 'SIETE';
      case 8:
        return 'OCHO';
      case 9:
        return 'NUEVE';
    }

    return '';
  }

  var decenas = function(num) {

    decena = Math.floor(num / 10);
    unidad = num - (decena * 10);

    switch (decena) {
      case 1:
        switch (unidad) {
          case 0:
            return 'DIEZ';
          case 1:
            return 'ONCE';
          case 2:
            return 'DOCE';
          case 3:
            return 'TRECE';
          case 4:
            return 'CATORCE';
          case 5:
            return 'QUINCE';
          default:
            return 'DIECI' + unidades(unidad);
        }
      case 2:
        switch (unidad) {
          case 0:
            return 'VEINTE';
          default:
            return 'VEINTI' + unidades(unidad);
        }
      case 3:
        return decenasY('TREINTA', unidad);
      case 4:
        return decenasY('CUARENTA', unidad);
      case 5:
        return decenasY('CINCUENTA', unidad);
      case 6:
        return decenasY('SESENTA', unidad);
      case 7:
        return decenasY('SETENTA', unidad);
      case 8:
        return decenasY('OCHENTA', unidad);
      case 9:
        return decenasY('NOVENTA', unidad);
      case 0:
        return unidades(unidad);
    }
  }

  var decenasY = function(strSin, numUnidades) {
    if (numUnidades > 0)
      return strSin + ' Y ' + unidades(numUnidades)

    return strSin;
  }

  var centenas = function(num) {

    centenas = Math.floor(num / 100);
    decenas = num - (centenas * 100);

    switch (centenas) {
      case 1:
        if (decenas > 0)
          return 'CIENTO ' + decenas(decenas);
        return 'CIEN';
      case 2:
        return 'DOSCIENTOS ' + decenas(decenas);
      case 3:
        return 'TRESCIENTOS ' + decenas(decenas);
      case 4:
        return 'CUATROCIENTOS ' + decenas(decenas);
      case 5:
        return 'QUINIENTOS ' + decenas(decenas);
      case 6:
        return 'SEISCIENTOS ' + decenas(decenas);
      case 7:
        return 'SETECIENTOS ' + decenas(decenas);
      case 8:
        return 'OCHOCIENTOS ' + decenas(decenas);
      case 9:
        return 'NOVECIENTOS ' + decenas(decenas);
    }

    return decenas(decenas);
  }

  var seccion = function(num, divisor, strSingular, strPlural) {
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    letras = '';

    if (cientos > 0)
      if (cientos > 1)
        letras = centenas(cientos) + ' ' + strPlural;
      else
        letras = strSingular;

    if (resto > 0)
      letras += '';

    return letras;
  }

  var miles = function(num) {
    divisor = 1000;
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    strMiles = seccion(num, divisor, 'UN MIL', 'MIL');
    strCentenas = centenas(resto);

    if (strMiles === '')
      return strCentenas;

    return strMiles + ' ' + strCentenas;

    //return seccion(num, divisor, "UN MIL", "MIL") + " " + centenas(resto);
  }

  var millones = function(num) {
    divisor = 1000000;
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    strMillones = seccion(num, divisor, 'UN MILLON', 'MILLONES');
    strMiles = miles(resto);

    if (strMillones === '')
      return strMiles;

    return strMillones + ' ' + strMiles;

    //return seccion(num, divisor, "UN MILLON", "MILLONES") + " " + miles(resto);
  }

  var data = {
    numero: num,
    enteros: Math.floor(num),
    centavos: (((Math.round(num * 100)) - (Math.floor(num) * 100))),
    letrasCentavos: '',
    letrasMonedaPlural: 'PESOS',
    letrasMonedaSingular: 'PESO',
  };

  if (data.centavos > 0)
    data.letrasCentavos = 'CON ' + data.centavos + '/100';

  if (data.enteros === 0)
    return 'CERO ' + data.letrasMonedaPlural + ' ' + data.letrasCentavos;
  if (data.enteros === 1)
    return millones(data.enteros) + ' ' + data.letrasMonedaSingular + ' ' + data.letrasCentavos;
  else
    return millones(data.enteros) + ' ' + data.letrasMonedaPlural + ' ' + data.letrasCentavos;
}<commit_msg>fix(pateFormat): moneyToWords errors due to ESLint<commit_after>/* eslint-disable*/

/**
 * Sample formatting library
 */

/**
 * Format money
 * Source: http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript
 *
 * @param  {[type]} n [description]
 * @param  {[type]} c [description]
 * @param  {[type]} d [description]
 * @param  {[type]} t [description]
 * @return {[type]}   [description]
 */
exports.formatMoney = function(n, c, d, t) {
  var c = isNaN(c = Math.abs(c)) ? 2 : c,
    d = d === undefined ? '.' : d,
    t = t === undefined ? ',' : t,
    s = n < 0 ? '-' : '',
    i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + '',
    j = (j = i.length) > 3 ? j % 3 : 0;
  return s + (j ? i.substr(0, j) + t : '') +
    i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) +
    (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
};

/**
 * Money To Words
 * Source: https://eglador.wordpress.com/2013/02/27/conversion-de-numeros-a-letras-con-javascript/
 * @param  {Int}    num Number
 * @return {String}     Number
 */
exports.moneyToWords = function(num) {

  function Unidades(num) {

    switch (num) {
      case 1:
        return "UN";
      case 2:
        return "DOS";
      case 3:
        return "TRES";
      case 4:
        return "CUATRO";
      case 5:
        return "CINCO";
      case 6:
        return "SEIS";
      case 7:
        return "SIETE";
      case 8:
        return "OCHO";
      case 9:
        return "NUEVE";
    }

    return "";
  }

  function Decenas(num) {

    decena = Math.floor(num / 10);
    unidad = num - (decena * 10);

    switch (decena) {
      case 1:
        switch (unidad) {
          case 0:
            return "DIEZ";
          case 1:
            return "ONCE";
          case 2:
            return "DOCE";
          case 3:
            return "TRECE";
          case 4:
            return "CATORCE";
          case 5:
            return "QUINCE";
          default:
            return "DIECI" + Unidades(unidad);
        }
      case 2:
        switch (unidad) {
          case 0:
            return "VEINTE";
          default:
            return "VEINTI" + Unidades(unidad);
        }
      case 3:
        return DecenasY("TREINTA", unidad);
      case 4:
        return DecenasY("CUARENTA", unidad);
      case 5:
        return DecenasY("CINCUENTA", unidad);
      case 6:
        return DecenasY("SESENTA", unidad);
      case 7:
        return DecenasY("SETENTA", unidad);
      case 8:
        return DecenasY("OCHENTA", unidad);
      case 9:
        return DecenasY("NOVENTA", unidad);
      case 0:
        return Unidades(unidad);
    }
  } //Unidades()

  function DecenasY(strSin, numUnidades) {
    if (numUnidades > 0)
      return strSin + " Y " + Unidades(numUnidades)

    return strSin;
  } //DecenasY()

  function Centenas(num) {

    centenas = Math.floor(num / 100);
    decenas = num - (centenas * 100);

    switch (centenas) {
      case 1:
        if (decenas > 0)
          return "CIENTO " + Decenas(decenas);
        return "CIEN";
      case 2:
        return "DOSCIENTOS " + Decenas(decenas);
      case 3:
        return "TRESCIENTOS " + Decenas(decenas);
      case 4:
        return "CUATROCIENTOS " + Decenas(decenas);
      case 5:
        return "QUINIENTOS " + Decenas(decenas);
      case 6:
        return "SEISCIENTOS " + Decenas(decenas);
      case 7:
        return "SETECIENTOS " + Decenas(decenas);
      case 8:
        return "OCHOCIENTOS " + Decenas(decenas);
      case 9:
        return "NOVECIENTOS " + Decenas(decenas);
    }

    return Decenas(decenas);
  } //Centenas()

  function Seccion(num, divisor, strSingular, strPlural) {
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    letras = "";

    if (cientos > 0)
      if (cientos > 1)
        letras = Centenas(cientos) + " " + strPlural;
      else
        letras = strSingular;

    if (resto > 0)
      letras += "";

    return letras;
  } //Seccion()

  function Miles(num) {
    divisor = 1000;
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    strMiles = Seccion(num, divisor, "UN MIL", "MIL");
    strCentenas = Centenas(resto);

    if (strMiles == "")
      return strCentenas;

    return strMiles + " " + strCentenas;

    //return Seccion(num, divisor, "UN MIL", "MIL") + " " + Centenas(resto);
  } //Miles()

  function Millones(num) {
    divisor = 1000000;
    cientos = Math.floor(num / divisor)
    resto = num - (cientos * divisor)

    strMillones = Seccion(num, divisor, "UN MILLON", "MILLONES");
    strMiles = Miles(resto);

    if (strMillones == "")
      return strMiles;

    return strMillones + " " + strMiles;

    //return Seccion(num, divisor, "UN MILLON", "MILLONES") + " " + Miles(resto);
  } //Millones()

  var data = {
    numero: num,
    enteros: Math.floor(num),
    centavos: (((Math.round(num * 100)) - (Math.floor(num) * 100))),
    letrasCentavos: "",
    letrasMonedaPlural: "PESOS",
    letrasMonedaSingular: "PESO"
  };

  if (data.centavos > 0)
    data.letrasCentavos = "CON " + data.centavos + "/100";

  if (data.enteros == 0)
    return "CERO " + data.letrasMonedaPlural + " " + data.letrasCentavos;
  if (data.enteros == 1)
    return Millones(data.enteros) + " " + data.letrasMonedaSingular + " " + data.letrasCentavos;
  else
    return Millones(data.enteros) + " " + data.letrasMonedaPlural + " " + data.letrasCentavos;
}<|endoftext|>


<commit_before>var FS, Path, $, Client, TreeView, AddDialog, MoveDialog;

function hasProject () {
	return atom.project && atom.project.getPaths().length;
}

module.exports = {
	configDefaults: {
		hideLocalWhenDisplayed: false
	},

	treeView: null,
	client: null,

	activate: function (state) {
		var self = this;

		if (!FS) {
			FS = require('fs-plus');
			Path = require('path');
			$ = require('atom').$;

			Client = require('./client');
			TreeView = require('./views/tree-view');
			Directory = require('./directory');
		}

		atom.project.remoteftp = new Client();

		self.treeView = new TreeView();
		self.treeView.detach();

		atom.project.remoteftp.on('connected', function () {
			self.treeView.root.name.attr('data-name', Path.basename(atom.project.remoteftp.root.remote));
			self.treeView.root.name.attr('data-path', atom.project.remoteftp.root.remote);
		});

		if (hasProject()) {
			FS.exists(atom.project.resolve('.ftpconfig'), function (exists) {
				if (exists)
					self.treeView.attach();
			});
		}

		atom.commands.add('atom-workspace', {

			'remote-ftp:create-ftp-config': function () {
				if (!hasProject()) return;

				FS.writeFile(atom.project.resolve('.ftpconfig'), '{\n\
    "protocol": "ftp",\n\
	"host": "example.com",\n\
    "port": 21,\n\
    "user": "user",\n\
    "pass": "pass",\n\
    "remote": "/",\n\
    "secure": false,\n\
    "secureOptions": null,\n\
    "connTimeout": 10000,\n\
    "pasvTimeout": 10000,\n\
    "keepalive": 10000\n\
}'			, function (err) {
					if (!err)
						atom.workspace.open(atom.project.resolve('.ftpconfig'));
				});
			},

			'remote-ftp:create-sftp-config': function () {
				if (!hasProject()) return;

				FS.writeFile(atom.project.resolve('.ftpconfig'), '{\n\
    "protocol": "sftp",\n\
	"host": "example.com",\n\
    "port": 22,\n\
    "user": "user",\n\
    "pass": "pass",\n\
    "remote": "/",\n\
	"agent": "",\n\
    "privatekey": "",\n\
	"passphrase": "",\n\
	"hosthash": "",\n\
	"ignorehost": true,\n\
	"connTimeout": 10000,\n\
	"keepalive": 10000\n\
}'			, function (err) {
					if (!err)
						atom.workspace.open(atom.project.resolve('.ftpconfig'));
				});
			},

			'remote-ftp:toggle': function () {
				if (!hasProject()) return;

	            self.treeView.toggle();
	        },

	        'remote-ftp:connect': function () {
				if (!hasProject()) return;

	            atom.project.remoteftp.readConfig(function (e) {
	                if (e) {
						throw "Could not read `.ftpconfig` file";
	                    return;
	                }
	                atom.project.remoteftp.connect();
	            });
	        },

	        'remote-ftp:disconnect': function () {
				if (!hasProject()) return;

	            atom.project.remoteftp.disconnect();
	        },

	        'remote-ftp:add-file': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            if (!AddDialog)
	                AddDialog = require('./dialogs/add-dialog');

	            var dialog = new AddDialog('');
	    		dialog.on('new-path', function (e, name) {
					dialog.close();

	                var remote = Path.join(remotes[0].item.remote, name).replace(/\\/g, '/');

	                atom.project.remoteftp.mkdir(remotes[0].item.remote, true, function (err) {
	                    atom.project.remoteftp.mkfile(remote, function (err) {

	                        remotes[0].open();

	                        if (!err)
	                            atom.workspace.open(atom.project.remoteftp.toLocal(remote));
	                    })
	                });
	    		});
	            dialog.attach();
	        },

	        'remote-ftp:add-folder': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            if (!AddDialog)
	                AddDialog = require('./dialogs/add-dialog');

	            var dialog = new AddDialog('');
	            dialog.on('new-path', function (e, name) {
	                var remote = Path.join(remotes[0].item.remote, name).replace(/\\/g, '/');

	                atom.project.remoteftp.mkdir(remote, true, function (err) {
	                    dialog.close();

	                    remotes[0].open();
	                })
	            });
	            dialog.attach();
	        },

	        'remote-ftp:refresh-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            remotes.forEach(function (remote) {
	                remote.open();
	            });
	        },

	        'remote-ftp:move-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            if (!MoveDialog)
	                MoveDialog = require('./dialogs/move-dialog');

	            var dialog = new MoveDialog(remotes[0].item.remote);
	    		dialog.on('path-changed', function (e, newremote) {
	    			atom.project.remoteftp.rename(remotes[0].item.remote, newremote, function (error) {
						dialog.close();

						// Refresh new folder
						var parentNew = self.treeView.resolve(Path.dirname(newremote));
						if (parentNew)
							parentNew.open();

						// Refresh old folder
						var parentOld = self.treeView.resolve(Path.dirname(remotes[0].item.remote));
						if (parentOld && parentOld != parentNew)
							parentOld.open();

	                    remotes[0].destroy();
	    			});
	    		});
	    		dialog.attach();
	        },

	        'remote-ftp:delete-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            atom.confirm({
	    			message: "Are you sure you want to delete the selected item?",
	    			detailedMessage: "You are deleting:"+ remotes.map(function (view) { return "\n  " + view.item.remote; }),
	                buttons: {
	    				"Move to Trash": function () {
	    					remotes.forEach(function (view) {
								if (!view) return;

								var dir = Path.dirname(view.item.remote).replace(/\\/g, '/'),
									parent = self.treeView.resolve(dir);

								atom.project.remoteftp.delete(view.item.remote, function (err, list) {
									if (!err && parent) {
										parent.open();
									}
								});
	                         });
	    				},
	    				"Cancel": null
	    			}
	    		});
	        },

			'remote-ftp:download-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();

	            remotes.forEach(function (view) {
	                if (!view) return;

	                atom.project.remoteftp.download(view.item.remote, true, function (err) {

	                })
	            })
	        },

			'remote-ftp:upload-selected': function () {
				if (!hasProject()) return;

				var locals = $('.tree-view .selected').map(function () {
				    return this.getPath ? this.getPath() : '';
				}).get();

	            locals.forEach(function (local) {
	                if (!local) return;

	                atom.project.remoteftp.upload(local, function (err, list) {
						if (err)
							return;

						var dirs = [];
						list.forEach(function (item) {
							var remote = atom.project.remoteftp.toRemote(item.name),
								dir = Path.dirname(remote);
							if (dirs.indexOf(dir) == -1)
								dirs.push(dir);
						});

						dirs.forEach(function (dir) {
							var view = self.treeView.resolve(dir);

							if (view)
								view.open();
						});
	                });
	            });
	        },

			// Remote -> local
			'remote-ftp:sync-with-remote': function () {
				var remotes = self.treeView.getSelected();

	            remotes.forEach(function (view) {
	                if (!view) return;

					atom.project.remoteftp.syncRemoteLocal(view.item.remote, function (err) {

					});
				});
			},

			// Local -> Remote
			'remote-ftp:sync-with-local': function () {
				if (!hasProject()) return;

				var locals = $('.tree-view .selected').map(function () {
				    return this.getPath ? this.getPath() : '';
				}).get();

				locals.forEach(function (local) {
	                if (!local) return;

					atom.project.remoteftp.syncLocalRemote(local, function (err) {
						var remote = atom.project.remoteftp.toRemote(local);
						if (remote) {
							var parent = self.treeView.resolve(remote);
							if (!(parent.item instanceof Directory))
								parent = self.treeView.resolve(Path.dirname(remote).replace(/\\/g, '/'));

							if (parent)
								parent.open();
						}
					});
				});
			},

			'remote-ftp:abort-current': function () {
				if (!hasProject()) return;

				atom.project.remoteftp.abort();
			}

		})

		atom.workspace.eachEditor(function (ed) {
			var buffer = ed.buffer;
			buffer.on('saved', self.fileSaved.bind(self));
		});
	},

	deactivate: function () {
		var self = this;
		atom.workspace.eachEditor(function (ed) {
			var buffer = ed.buffer;
			buffer.off('saved', self.fileSaved);
		});

		if (atom.project.remoteftp)
			atom.project.remoteftp.disconnect();
	},

	fileSaved: function (text) {
		if (!hasProject()) return;

		var self = this;

		//if (!atom.project.remoteftp.isConnected())
		//	return;

		var local = text.file.path;

		if (!atom.project.contains(local))
			return;

		if (local == atom.project.resolve('.ftpconfig'))
			return;

		atom.project.remoteftp.upload(local, function (err) {
			try {
				var remote = atom.project.remoteftp.toRemote(local),
					parent = atom.project.remoteftp.resolve(Path.dirname(remote).replace(/\\/g, '/'));
				if (parent)
					parent.open();
			} catch (e) {}
		});
	}
}
<commit_msg>fix #33<commit_after>var FS, Path, $, Client, TreeView, AddDialog, MoveDialog;

function hasProject () {
	return atom.project && atom.project.getPaths().length;
}

module.exports = {
	configDefaults: {
		hideLocalWhenDisplayed: false
	},

	treeView: null,
	client: null,

	activate: function (state) {
		var self = this;

		if (!FS) {
			FS = require('fs-plus');
			Path = require('path');
			$ = require('atom').$;

			Client = require('./client');
			TreeView = require('./views/tree-view');
			Directory = require('./directory');
		}

		atom.project.remoteftp = new Client();

		self.treeView = new TreeView();
		self.treeView.detach();

		atom.project.remoteftp.on('connected', function () {
			self.treeView.root.name.attr('data-name', Path.basename(atom.project.remoteftp.root.remote));
			self.treeView.root.name.attr('data-path', atom.project.remoteftp.root.remote);
		});

		if (hasProject()) {
			FS.exists(atom.project.resolve('.ftpconfig'), function (exists) {
				if (exists)
					self.treeView.attach();
			});
		}

		atom.commands.add('atom-workspace', {

			'remote-ftp:create-ftp-config': function () {
				if (!hasProject()) return;

				FS.writeFile(atom.project.resolve('.ftpconfig'), '{\n\
    "protocol": "ftp",\n\
	"host": "example.com",\n\
    "port": 21,\n\
    "user": "user",\n\
    "pass": "pass",\n\
    "remote": "/",\n\
    "secure": false,\n\
    "secureOptions": null,\n\
    "connTimeout": 10000,\n\
    "pasvTimeout": 10000,\n\
    "keepalive": 10000\n\
}'			, function (err) {
					if (!err)
						atom.workspace.open(atom.project.resolve('.ftpconfig'));
				});
			},

			'remote-ftp:create-sftp-config': function () {
				if (!hasProject()) return;

				FS.writeFile(atom.project.resolve('.ftpconfig'), '{\n\
    "protocol": "sftp",\n\
	"host": "example.com",\n\
    "port": 22,\n\
    "user": "user",\n\
    "pass": "pass",\n\
    "remote": "/",\n\
	"agent": "",\n\
    "privatekey": "",\n\
	"passphrase": "",\n\
	"hosthash": "",\n\
	"ignorehost": true,\n\
	"connTimeout": 10000,\n\
	"keepalive": 10000\n\
}'			, function (err) {
					if (!err)
						atom.workspace.open(atom.project.resolve('.ftpconfig'));
				});
			},

			'remote-ftp:toggle': function () {
				if (!hasProject()) return;

	            self.treeView.toggle();
	        },

	        'remote-ftp:connect': function () {
				if (!hasProject()) return;

	            atom.project.remoteftp.readConfig(function (e) {
	                if (e) {
						throw "Could not read `.ftpconfig` file";
	                    return;
	                }
	                atom.project.remoteftp.connect();
	            });
	        },

	        'remote-ftp:disconnect': function () {
				if (!hasProject()) return;

	            atom.project.remoteftp.disconnect();
	        },

	        'remote-ftp:add-file': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            if (!AddDialog)
	                AddDialog = require('./dialogs/add-dialog');

	            var dialog = new AddDialog('');
	    		dialog.on('new-path', function (e, name) {
					dialog.close();

	                var remote = Path.join(remotes[0].item.remote, name).replace(/\\/g, '/');

	                atom.project.remoteftp.mkdir(remotes[0].item.remote, true, function (err) {
	                    atom.project.remoteftp.mkfile(remote, function (err) {

	                        remotes[0].open();

	                        if (!err)
	                            atom.workspace.open(atom.project.remoteftp.toLocal(remote));
	                    })
	                });
	    		});
	            dialog.attach();
	        },

	        'remote-ftp:add-folder': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            if (!AddDialog)
	                AddDialog = require('./dialogs/add-dialog');

	            var dialog = new AddDialog('');
	            dialog.on('new-path', function (e, name) {
	                var remote = Path.join(remotes[0].item.remote, name).replace(/\\/g, '/');

	                atom.project.remoteftp.mkdir(remote, true, function (err) {
	                    dialog.close();

	                    remotes[0].open();
	                })
	            });
	            dialog.attach();
	        },

	        'remote-ftp:refresh-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            remotes.forEach(function (remote) {
	                remote.open();
	            });
	        },

	        'remote-ftp:move-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            if (!MoveDialog)
	                MoveDialog = require('./dialogs/move-dialog');

	            var dialog = new MoveDialog(remotes[0].item.remote);
	    		dialog.on('path-changed', function (e, newremote) {
	    			atom.project.remoteftp.rename(remotes[0].item.remote, newremote, function (error) {
						dialog.close();

						// Refresh new folder
						var parentNew = self.treeView.resolve(Path.dirname(newremote));
						if (parentNew)
							parentNew.open();

						// Refresh old folder
						var parentOld = self.treeView.resolve(Path.dirname(remotes[0].item.remote));
						if (parentOld && parentOld != parentNew)
							parentOld.open();

	                    remotes[0].destroy();
	    			});
	    		});
	    		dialog.attach();
	        },

	        'remote-ftp:delete-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            atom.confirm({
	    			message: "Are you sure you want to delete the selected item?",
	    			detailedMessage: "You are deleting:"+ remotes.map(function (view) { return "\n  " + view.item.remote; }),
	                buttons: {
	    				"Move to Trash": function () {
	    					remotes.forEach(function (view) {
								if (!view) return;

								var dir = Path.dirname(view.item.remote).replace(/\\/g, '/'),
									parent = self.treeView.resolve(dir);

								atom.project.remoteftp.delete(view.item.remote, function (err, list) {
									if (!err && parent) {
										parent.open();
									}
								});
	                         });
	    				},
	    				"Cancel": null
	    			}
	    		});
	        },

			'remote-ftp:download-selected': function () {
				if (!hasProject()) return;

	            var remotes = self.treeView.getSelected();
				if (!remotes || remotes.length == 0) {
					atom.notifications.addError("**Remote-FTP**
You need to select a folder first");
					return;
				}

	            remotes.forEach(function (view) {
	                if (!view) return;

	                atom.project.remoteftp.download(view.item.remote, true, function (err) {

	                })
	            })
	        },

			'remote-ftp:upload-selected': function () {
				if (!hasProject()) return;

				var locals = $('.tree-view .selected').map(function () {
				    return this.getPath ? this.getPath() : '';
				}).get();

	            locals.forEach(function (local) {
	                if (!local) return;

	                atom.project.remoteftp.upload(local, function (err, list) {
						if (err)
							return;

						var dirs = [];
						list.forEach(function (item) {
							var remote = atom.project.remoteftp.toRemote(item.name),
								dir = Path.dirname(remote);
							if (dirs.indexOf(dir) == -1)
								dirs.push(dir);
						});

						dirs.forEach(function (dir) {
							var view = self.treeView.resolve(dir);

							if (view)
								view.open();
						});
	                });
	            });
	        },

			// Remote -> local
			'remote-ftp:sync-with-remote': function () {
				var remotes = self.treeView.getSelected();

	            remotes.forEach(function (view) {
	                if (!view) return;

					atom.project.remoteftp.syncRemoteLocal(view.item.remote, function (err) {

					});
				});
			},

			// Local -> Remote
			'remote-ftp:sync-with-local': function () {
				if (!hasProject()) return;

				var locals = $('.tree-view .selected').map(function () {
				    return this.getPath ? this.getPath() : '';
				}).get();

				locals.forEach(function (local) {
	                if (!local) return;

					atom.project.remoteftp.syncLocalRemote(local, function (err) {
						var remote = atom.project.remoteftp.toRemote(local);
						if (remote) {
							var parent = self.treeView.resolve(remote);
							if (!(parent.item instanceof Directory))
								parent = self.treeView.resolve(Path.dirname(remote).replace(/\\/g, '/'));

							if (parent)
								parent.open();
						}
					});
				});
			},

			'remote-ftp:abort-current': function () {
				if (!hasProject()) return;

				atom.project.remoteftp.abort();
			}

		})

		atom.workspace.eachEditor(function (ed) {
			var buffer = ed.buffer;
			buffer.on('saved', self.fileSaved.bind(self));
		});
	},

	deactivate: function () {
		var self = this;
		atom.workspace.eachEditor(function (ed) {
			var buffer = ed.buffer;
			buffer.off('saved', self.fileSaved);
		});

		if (atom.project.remoteftp)
			atom.project.remoteftp.disconnect();
	},

	fileSaved: function (text) {
		if (!hasProject()) return;

		var self = this;

		//if (!atom.project.remoteftp.isConnected())
		//	return;

		var local = text.file.path;

		if (!atom.project.contains(local))
			return;

		if (local == atom.project.resolve('.ftpconfig'))
			return;

		atom.project.remoteftp.upload(local, function (err) {
			try {
				var remote = atom.project.remoteftp.toRemote(local),
					parent = atom.project.remoteftp.resolve(Path.dirname(remote).replace(/\\/g, '/'));
				if (parent)
					parent.open();
			} catch (e) {}
		});
	}
}
<|endoftext|>


<commit_before>/**
  RemoteCall
  @description function that makes the remote call using the fetch polyfill,
    running a series of provided lifecycle hooks
  @exports @default {function} callRemoteResource
**/

/* eslint no-unused-vars:0 */
// TODO: should probably use a global fetch instance if we can
import fetch from 'isomorphic-fetch';

/**
  @private
  @name callRemoteResource
  @desc makes a call using the fetch API w/ the given request data & hooks
  @param {object} request
  @param {string} request.uri
  @param {string} request.method
  @param {object} request.headers
  @param {string} request.body
  @param {object} request.requestOps arbitrary options passed to fetch
  @param {object} hooks the lifecycle hooks evaluated at various times
  @param {function} hooks.onBeforeCall
  @param {function} hooks.onCallSuccess(data, response)
  @param {function} hooks.onCallFailure(statusCode, data, response)
**/
export default function callRemoteResource(request, hooks) {
  return null;
}
<commit_msg>Add statusActions arg to remote call sig<commit_after>/**
  RemoteCall
  @description function that makes the remote call using the fetch polyfill,
    running a series of provided lifecycle hooks
  @exports @default {function} callRemoteResource
**/

/* eslint no-unused-vars:0 */
// TODO: should probably use a global fetch instance if we can
import fetch from 'isomorphic-fetch';

/**
  @private
  @name callRemoteResource
  @desc makes a call using the fetch API w/ the given request data & hooks
  @param {object} request
  @param {string} request.uri
  @param {string} request.method
  @param {object} request.headers
  @param {string} request.body
  @param {object} request.requestOps arbitrary options passed to fetch
  @param {array} statusActions an array of objects w/ code & callback keys
  @param {object} hooks the lifecycle hooks evaluated at various times
  @param {function} hooks.onBeforeCall
  @param {function} hooks.onCallSuccess(data, response)
  @param {function} hooks.onCallFailure(statusCode, data, response)
**/
export default function callRemoteResource(request, statusActions, hooks) {
  return null;
}
<|endoftext|>


<commit_before>var funkit = require('funkit');
var is = require('is-js');

function init(app, prefix, apis, queries, auth) {
    prefix = funkit.string.rtrim('/', prefix);

    app.get(prefix, handle(auth, function(req, res) {
        var api = {};

        for(var k in apis) api[k] = queries.getMeta(apis[k]);

        res.json(api);
    }));

    for(var k in apis) initAPI(app, prefix + '/' + k, apis[k], queries, auth);
}
exports.init = init;

// IMPORTANT! if you decide to use key based auth, remember to use SSL
// to mitigate MITM attacks
function key(name, value, check) {
    check = check || function(req) {return true;};

    return function(err, ok) {
        return function(req, res) {
            if(!check(req)) return err(res);

            if(req.query[name] == value || req.body[name] == value) {
                if('query' in req) delete req.query[name];
                if('body' in req) delete req.body[name];
                ok(req, res);
            }
            else err(res);
        };
    };
}

function only(method) {
    return function(err, ok) {
        return function(req, res) {
            if(req.method == method) ok(req, res);
            else err(res);
        };
    };
}

function unauthorized(res) {
    error(res, "Sorry, unable to access this resource. Check your auth", 401);
}

function error(res, msg, code) {
    res.json({errors: [{message: msg}]}, code);
}

exports.auth = {
    key: key,
    only: only
};

function initAPI(app, name, model, queries, auth) {
    var groupOps = {
        post: function(req, res) {
            queries.create(model, getParams(req), ret(res));
        },
        get: function(req, res) {
            var query = req.query;
            var method = query.method;
            delete query.method;

            if(method && method != 'get') getOp(groupOps, method)(req, res);
            else queries.getAll(model, query, ret(res));
        }
    };

    crud(app, name, handlers(auth, groupOps));

    app.get(name + '/count', handle(auth, function(req, res) {
        queries.count(model, ret(res));
    }));

    var idOps = {
        get: function(req, res) {
            var method = req.query.method;

            if(method && method != 'get') getOp(idOps, method)(req, res);
            else queries.get(model, req.params.id, req.query.fields, ret(res));
        },
        put: function(req, res) {
            queries.update(model, req.params.id, getParams(req), ret(res));
        },
        'delete': function(req, res) {
            queries['delete'](model, req.params.id, ret(res));
        }
    };

    crud(app, name + '/:id', handlers(auth, idOps));
}

function getParams(req) {
    return Object.keys(req.body).length? req.body: req.query;
}

function handlers(auth, o) {
    var ret = {};

    for(var k in o) ret[k] = handle(auth, o[k]);

    return ret;
}

function handle(auth, fn) {
    auth = auth || function(err, ok) {return function(req, res) {ok(req, res);};};

    return auth(unauthorized, function(req, res) {
        req.body = parseCommaLists(req.body);
        req.query = parseCommaLists(req.query);
        fn(req, res);
    });
}

function ret(res) {
    return function(err, d) {
        if(err) {
            res.status(400);
            res.json(err);
            return;
        }

        res.json(d);
    };
}

function getOp(verbs, method) {
    if(method in verbs) return verbs[method];
    return notAllowed(verbs);
}

function parseCommaLists(o) {
    var ret = {};

    for(var k in o) {
        var v = o[k];

        if(k && is.string(v)) {
            var parts = v.split(',');

            ret[k] = parts.length > 1? parts: v;
        }
        else {
            ret[k] = v;
        }
    }

    return ret;
}

function crud(app, url, verbs) {
    for(var k in verbs) app[k](url, verbs[k] || notAllowed(verbs));
}

function notAllowed(verbs) {
    var allowed = Object.keys(verbs).map(function(k) {k.toUpperCase();}).join(', ');

    return function(req, res) {
        res.header('Allow', allowed);
        res.send(403);
    };
}

<commit_msg>Add success callback<commit_after>var funkit = require('funkit');
var is = require('is-js');

function init(app, prefix, apis, queries, auth, success) {
    prefix = funkit.string.rtrim('/', prefix);

    app.get(prefix, handle(auth, function(req, res) {
        var api = {};

        for(var k in apis) api[k] = queries.getMeta(apis[k]);

        res.json(api);
    }));

    for(var k in apis) initAPI(app, prefix + '/' + k, apis[k], queries, auth, success);
}
exports.init = init;

// IMPORTANT! if you decide to use key based auth, remember to use SSL
// to mitigate MITM attacks
function key(name, value, check) {
    check = check || function(req) {return true;};

    return function(err, ok) {
        return function(req, res) {
            if(!check(req)) return err(res);

            if(req.query[name] == value || req.body[name] == value) {
                if('query' in req) delete req.query[name];
                if('body' in req) delete req.body[name];
                ok(req, res);
            }
            else err(res);
        };
    };
}

function only(method) {
    return function(err, ok) {
        return function(req, res) {
            if(req.method == method) ok(req, res);
            else err(res);
        };
    };
}

function unauthorized(res) {
    error(res, "Sorry, unable to access this resource. Check your auth", 401);
}

function error(res, msg, code) {
    res.json({errors: [{message: msg}]}, code);
}

exports.auth = {
    key: key,
    only: only
};

function initAPI(app, name, model, queries, auth, success) {
    var groupOps = {
        post: function(req, res) {
            queries.create(model, getParams(req), ret(res, success));
        },
        get: function(req, res) {
            var query = req.query;
            var method = query.method;
            delete query.method;

            if(method && method != 'get') getOp(groupOps, method)(req, res);
            else queries.getAll(model, query, ret(res, success));
        }
    };

    crud(app, name, handlers(auth, groupOps));

    app.get(name + '/count', handle(auth, function(req, res) {
        queries.count(model, ret(res, success));
    }));

    var idOps = {
        get: function(req, res) {
            var method = req.query.method;

            if(method && method != 'get') getOp(idOps, method)(req, res);
            else queries.get(model, req.params.id, req.query.fields, ret(res, success));
        },
        put: function(req, res) {
            queries.update(model, req.params.id, getParams(req), ret(res, success));
        },
        'delete': function(req, res) {
            queries['delete'](model, req.params.id, ret(res, success));
        }
    };

    crud(app, name + '/:id', handlers(auth, idOps));
}

function getParams(req) {
    return Object.keys(req.body).length? req.body: req.query;
}

function handlers(auth, o) {
    var ret = {};

    for(var k in o) ret[k] = handle(auth, o[k]);

    return ret;
}

function handle(auth, fn) {
    auth = auth || function(err, ok) {return function(req, res) {ok(req, res);};};

    return auth(unauthorized, function(req, res) {
        req.body = parseCommaLists(req.body);
        req.query = parseCommaLists(req.query);
        fn(req, res);
    });
}

function ret(res, success) {
    success = function() {};

    return function(err, d) {
        if(err) {
            res.status(400);
            res.json(err);
            return;
        }

        success(d);

        res.json(d);
    };
}

function getOp(verbs, method) {
    if(method in verbs) return verbs[method];
    return notAllowed(verbs);
}

function parseCommaLists(o) {
    var ret = {};

    for(var k in o) {
        var v = o[k];

        if(k && is.string(v)) {
            var parts = v.split(',');

            ret[k] = parts.length > 1? parts: v;
        }
        else {
            ret[k] = v;
        }
    }

    return ret;
}

function crud(app, url, verbs) {
    for(var k in verbs) app[k](url, verbs[k] || notAllowed(verbs));
}

function notAllowed(verbs) {
    var allowed = Object.keys(verbs).map(function(k) {k.toUpperCase();}).join(', ');

    return function(req, res) {
        res.header('Allow', allowed);
        res.send(403);
    };
}

<|endoftext|>


<commit_before>module.exports = exports = function(redRGB, greenRGB, blueRGB) {
  var red = redRGB / 255;
  var green = greenRGB / 255;
  var blue = blueRGB / 255;

  var max = Math.max(red, green, blue);
  var min = Math.min(red, green, blue);
  var delta = max - min;

  var luminace = (max + min) / 2;

  var saturation = 0;
  var hueCalc = 0;

  if (luminace < 0.5) {
    saturation = delta / (max + min);
  } else {
    saturation = delta / (2 - delta);
  }

  if (min === max) {
    saturation = 0;
    hueCalc = 0;
  } else if (max === red) {
    hueCalc = (green - blue) / delta;
  } else if (max === green) {
    hueCalc = 2 + (blue - red) / delta;
  } else if (max === blue) {
    hueCalc = 4 + (red - green) / delta;
  }

  var hue360 = hueCalc * 60;
  if (hue360 < 0) hue360 += 360;

  var colorObj = {};
  colorObj.hue = Math.round(hue360 * 182.0417);
  // the bottom of the saturation spectrum just looks white, so we capping
  // the lower end at 100 to give a better color spread
  colorObj.sat = Math.round(saturation * 155 + 100);

  return colorObj;
};
<commit_msg>final refactor, closes #64<commit_after>module.exports = exports = function(redRGB, greenRGB, blueRGB) {
  var red = redRGB / 255;
  var green = greenRGB / 255;
  var blue = blueRGB / 255;

  var max = Math.max(red, green, blue);
  var min = Math.min(red, green, blue);
  var delta = max - min;

  var saturation = 0;
  var hue360 = 0;

  if ((max + min) / 2 < 0.5) {
    saturation = delta / (max + min);
  } else {
    saturation = delta / (2 - delta);
  }

  if (min === max) {
    saturation = 0;
    hue360 = 0;
  } else if (max === red) {
    hue360 = 60 * (green - blue) / delta;
  } else if (max === green) {
    hue360 = 60 * (2 + (blue - red)) / delta;
  } else if (max === blue) {
    hue360 = 60 * (4 + (red - green)) / delta;
  }

  if (hue360 < 0) hue360 += 360;

  var colorObj = {};
  // hue360 is on 360 degree color wheel, but our hue values support 65535
  // hue values.  This converts from 360 to 65535
  colorObj.hue = Math.round(hue360 * 182.0417);
  // the bottom of the saturation spectrum just looks white, so we capping
  // the lower end at 100 to give a better color spread
  colorObj.sat = Math.round(saturation * 155 + 100);

  return colorObj;
};
<|endoftext|>


<commit_before>const { window: { document } } = require('sdk/addon/window');
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
var { viewFor } = require("sdk/view/core");

const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
document.documentElement.appendChild(canvas);

exports.captureTab = function (tab, pos, backgroundColor) {
  if (! tab) {
    tab = getActiveTab(getMostRecentBrowserWindow());
  }
  if (tab && tab.attach) {
    tab = viewFor(tab);
  }
  let contentWindow = getTabContentWindow(tab);

  if (! pos) {
    pos = {};
    pos.w = contentWindow.innerWidth;
    pos.h = contentWindow.innerHeight;
    pos.x = contentWindow.scrollX;
    pos.y = contentWindow.scrollY;
  }

  canvas.width = pos.w;
  canvas.height = pos.h;

  let ctx = canvas.getContext('2d');

  backgroundColor = backgroundColor || "#000";

  try {
    ctx.drawWindow(contentWindow, pos.x, pos.y, pos.w, pos.h, backgroundColor);
  } catch (e) {
    console.warn("Error in making screenshot: do you have e10s enabled?  This addon is not compatible with that.");
    throw e;
  }
  return canvas.toDataURL();
};
<commit_msg>Keep the size of screenshots limited (scale them down)<commit_after>const { window: { document } } = require('sdk/addon/window');
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
var { viewFor } = require("sdk/view/core");

const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
document.documentElement.appendChild(canvas);

var MAX_WIDTH = 350;
var MAX_HEIGHT = 200;

exports.captureTab = function (tab, pos, maxSize, backgroundColor) {
  if (! tab) {
    tab = getActiveTab(getMostRecentBrowserWindow());
  }
  if (tab && tab.attach) {
    tab = viewFor(tab);
  }
  if (! maxSize) {
    maxSize = {h: MAX_HEIGHT, w: MAX_WIDTH};
  }
  let contentWindow = getTabContentWindow(tab);

  if (! pos) {
    pos = {};
    pos.w = contentWindow.innerWidth;
    pos.h = contentWindow.innerHeight;
    pos.x = contentWindow.scrollX;
    pos.y = contentWindow.scrollY;
  }

  if (pos.w > maxSize.w || pos.h > maxSize.h) {
    if ((pos.w / pos.h) > (maxSize.w / maxSize.h)) {
      // Wider than tall
      maxSize.w = (maxSize.h / pos.h) * pos.w;
    } else {
      // Taller than wide
      maxSize.h = (maxSize.w / pos.w) * pos.h;
    }
  } else {
    maxSize = null;
  }

  if (maxSize) {
    canvas.width = maxSize.w;
    canvas.height = maxSize.h;
  } else {
    canvas.width = pos.w;
    canvas.height = pos.h;
  }

  let ctx = canvas.getContext('2d');

  if (maxSize) {
    ctx.scale(pos.w / maxSize.w, pos.h / maxSize.h);
  }
  backgroundColor = backgroundColor || "#000";

  try {
    ctx.drawWindow(contentWindow, pos.x, pos.y, pos.w, pos.h, backgroundColor);
  } catch (e) {
    console.warn("Error in making screenshot: do you have e10s enabled?  This addon is not compatible with that.");
    throw e;
  }
  return canvas.toDataURL();
};
<|endoftext|>


<commit_before>'use strict';

var JSONProblemError = require('./json-problem-error');

// todo handle array of errors in sendError
var sendError = function (req, res, error) {

    var stringify = function (object) {
        return process.env.NODE_ENV === 'production' ?
            JSON.stringify(object, null, null) :
        JSON.stringify(object, null, 2) + '\n';
    };

    function normaliseError(error) {
        if (error instanceof JSONProblemError) {
            return error;
        } else {
            return new JSONProblemError({
                httpStatus: 500,
                problemType: 'about:blank',
                title: 'Oops, something went wrong.',
                detail: error && process.env.NODE_ENV !== 'production' ? error.toString() : ''
            });
        }
    }

    try {
        if (!!error && error instanceof JSONProblemError && error.problem.httpStatus >= 500) console.trace(error);
        res.set('Content-Type', 'application/problem+json');
        var normalisedError = normaliseError(error);
        res.send(normalisedError.problem.httpStatus, stringify(normalisedError));
    } catch (e) {
        console.error('! Something broke during sendError routine !', e.stack);
    }

};

module.exports = sendError;

<commit_msg>removed duplicate code in send-error.js<commit_after>'use strict';

var JSONProblemError = require('./json-problem-error');

// todo handle array of errors in sendError
var sendError = function (req, res, error) {

    var stringify = function (object) {
        return process.env.NODE_ENV === 'production' ?
            JSON.stringify(object, null, null) :
        JSON.stringify(object, null, 2) + '\n';
    };

    function normaliseError(error) {
        if (error instanceof JSONProblemError) {
            return error;
        } else {
            return new JSONProblemError({
                httpStatus: 500,
                detail: error && process.env.NODE_ENV !== 'production' ? error.toString() : ''
            });
        }
    }

    try {
        if (!!error && error instanceof JSONProblemError && error.problem.httpStatus >= 500) console.trace(error);
        res.set('Content-Type', 'application/problem+json');
        var normalisedError = normaliseError(error);
        res.send(normalisedError.problem.httpStatus, stringify(normalisedError));
    } catch (e) {
        console.error('! Something broke during sendError routine !', e.stack);
    }

};

module.exports = sendError;

<|endoftext|>


<commit_before>/* @flow */
'use strict'

/* ::
import type {
  BlinkMRCServer, CorsConfiguration, RouteConfiguration
} from '../types.js'
*/

const path = require('path')

const execa = require('execa')
const loadJsonFile = require('load-json-file')
const writeJsonFile = require('write-json-file')

const nonAlphaNumericToDashes = require('./utils/non-alpha-numeric-to-dashes.js')
const readCors = require('./cors/read.js')
const readRoutes = require('./routes/read.js')
const scope = require('./scope.js')
const updateYamlFile = require('./utils/yaml.js').updateYamlFile
const copyRecursive = require('./utils/copy-recursive.js')
const validateCors = require('./cors/validate.js')

const HANDLER = 'handler'
const WRAPPER = path.join(__dirname, '..', 'dist', 'wrapper.js')

function applyTemplate (
  cwd /* : string */
) /* : Promise<void> */ {
  return execa(path.join(__dirname, '..', 'node_modules', '.bin', 'serverless'), [ 'create', '--template', 'aws-nodejs' ], { cwd })
}

function copyConfiguration (
  target /* : string */,
  projectPath /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  const configPath = path.join(target, 'bm-server.json')
  return Promise.all([
    readCors(projectPath)
      .then((cors) => cors ? validateCors(cors) : false),
    readRoutes(projectPath)
  ])
    .then((results) => writeJsonFile(configPath, {
      cors: results[0],
      routes: results[1].map((routeConfig, index) => {
        routeConfig.module = path.join(projectPath, routeConfig.module)
        return routeConfig
      })
    }))
}

function copyProject (
  source /* : string */,
  target /* : string */
) /* : Promise<string> */ {
  const projectPath = path.join(target, 'project')
  return copyRecursive(source, projectPath)
    .then(() => projectPath)
}

function copyWrapper (
  target /* : string */
) /* : Promise<void> */ {
  const wrapperPath = path.join(target, `${HANDLER}.js`)
  return copyRecursive(WRAPPER, wrapperPath)
}

function getFunctionName (
  cfg /* : BlinkMRCServer */,
  routeConfig /* : RouteConfiguration */,
  env /* : string */
) /* : string */ {
  // Lambdas do not allow for any characters other than alpha-numeric and dashes in function names
  const arr = [cfg.project || '', env, routeConfig.route]
  const mapped = arr.map(nonAlphaNumericToDashes)
  return mapped.join('-')
}

function registerFunctions (
  target /* : string */,
  projectPath /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  return Promise.all([
    readRoutes(projectPath),
    scope.read(projectPath)
  ])
    .then((results) => {
      const routeConfigs = results[0]
      const cfg = results[1]

      return updateServerlessYamlFile(target, (config) => {
        config.service = nonAlphaNumericToDashes(cfg.project || '')
        config.provider = config.provider || {}
        config.provider.region = cfg.region
        config.provider.stage = env
        config.functions = routeConfigs.reduce((functions, routeConfig, index) => {
          // The route must not start with a leading '/'
          const route = routeConfig.route.substr(1)
          const functionName = getFunctionName(cfg, routeConfig, env)
          functions[functionName] = {
            events: [{
              http: `ANY ${route}`
            }],
            handler: `${HANDLER}.handler`,
            name: functionName,
            description: routeConfig.route,
            timeout: routeConfig.timeout
          }
          return functions
        }, {})

        return config
      })
    })
}

function registerDeploymentBucket (
  target /* : string */,
  deploymentBucket /* : string | void */
) /* : Promise<void> */ {
  if (!deploymentBucket) {
    return Promise.resolve()
  }
  return updateServerlessYamlFile(target, (config) => {
    config.provider = config.provider || {}
    config.provider.deploymentBucket = deploymentBucket
    return config
  })
}

function registerExecutionRole (
  target /* : string */,
  executionRole /* : string | void */
) /* : Promise<void> */ {
  if (!executionRole) {
    return Promise.resolve()
  }
  return updateServerlessYamlFile(target, (config) => {
    config.provider = config.provider || {}
    config.provider.role = executionRole
    return config
  })
}

function registerRootProxy (
  target /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  // TODO: detect root route Lambda function (if any) and skip this proxy

  // https://serverless.com/framework/docs/providers/aws/events/apigateway#setting-an-http-proxy-on-api-gateway

  return loadJsonFile(path.join(__dirname, 'root-route-proxy.json'))
    .then((resources) => updateServerlessYamlFile(target, (config) => {
      config.resources = resources
      return config
    }))
}

function registerVpc (
  target /* : string */,
  vpcSecurityGroups /* : string | void */,
  vpcSubnets /* : string | void */,
  separator /* : string */
) /* : Promise<void> */ {
  // Only add vpc configuration if security groups and subnets are provided
  if (!vpcSecurityGroups || !vpcSubnets) {
    return Promise.resolve()
  }
  // https://serverless.com/framework/docs/providers/aws/guide/functions#vpc-configuration
  return updateServerlessYamlFile(target, (config) => {
    // need the extra check here incase things changed during updateServerlessYamlFile() (flow-type)
    if (vpcSecurityGroups && vpcSubnets) {
      config.provider = config.provider || {}
      config.provider.vpc = {
        securityGroupIds: vpcSecurityGroups.split(separator).map((securityGroup) => securityGroup.trim()),
        subnetIds: vpcSubnets.split(separator).map((subnet) => subnet.trim())
      }
    }
    return config
  })
}

function updateServerlessYamlFile (
  target /* : string */,
  updater /* : (data: Object) => Object */
) /* : Promise<void> */ {
  const configPath = path.join(target, 'serverless.yml')
  return updateYamlFile(configPath, updater)
}

module.exports = {
  applyTemplate,
  copyConfiguration,
  copyProject,
  copyWrapper,
  getFunctionName,
  registerDeploymentBucket,
  registerExecutionRole,
  registerFunctions,
  registerRootProxy,
  registerVpc
}
<commit_msg>SC-57 # function to execute serverless cli command<commit_after>/* @flow */
'use strict'

/* ::
import type {
  BlinkMRCServer, CorsConfiguration, RouteConfiguration
} from '../types.js'
*/

const path = require('path')

const execa = require('execa')
const loadJsonFile = require('load-json-file')
const writeJsonFile = require('write-json-file')

const nonAlphaNumericToDashes = require('./utils/non-alpha-numeric-to-dashes.js')
const readCors = require('./cors/read.js')
const readRoutes = require('./routes/read.js')
const scope = require('./scope.js')
const updateYamlFile = require('./utils/yaml.js').updateYamlFile
const copyRecursive = require('./utils/copy-recursive.js')
const validateCors = require('./cors/validate.js')

const HANDLER = 'handler'
const WRAPPER = path.join(__dirname, '..', 'dist', 'wrapper.js')

function applyTemplate (
  cwd /* : string */
) /* : Promise<void> */ {
  return executeSLSCommand([ 'create', '--template', 'aws-nodejs' ], { cwd })
}

function copyConfiguration (
  target /* : string */,
  projectPath /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  const configPath = path.join(target, 'bm-server.json')
  return Promise.all([
    readCors(projectPath)
      .then((cors) => cors ? validateCors(cors) : false),
    readRoutes(projectPath)
  ])
    .then((results) => writeJsonFile(configPath, {
      cors: results[0],
      routes: results[1].map((routeConfig, index) => {
        routeConfig.module = path.join(projectPath, routeConfig.module)
        return routeConfig
      })
    }))
}

function copyProject (
  source /* : string */,
  target /* : string */
) /* : Promise<string> */ {
  const projectPath = path.join(target, 'project')
  return copyRecursive(source, projectPath)
    .then(() => projectPath)
}

function copyWrapper (
  target /* : string */
) /* : Promise<void> */ {
  const wrapperPath = path.join(target, `${HANDLER}.js`)
  return copyRecursive(WRAPPER, wrapperPath)
}

function executeSLSCommand (
  args /* : Array<string> */,
  options /* : { [id:string]: any } */
) /* : Promise<void> */ {
  return execa(path.join(__dirname, '..', 'node_modules', '.bin', 'serverless'), args, options)
}

function getFunctionName (
  cfg /* : BlinkMRCServer */,
  routeConfig /* : RouteConfiguration */,
  env /* : string */
) /* : string */ {
  // Lambdas do not allow for any characters other than alpha-numeric and dashes in function names
  const arr = [cfg.project || '', env, routeConfig.route]
  const mapped = arr.map(nonAlphaNumericToDashes)
  return mapped.join('-')
}

function registerFunctions (
  target /* : string */,
  projectPath /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  return Promise.all([
    readRoutes(projectPath),
    scope.read(projectPath)
  ])
    .then((results) => {
      const routeConfigs = results[0]
      const cfg = results[1]

      return updateServerlessYamlFile(target, (config) => {
        config.service = nonAlphaNumericToDashes(cfg.project || '')
        config.provider = config.provider || {}
        config.provider.region = cfg.region
        config.provider.stage = env
        config.functions = routeConfigs.reduce((functions, routeConfig, index) => {
          // The route must not start with a leading '/'
          const route = routeConfig.route.substr(1)
          const functionName = getFunctionName(cfg, routeConfig, env)
          functions[functionName] = {
            events: [{
              http: `ANY ${route}`
            }],
            handler: `${HANDLER}.handler`,
            name: functionName,
            description: routeConfig.route,
            timeout: routeConfig.timeout
          }
          return functions
        }, {})

        return config
      })
    })
}

function registerDeploymentBucket (
  target /* : string */,
  deploymentBucket /* : string | void */
) /* : Promise<void> */ {
  if (!deploymentBucket) {
    return Promise.resolve()
  }
  return updateServerlessYamlFile(target, (config) => {
    config.provider = config.provider || {}
    config.provider.deploymentBucket = deploymentBucket
    return config
  })
}

function registerExecutionRole (
  target /* : string */,
  executionRole /* : string | void */
) /* : Promise<void> */ {
  if (!executionRole) {
    return Promise.resolve()
  }
  return updateServerlessYamlFile(target, (config) => {
    config.provider = config.provider || {}
    config.provider.role = executionRole
    return config
  })
}

function registerRootProxy (
  target /* : string */,
  env /* : string */
) /* : Promise<void> */ {
  // TODO: detect root route Lambda function (if any) and skip this proxy

  // https://serverless.com/framework/docs/providers/aws/events/apigateway#setting-an-http-proxy-on-api-gateway

  return loadJsonFile(path.join(__dirname, 'root-route-proxy.json'))
    .then((resources) => updateServerlessYamlFile(target, (config) => {
      config.resources = resources
      return config
    }))
}

function registerVpc (
  target /* : string */,
  vpcSecurityGroups /* : string | void */,
  vpcSubnets /* : string | void */,
  separator /* : string */
) /* : Promise<void> */ {
  // Only add vpc configuration if security groups and subnets are provided
  if (!vpcSecurityGroups || !vpcSubnets) {
    return Promise.resolve()
  }
  // https://serverless.com/framework/docs/providers/aws/guide/functions#vpc-configuration
  return updateServerlessYamlFile(target, (config) => {
    // need the extra check here incase things changed during updateServerlessYamlFile() (flow-type)
    if (vpcSecurityGroups && vpcSubnets) {
      config.provider = config.provider || {}
      config.provider.vpc = {
        securityGroupIds: vpcSecurityGroups.split(separator).map((securityGroup) => securityGroup.trim()),
        subnetIds: vpcSubnets.split(separator).map((subnet) => subnet.trim())
      }
    }
    return config
  })
}

function updateServerlessYamlFile (
  target /* : string */,
  updater /* : (data: Object) => Object */
) /* : Promise<void> */ {
  const configPath = path.join(target, 'serverless.yml')
  return updateYamlFile(configPath, updater)
}

module.exports = {
  applyTemplate,
  copyConfiguration,
  copyProject,
  copyWrapper,
  executeSLSCommand,
  getFunctionName,
  registerDeploymentBucket,
  registerExecutionRole,
  registerFunctions,
  registerRootProxy,
  registerVpc
}
<|endoftext|>