<commit_before>var assign = require('object-assign');
var fs = require('fs-extra');
var path = require('path');
var mime = require('mime-types');
var nameFunctions = require('./nameFunctions');

/**
	The Adapter Compatibility Level is used to ensure that provided adapters
	have been designed to work with the version of Storage implemented in the
	version of Keystone being used.

	The Adapter Compatibility Level must be an exact match or an error will be
	thrown when the Storage instance is initialised.
*/
var ADAPTER_COMPATIBILITY_LEVEL = 1;

/**
	This is the default storage schema for file fields. These paths will be
	persisted to the database and represent the value of the file field.

	Storage Adapters can specify their own schema properties but must implement
	the required schema fields (see array below).
*/
var SCHEMA_TYPES = {
//	filename: String,       // the filename, without the full path
	size: Number,           // the size of the file
	mimetype: String,       // the mime type of the file
	path: String,           // the path (e.g directory) the file is stored in; not the full path to the file
	originalname: String,   // the original (uploaded) name of the file; useful when filename generated
	url: String,            // publicly accessible URL of the stored file
};

/**
	This is the default set of schema fields that are enabled. The storage
	options can override these (must be supported by the adapter, or the
	adapter must use the default schema implementation)
*/
var SCHEMA_FIELD_DEFAULTS = {
	// filename: true,
	size: true,
	mimetype: true,
	path: false,
	originalname: false,
	url: false,
};

/**
	These schema paths _must_ be included in a schema, as they're expected
	by the Admin UI
*/
// var REQUIRED_SCHEMA_FIELDS = ['filename'];

// TODO: We could support custom schema mappings for backwards compatibilty
// with Keystone 3 or imported schamas... not sure if it's worth it though.

var DEFAULT_OPTIONS = {
	generateFilename: nameFunctions.randomFilename,
	whenExists: 'retry',
	retryAttempts: 3, // For whenExists: 'retry'.
};

/**
	# Storage Prototype

	Creates a new Keystone Storage instance, and validates and initialises the
	specified adapter. Storage schema is configured from the adapter or default.
*/
function Storage (options) {
	this.options = options = assign({}, DEFAULT_OPTIONS, options);
	// ensure the adapter compatibilityLevel of the adapter matches
	if (options.adapter.compatibilityLevel !== ADAPTER_COMPATIBILITY_LEVEL) {
		throw new Error('Incompatible Storage Adapter\n\n'
			+ 'The storage adapter specified (' + options.adapter.name + ') '
			+ 'does not match the compatibility level required for this '
			+ 'version of Keystone.');
	}

	var adapterType = options.adapter;
	// assign ensures the default schema constant isn't exposed as a property
	var schemaFields = assign({}, SCHEMA_FIELD_DEFAULTS, adapterType.SCHEMA_FIELD_DEFAULTS, options.schema);

	// Copy requested fields into local schema.
	var schema = this.schema = {};
	for (var path in schemaFields) {
		if (!schemaFields[path]) continue;

		var type = adapterType.SCHEMA_TYPES[path] || SCHEMA_TYPES[path];
		if (!type) throw Error('Unknown type for requested schema field ' + path);
		schema[path] = type;
	}

	// create the adapter
	this.adapter = new options.adapter(options, schema);

	if (!this.adapter.fileExists && (options.whenExists === 'retry' || options.whenExists === 'error')) {
		throw Error('Cannot use whenExists option `' + options.whenExists + '`'
			+ ' with file adapter as it does not implement optional .fileExists method');
	}

	// The generateFilename option takes an optional callback. Wrap it to always
	// take a callback.
	if (options.generateFilename.length <= 2) { // (file) or (file, attempt)
		// If generateFilename throws I'll take that as a runtime error and not
		// a file data error. If you need to pass errors upstream take a
		// callback.
		var original = options.generateFilename;
		options.generateFilename = function (file, attempt, callback) {
			callback(null, original(file, attempt));
		};
	}
}

// Helper function for figuring out the size of a file before uploading it.
function getSize (file, callback) {
	if (file.size) return callback(null, file.size);

	fs.stat(file.path, function (err, stats) {
		if (!stats.isFile()) {
			return callback(Error(file.path + ' is not a file'));
		}

		callback(err, stats ? stats.size : null);
	});
}

// Helper to attempt an async process `maxAttempts` times. Used to find a valid
// name for the uploaded file.
function attemptNTimes (maxAttempts, fn, callback) {
	function _attemptNTimes (attempt) {
		if (attempt >= maxAttempts) return callback(Error('Maximum attempts exceeded'));

		fn(attempt, function (err, isDone, data) {
			if (err) return callback(err);
			if (isDone) return callback(null, data);
			_attemptNTimes(attempt + 1);
		});
	}

	_attemptNTimes(0);
}

Storage.prototype._genFilename = function (file, callback) {
	var options = this.options;
	var adapter = this.adapter;
	switch (options.whenExists) {
		case 'overwrite':
			options.generateFilename(file, 0, callback);
			break;
		case 'error':
			options.generateFilename(file, 0, function (err, filename) {
				if (err) return callback(err);
				adapter.fileExists(filename, function (err, result) {
					if (err) return callback(err);
					if (result === true) return callback(Error('File already exists'));
					callback(null, filename);
				});
			});
			break;
		case 'retry':
			attemptNTimes(options.retryAttempts, function (num, next) {
				options.generateFilename(file, num, function (err, filename) {
					if (err) return next(err);
					self.adapter.fileExists(filename, function (err, exists) {
						next(err, !err && !exists);
					});
				});
			}, callback);
	}
};

// Helper to fill out missing fields in the file object
function normalizeFile (file, schema, callback) {
	// Detect required information if it wasn't provided by inspecting the
	// file stored at file.path
	if (schema.mimetype && !file.mimetype) file.mimetype = mime(file.path);

	if (!file.originalname) {
		file.originalname = file.name
			|| (file.path) ? path.parse(file.path).base : 'unnamedfile';
	}

	if (schema.size && !file.size) {
		getSize(file, function (err, size) {
			if (err) return callback(err);
			file.size = size;
			callback(null, file);
		});
	} else callback(null, file);
}

/**
	Uploads a new file via the adapter, then decorates the result with the
	public url for the file. The result is what is saved back to the field.
*/
Storage.prototype.uploadFile = function (file, callback) {
	var self = this;

	// The path to the file is required
	if (!file.path) return callback(Error('Cannot upload file - No source path'));

	normalizeFile(file, this.schema, function (err, file) {
		if (err) return callback(err);
		self._genFilename(file, function (err, filename) {
			if (err) return callback(err);

			self.adapter.uploadFile(filename, file, function (err, result) {
				if (err) return callback(err);
				result.url = self.adapter.getFileURL(result);

				callback(null, result);
			});
		});
	});
};

/**
	Removes a stored file by passing the field value to the adapter.
*/
Storage.prototype.removeFile = function (value, callback) {
	this.adapter.removeFile(value, callback);
};

/*
	Built-in Adapters
*/
Storage.Adapters = {};
Storage.Adapters.FS = require('./adapters/fs');
Storage.nameFunctions = nameFunctions;

module.exports = Storage;
<commit_msg>Simplifying filename generation logic<commit_after>var assign = require('object-assign');
var fs = require('fs-extra');
var path = require('path');
var mime = require('mime-types');
var nameFunctions = require('./nameFunctions');

/**
	The Adapter Compatibility Level is used to ensure that provided adapters
	have been designed to work with the version of Storage implemented in the
	version of Keystone being used.

	The Adapter Compatibility Level must be an exact match or an error will be
	thrown when the Storage instance is initialised.
*/
var ADAPTER_COMPATIBILITY_LEVEL = 1;

/**
	This is the default storage schema for file fields. These paths will be
	persisted to the database and represent the value of the file field.

	Storage Adapters can specify their own schema properties but must implement
	the required schema fields (see array below).
*/
var SCHEMA_TYPES = {
//	filename: String,       // the filename, without the full path
	size: Number,           // the size of the file
	mimetype: String,       // the mime type of the file
	path: String,           // the path (e.g directory) the file is stored in; not the full path to the file
	originalname: String,   // the original (uploaded) name of the file; useful when filename generated
	url: String,            // publicly accessible URL of the stored file
};

/**
	This is the default set of schema fields that are enabled. The storage
	options can override these (must be supported by the adapter, or the
	adapter must use the default schema implementation)
*/
var SCHEMA_FIELD_DEFAULTS = {
//	filename: true,
	size: true,
	mimetype: true,
	path: false,
	originalname: false,
	url: false,
};

// TODO: We could support custom schema mappings for backwards compatibilty
// with Keystone 3 or imported schamas... not sure if it's worth it though.

var DEFAULT_OPTIONS = {
	generateFilename: nameFunctions.randomFilename,
	whenExists: 'retry',
	retryAttempts: 3, // For whenExists: 'retry'.
};

/**
	# Storage Prototype

	Creates a new Keystone Storage instance, and validates and initialises the
	specified adapter. Storage schema is configured from the adapter or default.
*/
function Storage (options) {
	this.options = options = assign({}, DEFAULT_OPTIONS, options);
	// ensure the adapter compatibilityLevel of the adapter matches
	if (options.adapter.compatibilityLevel !== ADAPTER_COMPATIBILITY_LEVEL) {
		throw new Error('Incompatible Storage Adapter\n\n'
			+ 'The storage adapter specified (' + options.adapter.name + ') '
			+ 'does not match the compatibility level required for this '
			+ 'version of Keystone.');
	}

	var adapterType = options.adapter;
	// assign ensures the default schema constant isn't exposed as a property
	var schemaFields = assign({}, SCHEMA_FIELD_DEFAULTS, adapterType.SCHEMA_FIELD_DEFAULTS, options.schema);

	// Copy requested fields into local schema.
	var schema = this.schema = {};
	for (var path in schemaFields) {
		if (!schemaFields[path]) continue;

		var type = adapterType.SCHEMA_TYPES[path] || SCHEMA_TYPES[path];
		if (!type) throw Error('Unknown type for requested schema field ' + path);
		schema[path] = type;
	}

	// create the adapter
	this.adapter = new options.adapter(options, schema);

	if (!this.adapter.fileExists && (options.whenExists === 'retry' || options.whenExists === 'error')) {
		throw Error('Cannot use whenExists option `' + options.whenExists + '`'
			+ ' with file adapter as it does not implement optional .fileExists method');
	}

	// The generateFilename option takes an optional callback. Wrap it to always
	// take a callback.
	if (options.generateFilename.length <= 2) { // (file) or (file, attempt)
		// If generateFilename throws I'll take that as a runtime error and not
		// a file data error. If you need to pass errors upstream take a
		// callback.
		var original = options.generateFilename;
		options.generateFilename = function (file, attempt, callback) {
			callback(null, original(file, attempt));
		};
	}
}

// Helper function for figuring out the size of a file before uploading it.
function getSize (file, callback) {
	if (file.size) return callback(null, file.size);

	fs.stat(file.path, function (err, stats) {
		if (!stats.isFile()) {
			return callback(Error(file.path + ' is not a file'));
		}

		callback(err, stats ? stats.size : null);
	});
}

function retryFilename (attempt, file, options, adapter, callback) {
	if (attempt > options.retryAttempts) {
		return callback(Error('Unique filename could not be generated; Maximum attempts exceeded'));
	}
	options.generateFilename(file, attempt, function (err, filename) {
		if (err) return callback(err);
		adapter.fileExists(filename, function (err, exists) {
			if (err) return callback(err);
			if (exists) return retryFilename(attempt + 1, file, options, adapter, callback);
			callback(null, filename);
		});
	});
}

Storage.prototype.getFilename = function (file, callback) {
	var options = this.options;
	var adapter = this.adapter;
	switch (options.whenExists) {
		case 'overwrite':
			options.generateFilename(file, 0, callback);
			break;
		case 'error':
			options.generateFilename(file, 0, function (err, filename) {
				if (err) return callback(err);
				adapter.fileExists(filename, function (err, result) {
					if (err) return callback(err);
					if (result === true) return callback(Error('File already exists'));
					callback(null, filename);
				});
			});
			break;
		case 'retry':
			retryFilename(0, file, options, adapter, callback);
			break;
	}
};

// Helper to fill out missing fields in the file object
function normalizeFile (file, schema, callback) {
	// Detect required information if it wasn't provided by inspecting the
	// file stored at file.path
	if (schema.mimetype && !file.mimetype) file.mimetype = mime(file.path);

	if (!file.originalname) {
		file.originalname = file.name
			|| (file.path) ? path.parse(file.path).base : 'unnamedfile';
	}

	if (schema.size && !file.size) {
		getSize(file, function (err, size) {
			if (err) return callback(err);
			file.size = size;
			callback(null, file);
		});
	} else callback(null, file);
}

/**
	Uploads a new file via the adapter, then decorates the result with the
	public url for the file. The result is what is saved back to the field.
*/
Storage.prototype.uploadFile = function (file, callback) {
	var self = this;

	// The path to the file is required
	if (!file.path) return callback(Error('Cannot upload file - No source path'));

	normalizeFile(file, this.schema, function (err, file) {
		if (err) return callback(err);
		self.getFilename(file, function (err, filename) {
			if (err) return callback(err);

			self.adapter.uploadFile(filename, file, function (err, result) {
				if (err) return callback(err);
				result.url = self.adapter.getFileURL(result);

				callback(null, result);
			});
		});
	});
};

/**
	Removes a stored file by passing the field value to the adapter.
*/
Storage.prototype.removeFile = function (value, callback) {
	this.adapter.removeFile(value, callback);
};

/*
	Built-in Adapters
*/
Storage.Adapters = {};
Storage.Adapters.FS = require('./adapters/fs');
Storage.nameFunctions = nameFunctions;

module.exports = Storage;
<|endoftext|>


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

var linter = require('./tldr-lint.js');
var fs = require('fs');
var path = require('path');
var cli = module.exports;

cli.writeErrors = function(file, linterResult, args) {
  linterResult.errors.forEach(function(error) {
    console.error(file + ':' + (error.locinfo.first_line ||
                                error.locinfo.last_line - 1) +
                  ': ' + error.code + ' ' + error.description);
  });
  if (args.format) {
    if (!linterResult.success)
      console.error('Refraining from formatting because of fatal error');
    else {
      var formattedPage = linterResult.formatted;
      if (args.output) {
        var err = fs.writeFileSync(args.output, formattedPage, 'utf8');
        if (err) throw err;
      } else {
        console.log(formattedPage);
      }
    }
  }
};

cli.processFile = function(file, args) {
  var page = fs.readFileSync(file, 'utf8');
  var linterResult = linter.process(page, args.verbose, args.format);
  cli.writeErrors(file, linterResult, args);
  return linterResult;
};

cli.processDirectory = function(dir, args) {
  var files = fs.readdirSync(dir);
  var stats;
  var result = {
    success: true,
    errors: []
  };
  files.forEach(function(file) {
    file = path.join(dir, file);
    try {
      stats = fs.statSync(file);
    } catch(err) {
      console.error(err.toString());
      process.exit(1);
    }
    if (stats.isFile()) {
      // Only treat files ending in .md
      if (!file.match(/\.md$/)) return;
      var linterResult = cli.processFile(file, args);
      result.success &= linterResult.success;
      result.errors = result.errors.concat(linterResult.errors);
    } else {
      var aggregateResult = cli.processDirectory(file, args);
      result.success &= aggregateResult.success;
      result.errors = result.errors.concat(aggregateResult.errors);
    }
  });
  return result;
};

cli.process = function(args) {
  if (args.args.length != 1) {
    args.help();
  }
  if (args.output && !args.format) {
    console.error('--output only makes sense when used with --format');
    process.exit(1);
  }
  var file = args.args[0];
  try {
    var stats = fs.statSync(file);
  } catch(err) {
    console.error(err.toString());
    process.exit(1);
  }
  var isdir = stats.isDirectory();
  if (args.output && isdir) {
    console.error('--output only makes sense when used with a file');
  }
  var result;
  if (!isdir) {
    result = cli.processFile(file, args);
  } else {
    result = cli.processDirectory(file, args);
  }
  if (!result.success || result.errors.length >= 1) return process.exit(1);
};

if (require.main === module) {
  var args = require('commander');
  args
    .version(require('../package.json').version)
    .arguments('<file|dir>')
    .option('-f, --format', 'also attempt formatting (to stdout, or as specified by -o)')
    .option('-o, --output <file>', 'output to formatted file')
    .option('-v, --verbose', 'print verbose output')
    .parse(process.argv);

  cli.process(args);
  process.exit(0);
}
<commit_msg>Added inplace formatting<commit_after>#!/usr/bin/env node

var linter = require('./tldr-lint.js');
var fs = require('fs');
var path = require('path');
var cli = module.exports;

cli.writeErrors = function(file, linterResult, args) {
  linterResult.errors.forEach(function(error) {
    console.error(file + ':' + (error.locinfo.first_line ||
                                error.locinfo.last_line - 1) +
                  ': ' + error.code + ' ' + error.description);
  });
  if (args.format) {
    if (!linterResult.success)
      console.error('Refraining from formatting because of fatal error');
    else {
      var formattedPage = linterResult.formatted;
      if (args.output) {
        var err = fs.writeFileSync(args.output, formattedPage, 'utf8');
        if (err) throw err;
      } else if (args.inPlace) {
        var err = fs.writeFileSync(file, formattedPage, 'utf8');
        if (err) throw err;
      } else {
        console.log(formattedPage);
      }
    }
  }
};

cli.processFile = function(file, args) {
  var page = fs.readFileSync(file, 'utf8');
  var linterResult = linter.process(page, args.verbose, args.format);
  cli.writeErrors(file, linterResult, args);
  return linterResult;
};

cli.processDirectory = function(dir, args) {
  var files = fs.readdirSync(dir);
  var stats;
  var result = {
    success: true,
    errors: []
  };
  files.forEach(function(file) {
    file = path.join(dir, file);
    try {
      stats = fs.statSync(file);
    } catch(err) {
      console.error(err.toString());
      process.exit(1);
    }
    if (stats.isFile()) {
      // Only treat files ending in .md
      if (!file.match(/\.md$/)) return;
      var linterResult = cli.processFile(file, args);
      result.success &= linterResult.success;
      result.errors = result.errors.concat(linterResult.errors);
    } else {
      var aggregateResult = cli.processDirectory(file, args);
      result.success &= aggregateResult.success;
      result.errors = result.errors.concat(aggregateResult.errors);
    }
  });
  return result;
};

cli.process = function(args) {
  if (args.args.length != 1) {
    args.help();
  }
  if (args.output && !args.format) {
    console.error('--output only makes sense when used with --format');
    process.exit(1);
  }
  var file = args.args[0];
  try {
    var stats = fs.statSync(file);
  } catch(err) {
    console.error(err.toString());
    process.exit(1);
  }
  var isdir = stats.isDirectory();
  if (args.output && isdir) {
    console.error('--output only makes sense when used with a file');
  }
  var result;
  if (!isdir) {
    result = cli.processFile(file, args);
  } else {
    result = cli.processDirectory(file, args);
  }
  if (!result.success || result.errors.length >= 1) return process.exit(1);
};

if (require.main === module) {
  var args = require('commander');
  args
    .version(require('../package.json').version)
    .arguments('<file|dir>')
    .option('-f, --format', 'also attempt formatting (to stdout, or as specified by -o)')
    .option('-o, --output <file>', 'output to formatted file')
    .option('-i, --in-place', 'formats in place')
    .option('-v, --verbose', 'print verbose output')
    .parse(process.argv);

  cli.process(args);
  process.exit(0);
}
<|endoftext|>


<commit_before>//
// DUST MODIFICATIONS
//

var dust = require('dustjs-linkedin');

// if dust cannot find the specified template in dust.cache, this function gets called.
dust.onLoad = function(name, callback) {
	// callback is a function provided by dust.
	// run console.log(callback.toString()) if you are interested in it's contents.
	function notFound() {
		callback(new Error('Template Not Found: ' + name));
	}
	// attempt to load the template using the templates route in Express.
	$.ajax({
		method: 'GET',
		url: '/templates/' + name,
		dataType: 'json',
		success: function(res) {
			var arr = [];
			// the templates route does not only return the specified temlate, but also
			// all templates it depends on. They are placed in the res.compiled array.
			if(res.compiled.length > 0) {
				for(var i = 0; i < res.compiled.length; i++) {
					arr.push(dust.loadSource(res.compiled[i]));
				}
				// the specified template will always be the first item in the res.compiled array.
				callback(null, res.compiled[0]);
			} else {
				notFound();
			}
		},
		error: notFound
	});
};
<commit_msg>Fixed so only one request is made per template. If a template is already loading, simply wait until the first request finishes.<commit_after>//
// DUST MODIFICATIONS
//

var dust = require('dustjs-linkedin');

dust.loading = {};

// if dust cannot find the specified template in dust.cache, this function gets called.
dust.onLoad = function(name, callback) {
	// callback is a function provided by dust.
	// run console.log(callback.toString()) if you are interested in it's contents.
	function notFound() {
		delete dust.loading[name];
		callback(new Error('Template Not Found: ' + name));
	}
	if(dust.loading[name]) {
		dust.loading[name].push(callback);
		return;
	} else {
		var callbacks = dust.loading[name] = [ callback ];
	}

	// attempt to load the template using the templates route in Express.
	$.ajax({
		method: 'GET',
		url: '/templates/' + name,
		dataType: 'json',
		success: function(res) {
			var arr = [];
			// the templates route does not only return the specified temlate, but also
			// all templates it depends on. They are placed in the res.compiled array.
			if(res.compiled.length > 0) {
				res.compiled.forEach(dust.loadSource);

				// the specified template will always be the first item in the res.compiled array.
				callbacks.forEach(function(cb) {
					cb(null, res.compiled[0]);
				});

				delete dust.loading[name];
				//callback(null, res.compiled[0]);
			} else {
				notFound();
			}
		},
		error: notFound
	});
};
<|endoftext|>


<commit_before>var util = require('util'),
	Renderer = require('./Renderer').Renderer;

var HTTP_STATUS = exports.HTTP_STATUS = [
		{"code": 200, "name": "OK", "headers_required": [], "function_required": [''] },
		{"code": 201, "name": "Created", "headers_required": [], "function_required": [''] },
		{"code": 202, "name": "Accepted", "headers_required": [], "function_required": [''] },
		{"code": 204, "name": "No Content", "headers_required": [], "function_required": [''] },
		{"code": 205, "name": "Reset Content", "headers_required": [], "function_required": [''] },
		{"code": 301, "name": "Moved Permanently", "headers_required": ['Location'], "function_required": [''] },
		{"code": 302, "name": "Found", "headers_required": ['Location'], "function_required": ['_302Settings'] },
		{"code": 303, "name": "See Other", "headers_required": ['Location'], "function_required": [''] },
		{"code": 304, "name": "Not Modified", "headers_required": ['Etag', 'Last-Modified'], "function_required": [''] },
		{"code": 305, "name": "Use Proxy", "headers_required": ['Location'], "function_required": [''] },
		{"code": 307, "name": "Temporary Redirect", "headers_required": ['Location'], "function_required": [''] },
		{"code": 400, "name": "Bad Request", "headers_required": [], "function_required": [''] },
		{"code": 401, "name": "Unauthorized", "headers_required": ['WWW-Authenticate'], "function_required": [''] },
		{"code": 403, "name": "Forbidden", "headers_required": [''], "function_required": [''] },
		{"code": 404, "name": "Not Found", "headers_required": [''], "function_required": [''] },
		{"code": 405, "name": "Method Not Allowed", "headers_required": ['Allow'], "function_required": [''] },
		{"code": 406, "name": "Not Acceptable", "headers_required": [], "function_required": [''] },
		{"code": 407, "name": "Proxy Authentication Required", "headers_required": [''], "function_required": [''] },
		{"code": 408, "name": "Request Time Out", "headers_required": [''], "function_required": [''] },
		{"code": 409, "name": "Conflict", "headers_required": [], "function_required": [''] },
		{"code": 410, "name": "Gone", "headers_required": [], "function_required": [''] },
		{"code": 411, "name": "Length Required", "headers_required": [], "function_required": [''] },
		{"code": 413, "name": "Request Entity Too Large", "headers_required": [], "function_required": ['closeConnection'] },
		{"code": 415, "name": "Unsupported Media Type", "headers_required": [], "function_required": [''] },
		{"code": 500, "name": "Internal Server Error", "headers_required": [], "function_required": [''] },
		{"code": 501, "name": "Not Implemented", "headers_required": [], "function_required": [''] },
		{"code": 502, "name": "Bad Gateway", "headers_required": [], "function_required": [''] },
		{"code": 503, "name": "Service Unavailable", "headers_required": [], "function_required": [''] },
		{"code": 504, "name": "Gateway Time Out", "headers_required": [], "function_required": [''] },
		{"code": 505, "name": "HTTP Version not supported", "headers_required": [], "function_required": [''] },
];

var print_response = false;

exports.printResponse = function (print) {
	print_response = print;
	return this;
};

function HttpResponse(res, cb) {
	this._response = res;
	this._status = null;
	this._headers = [];
	this._body = null;
	this._content_type = null;
	this._committed = false;
	cb(this);
}

util.inherits(HttpResponse, Renderer);

HTTP_STATUS.forEach(generateHttpResponse);

function generateHttpResponse(status) {
	var code = status.code;
		name = status.name.replace(/\s/g, '');

	HttpResponse.prototype[name] = function () {
		this._status = code;

		for(var i=0; i<status.headers_required.length; i++)
			if(arguments[i]) this.appendHeader(status.headers_required[i], arguments[i]);
		for(var i=0; i<status.function_required.length; i++)
			if(this[status.function_required[i]]) this[status.function_required[i]]();

		return this;
	};
}
//------------------------------------- APPLICATION FUNCTION

HttpResponse.prototype.setStatus = function (status) {
	this._status = status;
	return this;
};

HttpResponse.prototype.setLocale = function (locale) {
	if(typeof locale === 'string') this._response_locale = [ locale ];
	else this._response_locale = locale;
	return this;
};

HttpResponse.prototype.closeConnection = function () {
	this._headers.push(['Connection', 'close']);
	return this;
};

HttpResponse.prototype.contentType = function (contentType) {
	if(contentType.split(';').length === 1) this._content_type = contentType + '; charset=UTF-8';
	else this._content_type = contentType;
	return this;
};

HttpResponse.prototype.contentDisposition = function (contentDisposition) {
	this._content_disposition = contentDisposition;
	return this;
};

HttpResponse.prototype.cacheFor = function (etag, last_modified) {
	if(etag) this.appendHeader('Etag', etag);
	if(last_modified) this.appendHeader('Last-Modified', last_modified);
	return this;
};

HttpResponse.prototype.noStoreCache = function () {
	this.appendHeader('Cache-Control', 'no-store');
	this.appendHeader('Pragma', 'no-cache');
	return this;
};

HttpResponse.prototype.json = function(json) {
	this._body = new Buffer(JSON.stringify(json), 'utf8');
	return this.contentType('application/json; charset=UTF-8');
};

HttpResponse.prototype.text = function(text) {
	this._body = new Buffer(text, 'utf8');
	return this.contentType('text/plain; charset=UTF-8');
};

HttpResponse.prototype.addCookie = function (name, value, expires, http_only, secure, domain, path) {
	var cookie = undefined;

	if(typeof name === 'object') {
		cookie = [name.name + '=' + name.value];
		if(name.expires != undefined) cookie.push('Expires=' + name.expires);
		if(name.http_only) cookie.push('HttpOnly');
		if(name.secure) cookie.push('Secure');
		if(name.domain != undefined) cookie.push('Domain=' + name.domain);
		if(name.path != undefined) cookie.push('Path=' + name.path);
	} else {
		cookie = [name + '=' + value];
		if(expires != undefined) cookie.push('Expires=' + expires);
		if(http_only) cookie.push('HttpOnly');
		if(secure) cookie.push('Secure');
		if(domain != undefined) cookie.push('Domain=' + domain);
		if(path != undefined) cookie.push('Path=' + path);
	}

	return this.appendHeader('Set-Cookie', cookie.join(';'));
};

HttpResponse.prototype.error = function (err) {
	this.InternalServerError();
	global && global.gozy && global.gozy.error && global.gozy.error(err);
	return this.commit();
};

//------------------------------------- RAW FUNCTION

HttpResponse.prototype.commit = function () {
	if(this._committed) return;

	if(this._content_type) this.appendHeader("Content-Type", this._content_type);
	else this.appendHeader("Content-Type", "text/plain; charset=UTF-8");

	if(this._content_disposition) this.appendHeader("Content-Disposition", this._content_disposition);

	if(this._body) this.appendHeader("Content-Length", this._body.length);
	else this.appendHeader("Content-Length", 0);

	if(!this._status) {
		global.gozy.error('Response status is not set. Response as 500');
		this._status = 500;
	}

	this._response.writeHead(this._status, this._headers);
	if(this._body) this._response.write(this._body);
	this._response.end();

	if(print_response) global.gozy.debug('printing response...\n----------- RESPONSE BEGIN -----------\n' + this.toString() + '------------ RESPONSE END ------------');
	this._committed = true;
	return this;
};

HttpResponse.prototype.appendHeader = function (name, value) {
	this._headers.push([name, value]);
	return this;
};

HttpResponse.prototype.body = function(body) {
	if(Buffer.isBuffer(body)) this._body = body;
	else this._body = new Buffer(body);
	return this;
};

//------------------------------------- UTILITIES

HttpResponse.prototype.toString = function () {
	return '[HTTP_RESPONSE_OBJECT]';
	var str = [];
	str.push('HTTP/1.1 ' + this._status + ' ' + stringifyStatus(this._status));
	for(var i=0; i<this._headers.length; i++)
		str.push(this._headers[i][0] + ': ' + this._headers[i][1]);
	str.push('');
	/*if(this._body)
		str.push(this._body);*/
	return str.join('\n');
};

HttpResponse.prototype._302Settings = function () {
	var _url;
	for(var i=0; i<this._headers.length; i++) {
		if(this._headers[i][0] == 'Location') {
			_url = this._headers[i][1];
			break;
		}
	}
	_url = _url || '/';

	this.contentType('text/html; charset=UTF-8');
	this.body('
Found. Redirecting to ' + _url + '
');
	/*this.contentType('text/plain');
	this.body('Found. Redirecting to ' + _url);*/
};

function stringifyStatus(code) {
	for(var i=0; i<HTTP_STATUS.length; i++)
		if(code === HTTP_STATUS[i].code)
			return HTTP_STATUS[i].name;
}

exports.HttpResponse = HttpResponse;<commit_msg>Change renderer name<commit_after>var util = require('util'),
	Renderer = require('./renderer').Renderer;

var HTTP_STATUS = exports.HTTP_STATUS = [
		{"code": 200, "name": "OK", "headers_required": [], "function_required": [''] },
		{"code": 201, "name": "Created", "headers_required": [], "function_required": [''] },
		{"code": 202, "name": "Accepted", "headers_required": [], "function_required": [''] },
		{"code": 204, "name": "No Content", "headers_required": [], "function_required": [''] },
		{"code": 205, "name": "Reset Content", "headers_required": [], "function_required": [''] },
		{"code": 301, "name": "Moved Permanently", "headers_required": ['Location'], "function_required": [''] },
		{"code": 302, "name": "Found", "headers_required": ['Location'], "function_required": ['_302Settings'] },
		{"code": 303, "name": "See Other", "headers_required": ['Location'], "function_required": [''] },
		{"code": 304, "name": "Not Modified", "headers_required": ['Etag', 'Last-Modified'], "function_required": [''] },
		{"code": 305, "name": "Use Proxy", "headers_required": ['Location'], "function_required": [''] },
		{"code": 307, "name": "Temporary Redirect", "headers_required": ['Location'], "function_required": [''] },
		{"code": 400, "name": "Bad Request", "headers_required": [], "function_required": [''] },
		{"code": 401, "name": "Unauthorized", "headers_required": ['WWW-Authenticate'], "function_required": [''] },
		{"code": 403, "name": "Forbidden", "headers_required": [''], "function_required": [''] },
		{"code": 404, "name": "Not Found", "headers_required": [''], "function_required": [''] },
		{"code": 405, "name": "Method Not Allowed", "headers_required": ['Allow'], "function_required": [''] },
		{"code": 406, "name": "Not Acceptable", "headers_required": [], "function_required": [''] },
		{"code": 407, "name": "Proxy Authentication Required", "headers_required": [''], "function_required": [''] },
		{"code": 408, "name": "Request Time Out", "headers_required": [''], "function_required": [''] },
		{"code": 409, "name": "Conflict", "headers_required": [], "function_required": [''] },
		{"code": 410, "name": "Gone", "headers_required": [], "function_required": [''] },
		{"code": 411, "name": "Length Required", "headers_required": [], "function_required": [''] },
		{"code": 413, "name": "Request Entity Too Large", "headers_required": [], "function_required": ['closeConnection'] },
		{"code": 415, "name": "Unsupported Media Type", "headers_required": [], "function_required": [''] },
		{"code": 500, "name": "Internal Server Error", "headers_required": [], "function_required": [''] },
		{"code": 501, "name": "Not Implemented", "headers_required": [], "function_required": [''] },
		{"code": 502, "name": "Bad Gateway", "headers_required": [], "function_required": [''] },
		{"code": 503, "name": "Service Unavailable", "headers_required": [], "function_required": [''] },
		{"code": 504, "name": "Gateway Time Out", "headers_required": [], "function_required": [''] },
		{"code": 505, "name": "HTTP Version not supported", "headers_required": [], "function_required": [''] },
];

var print_response = false;

exports.printResponse = function (print) {
	print_response = print;
	return this;
};

function HttpResponse(res, cb) {
	this._response = res;
	this._status = null;
	this._headers = [];
	this._body = null;
	this._content_type = null;
	this._committed = false;
	cb(this);
}

util.inherits(HttpResponse, Renderer);

HTTP_STATUS.forEach(generateHttpResponse);

function generateHttpResponse(status) {
	var code = status.code;
		name = status.name.replace(/\s/g, '');

	HttpResponse.prototype[name] = function () {
		this._status = code;

		for(var i=0; i<status.headers_required.length; i++)
			if(arguments[i]) this.appendHeader(status.headers_required[i], arguments[i]);
		for(var i=0; i<status.function_required.length; i++)
			if(this[status.function_required[i]]) this[status.function_required[i]]();

		return this;
	};
}
//------------------------------------- APPLICATION FUNCTION

HttpResponse.prototype.setStatus = function (status) {
	this._status = status;
	return this;
};

HttpResponse.prototype.setLocale = function (locale) {
	if(typeof locale === 'string') this._response_locale = [ locale ];
	else this._response_locale = locale;
	return this;
};

HttpResponse.prototype.closeConnection = function () {
	this._headers.push(['Connection', 'close']);
	return this;
};

HttpResponse.prototype.contentType = function (contentType) {
	if(contentType.split(';').length === 1) this._content_type = contentType + '; charset=UTF-8';
	else this._content_type = contentType;
	return this;
};

HttpResponse.prototype.contentDisposition = function (contentDisposition) {
	this._content_disposition = contentDisposition;
	return this;
};

HttpResponse.prototype.cacheFor = function (etag, last_modified) {
	if(etag) this.appendHeader('Etag', etag);
	if(last_modified) this.appendHeader('Last-Modified', last_modified);
	return this;
};

HttpResponse.prototype.noStoreCache = function () {
	this.appendHeader('Cache-Control', 'no-store');
	this.appendHeader('Pragma', 'no-cache');
	return this;
};

HttpResponse.prototype.json = function(json) {
	this._body = new Buffer(JSON.stringify(json), 'utf8');
	return this.contentType('application/json; charset=UTF-8');
};

HttpResponse.prototype.text = function(text) {
	this._body = new Buffer(text, 'utf8');
	return this.contentType('text/plain; charset=UTF-8');
};

HttpResponse.prototype.addCookie = function (name, value, expires, http_only, secure, domain, path) {
	var cookie = undefined;

	if(typeof name === 'object') {
		cookie = [name.name + '=' + name.value];
		if(name.expires != undefined) cookie.push('Expires=' + name.expires);
		if(name.http_only) cookie.push('HttpOnly');
		if(name.secure) cookie.push('Secure');
		if(name.domain != undefined) cookie.push('Domain=' + name.domain);
		if(name.path != undefined) cookie.push('Path=' + name.path);
	} else {
		cookie = [name + '=' + value];
		if(expires != undefined) cookie.push('Expires=' + expires);
		if(http_only) cookie.push('HttpOnly');
		if(secure) cookie.push('Secure');
		if(domain != undefined) cookie.push('Domain=' + domain);
		if(path != undefined) cookie.push('Path=' + path);
	}

	return this.appendHeader('Set-Cookie', cookie.join(';'));
};

HttpResponse.prototype.error = function (err) {
	this.InternalServerError();
	global && global.gozy && global.gozy.error && global.gozy.error(err);
	return this.commit();
};

//------------------------------------- RAW FUNCTION

HttpResponse.prototype.commit = function () {
	if(this._committed) return;

	if(this._content_type) this.appendHeader("Content-Type", this._content_type);
	else this.appendHeader("Content-Type", "text/plain; charset=UTF-8");

	if(this._content_disposition) this.appendHeader("Content-Disposition", this._content_disposition);

	if(this._body) this.appendHeader("Content-Length", this._body.length);
	else this.appendHeader("Content-Length", 0);

	if(!this._status) {
		global.gozy.error('Response status is not set. Response as 500');
		this._status = 500;
	}

	this._response.writeHead(this._status, this._headers);
	if(this._body) this._response.write(this._body);
	this._response.end();

	if(print_response) global.gozy.debug('printing response...\n----------- RESPONSE BEGIN -----------\n' + this.toString() + '------------ RESPONSE END ------------');
	this._committed = true;
	return this;
};

HttpResponse.prototype.appendHeader = function (name, value) {
	this._headers.push([name, value]);
	return this;
};

HttpResponse.prototype.body = function(body) {
	if(Buffer.isBuffer(body)) this._body = body;
	else this._body = new Buffer(body);
	return this;
};

//------------------------------------- UTILITIES

HttpResponse.prototype.toString = function () {
	return '[HTTP_RESPONSE_OBJECT]';
	var str = [];
	str.push('HTTP/1.1 ' + this._status + ' ' + stringifyStatus(this._status));
	for(var i=0; i<this._headers.length; i++)
		str.push(this._headers[i][0] + ': ' + this._headers[i][1]);
	str.push('');
	/*if(this._body)
		str.push(this._body);*/
	return str.join('\n');
};

HttpResponse.prototype._302Settings = function () {
	var _url;
	for(var i=0; i<this._headers.length; i++) {
		if(this._headers[i][0] == 'Location') {
			_url = this._headers[i][1];
			break;
		}
	}
	_url = _url || '/';

	this.contentType('text/html; charset=UTF-8');
	this.body('
Found. Redirecting to ' + _url + '
');
	/*this.contentType('text/plain');
	this.body('Found. Redirecting to ' + _url);*/
};

function stringifyStatus(code) {
	for(var i=0; i<HTTP_STATUS.length; i++)
		if(code === HTTP_STATUS[i].code)
			return HTTP_STATUS[i].name;
}

exports.HttpResponse = HttpResponse;<|endoftext|>


<commit_before>import os from 'os';
import mongo from '../mongo';
import redis from '../redis';
import config from '../../config';
import NR from 'node-resque';
import tasks from './tasks';

export default {
    worker: null,
    /* Start a standalone worker */
    start: () => {
        mongo.connect();
        redis.connect(config.redis, (redis) => {
            let workerConfig = {
                connection: {redis: redis},
                looping: true,
                timeout: 5000,
                queues: ['*'],
                name: os.hostname() + ':' + process.pid
            };

            let worker = new NR.worker(workerConfig, tasks);

            worker.connect(() => {
                worker.workerCleanup();
                worker.start();
            });
        });
    }
}
<commit_msg>Add missing semicolon for linting.<commit_after>import os from 'os';
import mongo from '../mongo';
import redis from '../redis';
import config from '../../config';
import NR from 'node-resque';
import tasks from './tasks';

export default {
    worker: null,
    /* Start a standalone worker */
    start: () => {
        mongo.connect();
        redis.connect(config.redis, (redis) => {
            let workerConfig = {
                connection: {redis: redis},
                looping: true,
                timeout: 5000,
                queues: ['*'],
                name: os.hostname() + ':' + process.pid
            };

            let worker = new NR.worker(workerConfig, tasks);

            worker.connect(() => {
                worker.workerCleanup();
                worker.start();
            });
        });
    }
};
<|endoftext|>


<commit_before>Vps.Form.ComboBox = Ext.extend(Ext.form.ComboBox,
{
    displayField: 'name',
    valueField: 'id',

    initComponent : function()
    {
        this.addEvents({
            changevalue : true
        });
        if(!this.store) {
            throw "no store set";
        }

        //store klonen (um nicht this.initalConfig.store zu ändern)
        var store = {};
        for (var i in this.store) {
            store[i] = this.store[i];
        }
        delete this.store;
        if (store.data) {
            store = Ext.applyIf(store, {
                fields: ['id', 'name'],
                id: 'id'
            });
            this.store = new Ext.data.SimpleStore(store);
			this.displayField = store.fields[1];
            this.mode = 'local';
        } else {
            if (store.reader) {
                if (store.reader.type && Ext.data[store.reader.type]) {
                    var readerType = Ext.data[store.reader.type];
                    delete store.reader.type;
                } else if (store.reader.type) {
                    try {
                        var readerType = eval(store.reader.type);
                    } catch(e) {
                        throw "invalid readerType: "+store.reader.type;
                    }
                    delete store.reader.type;
                } else {
                    var readerType = Ext.data.JsonReader;
                }
                if (!store.reader.rows) throw "no rows defined, required if reader doesn't this through meta data";
                var rows = store.reader.rows;
                delete store.reader.rows;
                var reader = new readerType(store.reader, rows);
            } else {
                var reader = new Ext.data.JsonReader(); //reader thisuriert sich autom. durch meta-daten
            }
            if (store.proxy) {
                if (store.proxy.type && Ext.data[store.proxy.type]) {
                    var proxyType = Ext.data[store.proxy.type];
                    delete store.proxy.type;
                } else if (store.proxy.type) {
                    try {
                        var proxyType = eval(store.proxy.type);
                    } catch(e) {
                        throw "invalid proxyType: "+store.proxy.type;
                    }
                    delete store.proxy.type;
                } else {
                    var proxyType = Ext.data.HttpProxy;
                }
                var proxy = new proxyType(store.proxy);
            } else if (store.data) {
                var proxy = new Ext.data.MemoryProxy(store.data);
            } else {
                var proxy = new Ext.data.HttpProxy(store);
            }
            if (store.type && Ext.data[store.type]) {
                this.store = new Ext.data[store.type]({
                    proxy: proxy,
                    reader: reader
                });
            } else if (store.type) {
                try {
                    var storeType = eval(store.type)
                } catch(e) {
                    throw "invalid storeType: "+store.type;
                }
                this.store = new storeType({
                    proxy: proxy,
                    reader: reader
                });
            } else {
                this.store = new Ext.data.Store({
                    proxy: proxy,
                    reader: reader
                });
            }
        }

        if (this.addDialog) {
            var d = Vps.Auto.Form.Window;
            if (this.addDialog.type) {
                try {
                    d = eval(this.addDialog.type);
                } catch (e) {
                    throw new Error("Invalid addDialog \'"+this.addDialog.type+"': "+e);
                }
            }
            this.addDialog = new d(this.addDialog);
            this.addDialog.on('datachange', function(result) {
                if (result.data.addedId) {
                    //neuen Eintrag auswählen
                    this.setValue(result.data.addedId);
                }
            }, this);
        }

        if (this.showNoSelection) {
            if (!this.emptyText) {
                this.emptyText = '('+trlVps('no selection')+')';
            }
        }
        this.store.on('load', function() {
            this.addNoSelection();
        }, this);
        if (this.store.recordType) {
            this.addNoSelection();
        }

        Vps.Form.ComboBox.superclass.initComponent.call(this);
    },

    addNoSelection : function() {
        if (this.showNoSelection && this.store.find('id', '') == -1) {
            var data = {};
            data[this.displayField] = this.emptyText;
            data[this.valueField] = null;
            for (var i = 0; i < this.store.fields.keys.length; i++) {
                if (this.store.fields.keys[i] != this.displayField
                    && this.store.fields.keys[i] != this.valueField
                ) {
                    data[this.store.fields.keys[i]] = null;
                }
            }
            this.store.insert(0, new this.store.recordType(data));
        }
    },

    setValue : function(v)
    {
        if (v == '') v = null;
        if (v == this.emptyText) v = null;
        if (v && this.store.proxy && this.valueField && this.mode == 'remote') {
            //wenn proxy vorhanden können daten nachgeladen werden
            //also loading anzeigen (siehe setValue)
            this.valueNotFoundText = this.loadingText;
        } else {
            this.valueNotFoundText = '';
        }
        Vps.Form.ComboBox.superclass.setValue.apply(this, arguments);
        if (v && this.valueField
                && !this.findRecord(this.valueField, v) //record nicht gefunden
                && this.mode == 'remote'
                && this.store.proxy //proxy vorhanden (dh. daten können nachgeladen werden)
                ) {
            this.store.baseParams[this.queryParam] = v;
            this.store.load({
                params: this.getParams(v),
                callback: function(r, options, success) {
                    if (success && this.findRecord(this.valueField, this.value)) {
                        this.setValue(this.value);
                    }
                },
                scope: this
            });
        }
        this.fireEvent('changevalue', this.value);
    },

    onRender : function(ct, position)
    {
        Vps.Form.ComboBox.superclass.onRender.call(this, ct, position);
        if (this.addDialog) {
            var c = this.el.up('div.x-form-field-wrap').insertSibling({style: 'float: right'}, 'before');
            var button = new Ext.Button({
                renderTo: c,
                text: this.addDialog.text || trlVps('add new entry'),
                handler: function() {
                    this.addDialog.showAdd();
                },
                scope: this
            });
        }
    }

});
Ext.reg('combobox', Vps.Form.ComboBox);
<commit_msg>Endlich den bug gefixt (bzw. workaround) dass im FF wenn eine combobox ein einem tab ist die breite des dropdowns immer bei 70px war<commit_after>Vps.Form.ComboBox = Ext.extend(Ext.form.ComboBox,
{
    displayField: 'name',
    valueField: 'id',

    initComponent : function()
    {
        this.addEvents({
            changevalue : true
        });
        if(!this.store) {
            throw "no store set";
        }

        //store klonen (um nicht this.initalConfig.store zu ändern)
        var store = {};
        for (var i in this.store) {
            store[i] = this.store[i];
        }
        delete this.store;
        if (store.data) {
            store = Ext.applyIf(store, {
                fields: ['id', 'name'],
                id: 'id'
            });
            this.store = new Ext.data.SimpleStore(store);
			this.displayField = store.fields[1];
            this.mode = 'local';
        } else {
            if (store.reader) {
                if (store.reader.type && Ext.data[store.reader.type]) {
                    var readerType = Ext.data[store.reader.type];
                    delete store.reader.type;
                } else if (store.reader.type) {
                    try {
                        var readerType = eval(store.reader.type);
                    } catch(e) {
                        throw "invalid readerType: "+store.reader.type;
                    }
                    delete store.reader.type;
                } else {
                    var readerType = Ext.data.JsonReader;
                }
                if (!store.reader.rows) throw "no rows defined, required if reader doesn't this through meta data";
                var rows = store.reader.rows;
                delete store.reader.rows;
                var reader = new readerType(store.reader, rows);
            } else {
                var reader = new Ext.data.JsonReader(); //reader thisuriert sich autom. durch meta-daten
            }
            if (store.proxy) {
                if (store.proxy.type && Ext.data[store.proxy.type]) {
                    var proxyType = Ext.data[store.proxy.type];
                    delete store.proxy.type;
                } else if (store.proxy.type) {
                    try {
                        var proxyType = eval(store.proxy.type);
                    } catch(e) {
                        throw "invalid proxyType: "+store.proxy.type;
                    }
                    delete store.proxy.type;
                } else {
                    var proxyType = Ext.data.HttpProxy;
                }
                var proxy = new proxyType(store.proxy);
            } else if (store.data) {
                var proxy = new Ext.data.MemoryProxy(store.data);
            } else {
                var proxy = new Ext.data.HttpProxy(store);
            }
            if (store.type && Ext.data[store.type]) {
                this.store = new Ext.data[store.type]({
                    proxy: proxy,
                    reader: reader
                });
            } else if (store.type) {
                try {
                    var storeType = eval(store.type)
                } catch(e) {
                    throw "invalid storeType: "+store.type;
                }
                this.store = new storeType({
                    proxy: proxy,
                    reader: reader
                });
            } else {
                this.store = new Ext.data.Store({
                    proxy: proxy,
                    reader: reader
                });
            }
        }

        if (this.addDialog) {
            var d = Vps.Auto.Form.Window;
            if (this.addDialog.type) {
                try {
                    d = eval(this.addDialog.type);
                } catch (e) {
                    throw new Error("Invalid addDialog \'"+this.addDialog.type+"': "+e);
                }
            }
            this.addDialog = new d(this.addDialog);
            this.addDialog.on('datachange', function(result) {
                if (result.data.addedId) {
                    //neuen Eintrag auswählen
                    this.setValue(result.data.addedId);
                }
            }, this);
        }

        if (this.showNoSelection) {
            if (!this.emptyText) {
                this.emptyText = '('+trlVps('no selection')+')';
            }
        }
        this.store.on('load', function() {
            this.addNoSelection();
        }, this);
        if (this.store.recordType) {
            this.addNoSelection();
        }

        Vps.Form.ComboBox.superclass.initComponent.call(this);
    },

    initList : function(){
        if (!this.listWidth) {
            //fixt bug wenn combobox in einem tab ist
            //ext verwendet this.wrap.getWidth() was ja eingentlich korrekt ist
            //das funktioniert aber im FF da nicht
            this.listWidth = this.el.getWidth()+this.trigger.getWidth();
        }
        Vps.Form.ComboBox.superclass.initList.call(this);
    },

    addNoSelection : function() {
        if (this.showNoSelection && this.store.find('id', '') == -1) {
            var data = {};
            data[this.displayField] = this.emptyText;
            data[this.valueField] = null;
            for (var i = 0; i < this.store.fields.keys.length; i++) {
                if (this.store.fields.keys[i] != this.displayField
                    && this.store.fields.keys[i] != this.valueField
                ) {
                    data[this.store.fields.keys[i]] = null;
                }
            }
            this.store.insert(0, new this.store.recordType(data));
        }
    },

    setValue : function(v)
    {
        if (v == '') v = null;
        if (v == this.emptyText) v = null;
        if (v && this.store.proxy && this.valueField && this.mode == 'remote') {
            //wenn proxy vorhanden können daten nachgeladen werden
            //also loading anzeigen (siehe setValue)
            this.valueNotFoundText = this.loadingText;
        } else {
            this.valueNotFoundText = '';
        }
        Vps.Form.ComboBox.superclass.setValue.apply(this, arguments);
        if (v && this.valueField
                && !this.findRecord(this.valueField, v) //record nicht gefunden
                && this.mode == 'remote'
                && this.store.proxy //proxy vorhanden (dh. daten können nachgeladen werden)
                ) {
            this.store.baseParams[this.queryParam] = v;
            this.store.load({
                params: this.getParams(v),
                callback: function(r, options, success) {
                    if (success && this.findRecord(this.valueField, this.value)) {
                        this.setValue(this.value);
                    }
                },
                scope: this
            });
        }
        this.fireEvent('changevalue', this.value);
    },

    onRender : function(ct, position)
    {
        Vps.Form.ComboBox.superclass.onRender.call(this, ct, position);
        if (this.addDialog) {
            var c = this.el.up('div.x-form-field-wrap').insertSibling({style: 'float: right'}, 'before');
            var button = new Ext.Button({
                renderTo: c,
                text: this.addDialog.text || trlVps('add new entry'),
                handler: function() {
                    this.addDialog.showAdd();
                },
                scope: this
            });
        }
    }

});
Ext.reg('combobox', Vps.Form.ComboBox);
<|endoftext|>


<commit_before>/**
 * Created by CoolGuy on 2014/8/13.
 */
jQuery.fn.extend({
    addNumberStyle:function(){
        var _this = $(this);
        var start = 0;
        var total = Number(_this.text());
        var timeId = setInterval(function(){
            if(start < total){
                _this.text(start);
                start += parseInt(total/20);
            }else{
                _this.text(total);
                clearInterval(timeId);
                _this.addClass("animated pulse");
            }
        },100);
    }
});
$(function(){
    $(".jumbotron").addClass("animated slideInDown");
    $("#count").addNumberStyle();
});

<commit_msg>修正访问数小于20时不能够正常显示动画的问题（现在小于20 没有动画）<commit_after>/**
 * Created by CoolGuy on 2014/8/13.
 */
jQuery.fn.extend({
    addNumberStyle:function(){
    	var TOTALTIME = 20;
        var _this = $(this);
        var start = 0;
        var total = Number(_this.text());
        if (total < TOTALTIME) {
        	return;
        }
        var timeId = setInterval(function(){
            if(start < total){
                _this.text(start);
                start += parseInt(total/TOTALTIME);
            }else{
                _this.text(total);
                clearInterval(timeId);
                _this.addClass("animated pulse");
            }
        },100);
    }
});
$(function(){
    $(".jumbotron").addClass("animated slideInDown");
    $("#count").addNumberStyle();
});

<|endoftext|>


<commit_before>'use strict';

var number = Math.floor((Math.random() * 50) + 1);
console.log(number);
var turns = 4;
var answer = parseInt(prompt('Guess a number between 1 and 50'));

while (turns >= 0) {
  if(turns === 0){
    alert('Sorry you ran out of turns');
    break;
  } else if (answer > number) {
    turns--;
    //document.write('Sorry, too high! Try again.');
    var answer = parseInt(prompt('Your number was too high. Try again.'));
    continue;
  } else if (answer < number) {
    turns--;
    //document.write('So close, yet so far.');
    var answer = parseInt(prompt('Your number was too low. Try again'));
    continue;
  } else if (number === answer) {
    alert('Congratulations! You guessed the secret number');
    //document.write('Correct! You guessed the secret number! ' + number);
    break;
  }
}
<commit_msg>added answer at bottom of number game<commit_after>'use strict';

var number = Math.floor((Math.random() * 50) + 1);
console.log(number);
var turns = 4;
var answer = parseInt(prompt('Guess a number between 1 and 50'));

while (turns >= 0) {
  if(turns === 0){
    alert('Sorry you ran out of turns');
    break;
  } else if (answer > number) {
    turns--;
    //document.write('Sorry, too high! Try again.');
    var answer = parseInt(prompt('Your number was too high. Try again.'));
    continue;
  } else if (answer < number) {
    turns--;
    //document.write('So close, yet so far.');
    var answer = parseInt(prompt('Your number was too low. Try again'));
    continue;
  } else if (number === answer) {
    alert('Congratulations! You guessed the secret number');
    //document.write('Correct! You guessed the secret number! ' + number);
    break;
  }
}
document.write('The secret number was ' + number);
<|endoftext|>


<commit_before>var crypto = require('crypto');
var qs = require('querystring');

/*
 * RFC 3986 compliant encoding.
 * We require this for creating the base string used in calculating signatures.
 * qs.escape alone leaves the extra special characters untouched.
 */
function encodeParameter(param) {
    return qs.escape(param).replace(/[!'()*]/g, function(c) {
        return '%' + c.charCodeAt(0).toString(16).toUpperCase();
    });
};

function decodeParameter(param) {
    return qs.unescape(param);
};

function generateParameterString(params, ignore_sig) {
    var paramString = '';

    Object.keys(params).sort().forEach(function(key) {
        if (!ignore_sig || key !== 'oauth_signature') {
            var val = params[key];
            paramString += (paramString ? '&' : '');
            paramString += key + '=' + encodeParameter(val);
        }
    });
    return paramString;
};

function getOAuthHeader(params) {
    var header = '';

    for (var key in params) {
        header += (header ? ', ' : '') + key + '="' + encodeParameter(params[key])+'"';
    }
    return 'OAuth '+header;
};

function oauthSignature(signatureParams) {
    var params = signatureParams;

    var self = this;

    self.toForm = function() {
        return generateParameterString(params);
    };

    self.toHeader = function() {
        return getOAuthHeader(params);
    };

    self.toObject = function() {
        return params;
    }

    return self;
};

function oauther(config) {
    var self = this;
    this.consumer = config.consumer;
    this.token = config.token;
    this.signature_method = config.signature_method || 'HMAC-SHA1';
    this.nonce_length = config.nonce_length || 32;
    this.version = '1.0';

    function getAllParams(req) {
        var params = {};

        for (var key in req.body) {
            params[key] = req.body[key];
        }
        for (var key in req.query) {
            params[key] = req.query[key];
        }
        var oauthparams = getOAuthHeaderParams(req);
        for (var key in oauthparams) {
            params[key] = oauthparams[key];
        }

        return params;
    };

    function getOAuthHeaderParams(req) {
        var oauthParams = {};

        if (req.header) {
            if (req.header('Authorization') && req.header('Authorization').match(/^OAuth/)) {
                var params = req.header('Authorization').match(/(oauth_)([^=\s]+)="([^"]*)"([^,]*)/g);
                params.forEach(function(p) {
                    var kv = p.match(/([^=\s]+)="([^"]*)"/);
                    oauthParams[decodeParameter(kv[1])] = decodeParameter(kv[2].replace(/"/g,''));
                });
            }
        }
        return oauthParams;
    };

    function parseURL(req) {
        // If we are in the express context, we will have req.header as a function.
        // Express version 4 strips the port out of the req.hostname parameter incorrectly
        var host = typeof req.header === 'function' ? req.header('Host') : req.hostname;
        var port = req.port;
        var mount = req.baseUrl || '';
        var path = req.path || '';

        var baseURL = (req.protocol ? req.protocol : 'http') + '://' + host;

        if (port) {
            baseURL += ':' + port;
        }

        baseURL += mount + path;

        return baseURL;
    };

    function getNonce() {
        var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        var nonce = '';

        for (var i = 0; i < self.nonce_length; i++) {
            nonce += chars[parseInt(Math.random() * chars.length, 10)];
        }

        return nonce;
    }

    function generateSignature(method, baseURL, params) {
        params.oauth_signature_method = self.signature_method;
        params.oauth_consumer_key = self.consumer.key;
        params.oauth_nonce = getNonce();
        params.oauth_timestamp = parseInt((new Date().getTime()) / 1000);
        params.oauth_version = self.version;
        if (config.token) {
            params.oauth_token = config.token.key;
        }
        var signature = calculateSignature(method, baseURL, params);
        params.oauth_signature = signature;
        return params;
    };

    function calculateSignature(method, baseURL, params) {
        var baseString = method.toUpperCase() + '&' + encodeParameter(baseURL) + '&' +
            encodeParameter(generateParameterString(params, true));

        var csecret = config.consumer ? config.consumer.secret : '';
        var tsecret = config.token ? config.token.secret : '';

        var keyString = encodeParameter(csecret) + '&' + encodeParameter(tsecret);

        if (params['oauth_signature_method'] === 'PLAINTEXT') {
            return keyString;
        }
        else if (params['oauth_signature_method'] === 'HMAC-SHA1') {
            var hmac = crypto.createHmac('sha1', keyString);
            return hmac.update(baseString).digest('base64');
        }
        else {
            throw 'oauther :: Unsupported signature method : ' + params['oauth_signature_method'];
        }
    };

    /**
     * Sign OAuth request
     * @param  {Object} req data
     * {
     *     hostname : 'example.com',
     *     method : 'GET',
     *     path : '/path/to/url',
     *     port : 80, // optional
     *     protocol : 'http', // optional, default 'http'
     *     query, : { 'gaius' : 'baltar' },// optional, query string as json
     *     body : { 'kara' : 'thrace' } // optional, form encoded body as json
     * }
     * @return {Object} OAuth data object
     */
    this.sign = function(req) {
        var method = req.method;
        var baseURL = parseURL(req);
        var params = params = getAllParams(req);
        var oauthParams = generateSignature(method, baseURL, params);

        return oauthSignature(oauthParams);
    };

    /**
     * A http request to validate
     * @param  {Object} req request
     * @return {Object} true if the signature is valid
     */
    this.validate = function(req) {
        var method = req.method;
        var baseURL = parseURL(req);
        var params = getAllParams(req);

        if (!params['oauth_signature']) {
            return false;
        }

        var expect = calculateSignature(method, baseURL, params);

        return params['oauth_signature'] === expect;
    };

    return self;
};

module.exports = oauther;
<commit_msg>Remove unnecessary semicolons.<commit_after>var crypto = require('crypto');
var qs = require('querystring');

/*
 * RFC 3986 compliant encoding.
 * We require this for creating the base string used in calculating signatures.
 * qs.escape alone leaves the extra special characters untouched.
 */
function encodeParameter(param) {
    return qs.escape(param).replace(/[!'()*]/g, function(c) {
        return '%' + c.charCodeAt(0).toString(16).toUpperCase();
    });
}

function decodeParameter(param) {
    return qs.unescape(param);
}

function generateParameterString(params, ignore_sig) {
    var paramString = '';

    Object.keys(params).sort().forEach(function(key) {
        if (!ignore_sig || key !== 'oauth_signature') {
            var val = params[key];
            paramString += (paramString ? '&' : '');
            paramString += key + '=' + encodeParameter(val);
        }
    });
    return paramString;
}

function getOAuthHeader(params) {
    var header = '';

    for (var key in params) {
        header += (header ? ', ' : '') + key + '="' + encodeParameter(params[key])+'"';
    }
    return 'OAuth '+header;
}

function oauthSignature(signatureParams) {
    var params = signatureParams;

    var self = this;

    self.toForm = function() {
        return generateParameterString(params);
    };

    self.toHeader = function() {
        return getOAuthHeader(params);
    };

    self.toObject = function() {
        return params;
    }

    return self;
}

function oauther(config) {
    var self = this;
    this.consumer = config.consumer;
    this.token = config.token;
    this.signature_method = config.signature_method || 'HMAC-SHA1';
    this.nonce_length = config.nonce_length || 32;
    this.version = '1.0';

    function getAllParams(req) {
        var params = {};

        for (var key in req.body) {
            params[key] = req.body[key];
        }
        for (var key in req.query) {
            params[key] = req.query[key];
        }
        var oauthparams = getOAuthHeaderParams(req);
        for (var key in oauthparams) {
            params[key] = oauthparams[key];
        }

        return params;
    }

    function getOAuthHeaderParams(req) {
        var oauthParams = {};

        if (req.header) {
            if (req.header('Authorization') && req.header('Authorization').match(/^OAuth/)) {
                var params = req.header('Authorization').match(/(oauth_)([^=\s]+)="([^"]*)"([^,]*)/g);
                params.forEach(function(p) {
                    var kv = p.match(/([^=\s]+)="([^"]*)"/);
                    oauthParams[decodeParameter(kv[1])] = decodeParameter(kv[2].replace(/"/g,''));
                });
            }
        }
        return oauthParams;
    }

    function parseURL(req) {
        // If we are in the express context, we will have req.header as a function.
        // Express version 4 strips the port out of the req.hostname parameter incorrectly
        var host = typeof req.header === 'function' ? req.header('Host') : req.hostname;
        var port = req.port;
        var mount = req.baseUrl || '';
        var path = req.path || '';

        var baseURL = (req.protocol ? req.protocol : 'http') + '://' + host;

        if (port) {
            baseURL += ':' + port;
        }

        baseURL += mount + path;

        return baseURL;
    }

    function getNonce() {
        var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        var nonce = '';

        for (var i = 0; i < self.nonce_length; i++) {
            nonce += chars[parseInt(Math.random() * chars.length, 10)];
        }

        return nonce;
    }

    function generateSignature(method, baseURL, params) {
        params.oauth_signature_method = self.signature_method;
        params.oauth_consumer_key = self.consumer.key;
        params.oauth_nonce = getNonce();
        params.oauth_timestamp = parseInt((new Date().getTime()) / 1000);
        params.oauth_version = self.version;
        if (config.token) {
            params.oauth_token = config.token.key;
        }
        var signature = calculateSignature(method, baseURL, params);
        params.oauth_signature = signature;
        return params;
    }

    function calculateSignature(method, baseURL, params) {
        var baseString = method.toUpperCase() + '&' + encodeParameter(baseURL) + '&' +
            encodeParameter(generateParameterString(params, true));

        var csecret = config.consumer ? config.consumer.secret : '';
        var tsecret = config.token ? config.token.secret : '';

        var keyString = encodeParameter(csecret) + '&' + encodeParameter(tsecret);

        if (params['oauth_signature_method'] === 'PLAINTEXT') {
            return keyString;
        }
        else if (params['oauth_signature_method'] === 'HMAC-SHA1') {
            var hmac = crypto.createHmac('sha1', keyString);
            return hmac.update(baseString).digest('base64');
        }
        else {
            throw 'oauther :: Unsupported signature method : ' + params['oauth_signature_method'];
        }
    }

    /**
     * Sign OAuth request
     * @param  {Object} req data
     * {
     *     hostname : 'example.com',
     *     method : 'GET',
     *     path : '/path/to/url',
     *     port : 80, // optional
     *     protocol : 'http', // optional, default 'http'
     *     query, : { 'gaius' : 'baltar' },// optional, query string as json
     *     body : { 'kara' : 'thrace' } // optional, form encoded body as json
     * }
     * @return {Object} OAuth data object
     */
    this.sign = function(req) {
        var method = req.method;
        var baseURL = parseURL(req);
        var params = params = getAllParams(req);
        var oauthParams = generateSignature(method, baseURL, params);

        return oauthSignature(oauthParams);
    };

    /**
     * A http request to validate
     * @param  {Object} req request
     * @return {Object} true if the signature is valid
     */
    this.validate = function(req) {
        var method = req.method;
        var baseURL = parseURL(req);
        var params = getAllParams(req);

        if (!params['oauth_signature']) {
            return false;
        }

        var expect = calculateSignature(method, baseURL, params);

        return params['oauth_signature'] === expect;
    };

    return self;
}

module.exports = oauther;
<|endoftext|>


<commit_before>"use strict";

function jQuery () {}

jQuery.type = function( obj ) {
	if ( obj == null ) {
		return obj + "";
	}
	return typeof obj;
	// Support: Android < 4.0, iOS < 6 (functionish RegExp)
	return typeof obj === "object" || typeof obj === "function" ?
		class2type[ toString.call(obj) ] || "object" :
		typeof obj;
};

jQuery.isPlainObject = function ( obj ) {
	"use strict";
	// Not plain objects:
	// - Any object or value whose internal [[Class]] property is not "[object Object]"
	// - DOM nodes
	// - window
	if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
		return false;
	}

	if ( obj.constructor &&
			!obj.constructor.prototype.hasOwnProperty("isPrototypeOf") ) {
		return false;
	}

	// If the function hasn't returned already, we're confident that
	// |obj| is a plain object, created by {} or constructed with new Object
	return true;
};

jQuery.extend = function () {
	"use strict";
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;

		// skip the boolean and the target
		target = arguments[ i ] || {};
		i++;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && typeof target !== 'function' ) {
		target = {};
	}

	// extend jQuery itself if only one argument is passed
	if ( i === length ) {
		target = this;
		i--;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				if ( target === copy ) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)) ) ) {
					if ( copyIsArray ) {
						copyIsArray = false;
						clone = src && Array.isArray(src) ? src : [];

					} else {
						clone = src && jQuery.isPlainObject(src) ? src : {};
					}

					// Never move original objects, clone them
					target[ name ] = extend( deep, clone, copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

function buildClass (base, extensions, protoProps, constProps) {
	// build constructor
	function F () {
		base.apply(this, arguments);			// top-down (super -> base) recursion
		// TODO: do we need to recurse at all?
	}

	F.superclass = base;

	// set prototype
	F.prototype = Object.create(base.prototype);
	F.prototype.constructor = F;

	// register extensions and merge their prototypes
	F.__ext = [];
	if (extensions) {
		extensions.forEach(function (ext) {
			F.__ext.push(ext);
			jQuery.extend(F.prototype, ext.prototype);
		});
	}

	// add properties
	if (protoProps) {
		jQuery.extend(F.prototype, protoProps);
	}
	if (constProps) {
		jQuery.extend(F, constProps);
	}

	return F;
}

function Root () {
	var args = arguments,
		self = this;

	console.log('Root()');

	// walk inheritance chain, call each (super) class extensions' init functions
	(function initExtensionsFor(constructor) {
		if (constructor === Root) {
			return;
		}
		initExtensionsFor(constructor.superclass);		// super -> base

		constructor.__ext.forEach(function (ext) {
			ext.apply(self, args);		// TODO: meh, should we even call Extensions constructors?
			ext.prototype.init.apply(self, args);
		});
		if (constructor.prototype.hasOwnProperty('init')) {
			constructor.prototype.init.apply(self, args);
		}

	}(this.constructor));
}

/*global console*/
(function () {
	"use strict";

	var Awesome, ai, Base, Mid;

	// Base
	Base = buildClass(Root);

	Base.prototype.init = function (config) {
		this.baseVar = config.baseVar;
		console.log('Base.init');
	};

	Base.prototype.baseFunc = function () {
		return 'Base: ' + this.baseVar;
	};

	// Mid
	Mid = buildClass(Base);

	Mid.prototype.init = function (config) {
		console.log('Mid.init');
		this.midVar = config.midVar;
	};
	Mid.prototype.midFunc = function () {
		return 'Mid: ' + this.midVar;
	};

	// Ext
	function Ext (config) {
		console.log('Ext constructor');
		this.extVar = config.extVar;
	}
	Ext.prototype.extFunc = function () {
		return 'Ext: ' + this.extVar;
	};
	Ext.prototype.init = function (config) {
		console.log('Ext.init');
	};

	// Awesome
	Awesome = buildClass(Mid, [Ext], {
		init: function (config) {
			console.log('Awesome.init');
			this.awsVar = config.awsVar;
		},
		awsFunc: function () {
			return 'Awesome: ' + this.awsVar;
		}
	});

	// test
	ai = new Awesome({
		baseVar:	'base',
		midVar:		'mid',
		extVar:		'ext',
		awsVar:		'pwn'
	});

	console.log(
		ai.baseFunc(), ai.midFunc(), ai.extFunc(), ai.awsFunc()
	);
	console.log(
		'these should all be true:', ai instanceof Awesome, ai instanceof Mid, ai instanceof Base
	);
	console.log(
		'and what about Ext?', ai instanceof Ext
	);
}());
<commit_msg>buildClass utility works<commit_after>"use strict";

function jQuery () {}

jQuery.type = function( obj ) {
	if ( obj == null ) {
		return obj + "";
	}
	return typeof obj;
	// Support: Android < 4.0, iOS < 6 (functionish RegExp)
	return typeof obj === "object" || typeof obj === "function" ?
		class2type[ toString.call(obj) ] || "object" :
		typeof obj;
};

jQuery.isPlainObject = function ( obj ) {
	"use strict";
	// Not plain objects:
	// - Any object or value whose internal [[Class]] property is not "[object Object]"
	// - DOM nodes
	// - window
	if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
		return false;
	}

	if ( obj.constructor &&
			!obj.constructor.prototype.hasOwnProperty("isPrototypeOf") ) {
		return false;
	}

	// If the function hasn't returned already, we're confident that
	// |obj| is a plain object, created by {} or constructed with new Object
	return true;
};

jQuery.extend = function () {
	"use strict";
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;

		// skip the boolean and the target
		target = arguments[ i ] || {};
		i++;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && typeof target !== 'function' ) {
		target = {};
	}

	// extend jQuery itself if only one argument is passed
	if ( i === length ) {
		target = this;
		i--;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null ) {
			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				if ( target === copy ) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)) ) ) {
					if ( copyIsArray ) {
						copyIsArray = false;
						clone = src && Array.isArray(src) ? src : [];

					} else {
						clone = src && jQuery.isPlainObject(src) ? src : {};
					}

					// Never move original objects, clone them
					target[ name ] = extend( deep, clone, copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

/**
 * Build a constructor function
 *
 * The constructor itself will only call its parent. This recursion will
 * stop with Root(). Extension constructors are not called.
 *
 * Each class' and extension's init() function is called. The order is
 * bottom-up (e.g. sub -> super), and extensions before the classes they
 * were set up on.
 *
 * Init functions (and the constructors) are called with the arguments used
 * for the built class.
 *
 * Example:
 *   B = buildClass(Root);
 *
 *   E = function () {}		// will never be called
 *   E.prototype.init = function () {}
 *
 *   F = buildClass(B, [E], {
 *     init: function () {}
 *   });
 *
 *   new F();
 *
 * Call order:
 *   F() -> B() -> Root()	// Root() in turn will call
 *   B.init(), E.init(), F.init()
 *   F's prototype will have E's merged
 *
 * @param {Function} base				Must be Root or subclass of Root
 * @param {[Function]} [extensions]		List of extension constructors
 * @param {Object} [protoProps]			Properties to merge onto the built class' prototype (e.g. Func.prototype.prop)
 * @param {Object} [staticProps]		Properties to merge onto the built class (e.g. Func.prop)
 * @returns {Function}
 */
function buildClass (base, extensions, protoProps, staticProps) {
	// build constructor
	function F () {
		base.apply(this, arguments);			// top-down (super -> base) recursion
	}

	F.superclass = base;

	// set prototype
	F.prototype = Object.create(base.prototype);
	F.prototype.constructor = F;

	// register extensions and merge their prototypes
	F.__ext = [];
	if (extensions) {
		extensions.forEach(function (ext) {
			F.__ext.push(ext);
			jQuery.extend(F.prototype, ext.prototype);
		});
	}

	// add properties
	if (protoProps) {
		jQuery.extend(F.prototype, protoProps);
	}
	if (staticProps) {
		jQuery.extend(F, staticProps);
	}

	return F;
}

function Root () {
	var args = arguments,
		self = this;

	console.log('Root()');

	// walk inheritance chain, call each (super) class extensions' init functions
	(function initExtensionsFor(constructor) {
		if (constructor === Root) {
			return;
		}
		initExtensionsFor(constructor.superclass);		// super -> base

		constructor.__ext.forEach(function (ext) {
//			ext.apply(self, args);		// TODO: meh, should we even call Extensions constructors?
			ext.prototype.init.apply(self, args);
		});
		if (constructor.prototype.hasOwnProperty('init')) {
			constructor.prototype.init.apply(self, args);
		}

	}(this.constructor));
}

/*global console*/
(function () {
	"use strict";

	var Awesome, my, Base, MESAp, Mid;

	// Base
	Base = buildClass(Root);

	Base.prototype.init = function (config) {
		this.baseVar = config.baseVar;
		console.log('Base.init');
	};

	Base.prototype.baseFunc = function () {
		return 'Base: ' + this.baseVar;
	};

	// Mid
	Mid = buildClass(Base);

	Mid.prototype.init = function (config) {
		console.log('Mid.init');
		this.midVar = config.midVar;
	};
	Mid.prototype.midFunc = function () {
		return 'Mid: ' + this.midVar;
	};
	Mid.midStatic = 'Mid static';

	// Ext1
	function Ext1 () {}

	Ext1.prototype.init = function (config) {
		this.ext1Var = config.ext1Var;
		console.log('Ext1.init');
	};
	Ext1.prototype.ext1Func = function () {
		return 'Ext1: ' + this.ext1Var;
	};
	Ext1.ext1Static = 'Ext1 static';

	// Awesome
	Awesome = buildClass(Mid, [Ext1], {
		init: function (config) {
			console.log('Awesome.init');
			this.awsVar = config.awsVar;
		},
		awsFunc: function () {
			return 'Awesome: ' + this.awsVar;
		}
	});

	// Ext2
	function Ext2 () {}

	Ext2.prototype.init = function (config) {
		this.ext2Var = config.ext2Var;
		console.log('Ext2.init');
	};
	Ext2.prototype.ext2Func = function () {
		return 'Ext2: ' + this.ext2Var;
	};
	Ext2.ext2Static = 'Ext2 static';

	// MESAp
	MESAp = buildClass(Awesome, [Ext2], {
		init: function (config) {
			console.log('MESAp.init');
			this.mesapVar = config.mesapVar;
		},
		mesapFunc: function () {
			return 'MESA+: ' + this.mesapVar;
		}
	}, {
		mesapStatic: 'MESA+ static'
	});

	// test
	my = new MESAp({
		baseVar:	'base',
		midVar:		'mid',
		ext1Var:	'ext1',
		awsVar:		'aws',
		ext2Var:	'ext2',
		mesapVar:	'mesa+'
	});

	console.log(
		my.baseFunc(), my.midFunc(), my.ext1Func(), my.awsFunc(), my.ext2Func(), my.mesapFunc()
	);
	console.log(
		'these should all be true:', my instanceof MESAp, my instanceof Awesome, my instanceof Mid, my instanceof Base
	);
	console.log(
		'and what about Ext1?', my instanceof Ext2, my instanceof Ext1
	);
}());
<|endoftext|>


<commit_before>'use strict';

var createBuffer = require('gl-buffer');
var createVAO = require('gl-vao');
var glslify = require('glslify');
var glm = require('gl-matrix');
var mat4 = glm.mat4;

module.exports = function(game, opts) {
  return new OutlinePlugin(game, opts);
};

function OutlinePlugin(game, opts) {
  this.shell = game.shell;

  this.mesherPlugin = game.plugins.get('voxel-mesher');
  if (!this.mesherPlugin) throw new Error('voxel-outline requires voxel-mesher');

  this.shaderPlugin = game.plugins.get('voxel-shader');
  if (!this.shaderPlugin) throw new Error('voxel-outline requires voxel-shader');

  this.showOutline = true;
  this.colorVector = opts.color !== undefined ? opts.color : [1,0,0,1]; // red, RGBA TODO: convert from hex? TODO: same in voxel-chunkborder
  this.modelMatrix = mat4.create(); // TODO

  this.enable();
}

OutlinePlugin.prototype.enable = function() {
  this.shell.on('gl-init', this.onInit = this.shaderInit.bind(this));
  this.shell.on('gl-render', this.onRender = this.render.bind(this));
};

OutlinePlugin.prototype.disable = function() {
  this.shell.removeListener('gl-render', this.onRender = this.render.bind(this));
  this.shell.removeListener('gl-init', this.onInit);
};

OutlinePlugin.prototype.render = function() {
  if (this.showOutline) {
    var gl = this.shell.gl;

    this.outlineShader.bind();
    this.outlineShader.attributes.position.location = 0;
    this.outlineShader.uniforms.projection = this.shaderPlugin.projectionMatrix;
    this.outlineShader.uniforms.view = this.shaderPlugin.viewMatrix;
    this.outlineShader.uniforms.color = this.colorVector;
    this.outlineShader.uniforms.model = this.modelMatrix;
    var outlineVAO = this.mesh;
    outlineVAO.bind();
    outlineVAO.draw(gl.LINES, outlineVAO.length);
    outlineVAO.unbind();
  }
};

// TODO: can we use the same simple shaders as elsewhere? (e.g. voxel-chunkborder)
// no need to specialize here
OutlinePlugin.prototype.shaderInit = function() {
  this.outlineShader = glslify({
    inline: true,
    vertex: "/* voxel-outline vertex shader */\
attribute vec3 position;\
uniform mat4 projection;\
uniform mat4 view;\
uniform mat4 model;\
void main() {\
  gl_Position = projection * view * model * vec4(position, 1.0);\
}",

  fragment: "/* voxel-outline fragment shader */\
precision highp float;\
uniform vec4 color;\
void main() {\
  gl_FragColor = color;\
}"})(this.shell.gl);

  // create outline mesh

  // TODO: refactor with voxel-chunkborder, very similar

  var w = 1;
  var outlineVertexArray = new Uint8Array([
    0,0,0,
    0,0,w,
    0,w,0,
    0,w,w,
    w,0,0,
    w,0,w,
    w,w,0,
    w,w,w
  ]);

  var indexArray = new Uint16Array([
    0,1, 0,2, 2,3, 3,1,
    0,4, 4,5, 5,1,
    5,7, 7,3,
    7,6, 6,2,
    6,4
  ]);

  var outlineVertexCount = indexArray.length;

  var gl = this.shell.gl;

  var outlineBuf = createBuffer(gl, outlineVertexArray);
  var indexBuf = createBuffer(gl, indexArray, gl.ELEMENT_ARRAY_BUFFER);

  var outlineVAO = createVAO(gl, [
      { buffer: outlineBuf,
        type: gl.UNSIGNED_BYTE,
        size: 3
      }], indexBuf);
  outlineVAO.length = outlineVertexCount;

  this.mesh = outlineVAO;
};

<commit_msg>Outline currently targeted voxel from raycastVoxels<commit_after>'use strict';

var createBuffer = require('gl-buffer');
var createVAO = require('gl-vao');
var glslify = require('glslify');
var glm = require('gl-matrix');
var mat4 = glm.mat4;
var vec3 = glm.vec3;

module.exports = function(game, opts) {
  return new OutlinePlugin(game, opts);
};

function OutlinePlugin(game, opts) {
  this.game = game;
  this.shell = game.shell;

  this.mesherPlugin = game.plugins.get('voxel-mesher');
  if (!this.mesherPlugin) throw new Error('voxel-outline requires voxel-mesher');

  this.shaderPlugin = game.plugins.get('voxel-shader');
  if (!this.shaderPlugin) throw new Error('voxel-outline requires voxel-shader');

  this.showOutline = true;
  this.colorVector = opts.color !== undefined ? opts.color : [1,0,0,1]; // red, RGBA TODO: convert from hex? TODO: same in voxel-chunkborder
  this.modelMatrix = mat4.create(); // TODO

  this.enable();
}

OutlinePlugin.prototype.enable = function() {
  this.shell.on('gl-init', this.onInit = this.shaderInit.bind(this));
  this.shell.on('gl-render', this.onRender = this.render.bind(this));
  this.game.on('tick', this.onTick = this.tick.bind(this)); // TODO: _.throttle? https://github.com/maxogden/voxel-highlight/blob/master/index.js#L56
};

OutlinePlugin.prototype.disable = function() {
  this.game.removeListener('tick', this.onTick);
  this.shell.removeListener('gl-render', this.onRender = this.render.bind(this));
  this.shell.removeListener('gl-init', this.onInit);
};

var scratch0 = vec3.create();
OutlinePlugin.prototype.tick = function() {
  var hit = this.game.raycastVoxels();

  if (!hit) {
    // TODO: remove outline if any
    return;
  }

  // translate to voxel position
  // TODO: only change if voxel target changed?
  mat4.identity(this.modelMatrix);
  scratch0[0] = hit.voxel[2];
  scratch0[1] = hit.voxel[1];
  scratch0[2] = hit.voxel[0];
  mat4.translate(this.modelMatrix, this.modelMatrix, scratch0);
};

OutlinePlugin.prototype.render = function() {
  if (this.showOutline) {
    var gl = this.shell.gl;

    this.outlineShader.bind();
    this.outlineShader.attributes.position.location = 0;
    this.outlineShader.uniforms.projection = this.shaderPlugin.projectionMatrix;
    this.outlineShader.uniforms.view = this.shaderPlugin.viewMatrix;
    this.outlineShader.uniforms.color = this.colorVector;
    this.outlineShader.uniforms.model = this.modelMatrix;
    var outlineVAO = this.mesh;
    outlineVAO.bind();
    outlineVAO.draw(gl.LINES, outlineVAO.length);
    outlineVAO.unbind();
  }
};

// TODO: can we use the same simple shaders as elsewhere? (e.g. voxel-chunkborder)
// no need to specialize here
OutlinePlugin.prototype.shaderInit = function() {
  this.outlineShader = glslify({
    inline: true,
    vertex: "/* voxel-outline vertex shader */\
attribute vec3 position;\
uniform mat4 projection;\
uniform mat4 view;\
uniform mat4 model;\
void main() {\
  gl_Position = projection * view * model * vec4(position, 1.0);\
}",

  fragment: "/* voxel-outline fragment shader */\
precision highp float;\
uniform vec4 color;\
void main() {\
  gl_FragColor = color;\
}"})(this.shell.gl);

  // create outline mesh

  // TODO: refactor with voxel-chunkborder, very similar

  var w = 1;
  var outlineVertexArray = new Uint8Array([
    0,0,0,
    0,0,w,
    0,w,0,
    0,w,w,
    w,0,0,
    w,0,w,
    w,w,0,
    w,w,w
  ]);

  var indexArray = new Uint16Array([
    0,1, 0,2, 2,3, 3,1,
    0,4, 4,5, 5,1,
    5,7, 7,3,
    7,6, 6,2,
    6,4
  ]);

  var outlineVertexCount = indexArray.length;

  var gl = this.shell.gl;

  var outlineBuf = createBuffer(gl, outlineVertexArray);
  var indexBuf = createBuffer(gl, indexArray, gl.ELEMENT_ARRAY_BUFFER);

  var outlineVAO = createVAO(gl, [
      { buffer: outlineBuf,
        type: gl.UNSIGNED_BYTE,
        size: 3
      }], indexBuf);
  outlineVAO.length = outlineVertexCount;

  this.mesh = outlineVAO;
};

<|endoftext|>