<commit_before>'use strict';
var Aubengine, exports;

/* Dependencies */
var Entity     = require('./Entity')
var NodeTree   = require('./NodeTree');
var Tree       = require('./Tree');
var Aubengine  = require('./Aubengine');
var Shader     = require('./Shader');
var Color      = require('./Color');
var Texture    = require('./Texture');
var Manager    = require('../ResourceManager');

Aubengine = (function(width, height, canvasId, tree, resourceManager) {
  function Aubengine(width, height, canvasId, tree, resourceManager) {
    /* Properties */
    this.width     = width;
    this.height    = height;
    this.names     = ['webgl', 'experimental-webgl', 'webkit-3d', 'moz-webgl'];

    /* WebGL elements*/
    this.gl        = null;
    this.canvasId  = canvasId;

    /* Scene entities */
    this.texture = new Texture();
    this.model   = new Model();
    this.light   = new Light();
    this.color   = new Color();

    /* Scene */
    this.scene   = new Scene();
}

Aubengine.prototype.startWeb = function() {
    var canvas = document.getElementById(this.canvasId);
    var i = 0;
    while ((this.gl == null) && (i < this.names.length)) {
      try {
        this.gl = canvas.getContext(this.names[i]);
      } catch (e) {
        console.log(e);
      };
      i++;
    }
  };

  Aubengine.prototype.createBuffer = function() {
    this.gl.createBuffer();
  };

  Aubengine.prototype.isStarted = function() {
    if (this.gl == null) {return false;}
    else {return true;}
  };

  Aubengine.prototype.clear = function() {
    if (this.isStarted()) {
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.viewport(0, 0, this.width, this.height);
    }
  },

  Aubengine.prototype.changeColor = function(color) {
    if (this.isStarted()) {
      this.gl.clearColor(color[0], color[1], color[2], color[3]);
      this.clear(this.gl);
    }
  };

  Aubengine.prototype.enableVertexAttributes = function(shader) {
    shader.setPointer();
    this.gl.enableVertexAttribArray(shader.getPointer());
  }

  Aubengine.prototype.draw = function() {
    /* TODO */
    //1. Iniciar libreria grafica
    //2. Iniciar las luces
    //3. Iniciar el viewport con la libreria grafica
    //4. Iniciar la camara
    //5.
  }

return Aubengine;
})();

exports = module.exports = Aubengine;
<commit_msg>improved main class, to use it as the main library<commit_after>'use strict';
var Aubengine = window.Aubengine || {}, exports;

/* Dependencies */
var Entity     = require('./Entity')
var Shader     = require('./Shader');
var Color      = require('./Color');
var Transform  = require('./Transform');
var Mesh       = require('./Mesh');
var Light      = require('./Light');
var Scene      = require('./Scene');
var Manager    = require('./ResourceManager');
var Content    = require('./ShadersContent');

Aubengine = (function(width, height, canvasId) {
  function Aubengine(width, height, canvasId) {
    /* Properties */
    this.width     = width;
    this.height    = height;
    this.names     = ['webgl', 'experimental-webgl', 'webkit-3d', 'moz-webgl'];
    this.canvasId  = canvasId;

    /* WebGL elements*/
    this.gl        = null;

    /* Entities */
    this.mesh      = new Mesh();
    this.light     = new Light();
    this.color     = new Color();
    this.transform = new Transform();
    this.shader    = new Shader(this.gl);

    /* Scene */
    this.scene   = new Scene(this.gl, this.program);

    /* Resource Manager */
    this.content = new Content();
    this.vertexShaderContent   = this.content.vertexContent;
    this.fragmentShaderContent = this.content.fragmentContent;
}

  Aubengine.prototype.setVertexShaderContent = function(content) {
    this.vertexShaderContent = content;
  };

  Aubengine.prototype.getManager = function() {
    return this.manager;
  }
  /* Basic previous configuration */
  Aubengine.prototype.getGl = function() {
    return this.gl;
  };

  Aubengine.prototype.setGl = function(gl) {
    this.gl = gl;
    this.scene.setGl(gl);
  };

  Aubengine.prototype.setProgram = function(program) {
    this.program = program;
    this.scene.setProgram(program);
  };

  Aubengine.prototype.setShaders = function(content, type) {
       var script = document.createElement('script');
       script.setAttribute('type', type);
       script.innerHTML = content;
       document.body.appendChild(script);
  }

  Aubengine.prototype.startWeb = function() {
    var canvas = document.getElementById(this.canvasId);
    var i = 0;
    this.gl = canvas.getContext('webgl');
    this.setShaders(this.vertexShaderContent,   this.shader.vertexName());
    this.setShaders(this.fragmentShaderContent, this.shader.fragmentName());
    // while ((this.gl == null) && (i < this.names.length)) {
    //   console.log(this.names[i]);
    //   try {
    //     this.gl = canvas.getContext(this.names[i]);
    //   } catch (e) {
    //     console.log(e);
    //   };
    //   i++;
    // }
  };

  Aubengine.prototype.createBuffer = function() {
    this.gl.createBuffer();
  };

  Aubengine.prototype.isStarted = function() {
    if (this.gl == null) {return false;}
    else {return true;}
  };

/* Main functions, the real magic */
  Aubengine.prototype.clear = function() {
    if (this.isStarted()) {
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.viewport(0, 0, this.width, this.height);
    }
  };

  Aubengine.prototype.changeColor = function(color) {
    if (this.isStarted()) {
      this.gl.clearColor(color[0], color[1], color[2], color[3]);
      this.clear(this.gl);
    }
  };

  Aubengine.prototype.scale = function(gl, x, y, z, matrix) {
    this.transform.scale(gl, x, y, z, matrix);
  };

return Aubengine;
})();

exports = module.exports = Aubengine;

window.Aubengine = Aubengine;
<|endoftext|>


<commit_before>var keystone = require('../'),
	Types = require('./fieldTypes'),
	_ = require('underscore'),
	async = require('async'),
	utils = require('keystone-utils');

var methods = module.exports.methods = {};
var options = module.exports.options = {};

exports.sortable = function() {

	var list = this;

	this.schema.add({
		sortOrder: { type: Number, index: true }
	});

	this.schema.pre('save', function(next) {

		var sortOrderType = this.schema.path('sortOrder');
		if (typeof sortOrderType !== 'undefined' && sortOrderType instanceof keystone.mongoose.Schema.Types.Number) {
			return next();
		}

		var item = this;
		list.model.findOne().sort('-sortOrder').exec(function(err, max) {
			item.sortOrder = (max && max.sortOrder) ? max.sortOrder + 1 : 0;
			next();
		});

	});

};

exports.autokey = function() {

	var autokey = this.autokey = this.get('autokey'),
		list = this,
		def = {};

	if (!autokey.from) {
		var fromMsg = 'Invalid List Option (autokey) for ' + list.key + ' (from is required)\n';
		throw new Error(fromMsg);
	}
	if (!autokey.path) {
		var pathMsg = 'Invalid List Option (autokey) for ' + list.key + ' (path is required)\n';
		throw new Error(pathMsg);
	}

	if ('string' === typeof autokey.from) {
		autokey.from = autokey.from.split(' ');
	}

	autokey.from = autokey.from.map(function(i) {
		i = i.split(':');
		return { path: i[0], format: i[1] };
	});

	def[autokey.path] = {
		type: String,
		index: true
	};

	if (autokey.unique) {
		def[autokey.path].index = { unique: true };
	}

	this.schema.add(def);

	var getUniqueKey = function(doc, src, callback) {

		var q = list.model.find().where(autokey.path, src);

		if (_.isObject(autokey.unique)) {
			_.each(autokey.unique, function(k, v) {
				if (_.isString(v) && v.charAt(0) === ':') {
					q.where(k, doc.get(v.substr(1)));
				} else {
					q.where(k, v);
				}
			});
		}

		q.exec(function(err, results) {
			if (err) {
				callback(err);
			// deliberate use of implicit type coercion with == because doc.id may need to become a String
			} else if (results.length && (results.length > 1 || results[0].id != doc.id)) { // jshint ignore:line
				var inc = src.match(/^(.+)\-(\d+)$/);
				if (inc && inc.length === 3) {
					src = inc[1];
					inc = '-' + ((inc[2] * 1) + 1);
				} else {
					inc = '-1';
				}
				return getUniqueKey(doc, src + inc, callback);
			} else {
				doc.set(autokey.path, src);
				return callback();
			}
		});
	};

	this.schema.pre('save', function(next) {

		var modified = false,
			values = [];

		autokey.from.forEach(function(ops) {
			if (list.fields[ops.path]) {
				values.push(list.fields[ops.path].format(this, ops.format));
				if (list.fields[ops.path].isModified(this)) {
					modified = true;
				}
			} else {
				values.push(this.get(ops.path));
				// virtual paths are always assumed to have changed, except 'id'
				if (ops.path !== 'id' && list.schema.pathType(ops.path) === 'virtual' || this.isModified(ops.path)) {
					modified = true;
				}
			}
		}, this);

		// if has a value and is unmodified or fixed, don't update it
		if ((!modified || autokey.fixed) && this.get(autokey.path)) {
			return next();
		}

		var newKey = utils.slug(values.join(' ') || this.id);

		if (autokey.unique) {
			return getUniqueKey(this, newKey, next);
		} else {
			this.set(autokey.path, newKey);
			return next();
		}

	});

};

/**
 * List track option
 *
 * When enabled, it tracks when a document are created/updated,
 * as well as the user who created/updated it.
 */
exports.track = function() {

	var list = this,
		options = list.get('track'),
		userModel = keystone.get('user model'),
		defaultOptions = {
			createdAt: false,
			createdBy: false,
			updatedAt: false,
			updatedBy: false
		},
		fields = {};

	// ensure track is a boolean or an object
	if (!_.isBoolean(options) && !_.isObject(options) ) {
		throw new Error('Invalid List "track" option for ' + list.key + '\n' +
			'"track" must be a boolean or an object.\n\n' +
			'See http://keystonejs.com/docs/database/#lists-options for more information.');
	}

	if (_.isBoolean(options)) {
		// shorthand: { track: true } sets all tracked fields to true
		if (options) {
			options = {
				createdAt: true,
				createdBy: true,
				updatedAt: true,
				updatedBy: true
			};
		} else {
			// otherwise user doesn't want tracking
			return;
		}
	}

	// enable createdAt/updatedAt when simulating standard meta
	if (list.get('track simulate standard meta')) {
		options.createdAt = true;
		options.updatedAt = true;
	}

	// if all track fields are set to false, then user doesn't want to track anything
	if (!options.createdAt && !options.createdBy && !options.updatedAt && !options.updatedBy) {
		return;
	}

	// merge user options with default options
	options = _.extend({}, defaultOptions, options);

	// validate option fields
	_.each(options, function(value, key) {

		var fieldName;

		// make sure the key isn't already defined as a field
		if (_.has(list.fields, key)) {
			throw new Error('Invalid List "track" option for ' + list.key + '\n' +
				'"' + key + '" is already defined in the Schema.');
		}

		// make sure it's a valid track option field
		if (_.has(defaultOptions, key)) {

			// make sure the option field value is either a boolean or a string
			if (!_.isBoolean(value) && !_.isString(value)) {
				throw new Error('Invalid List "track" option for ' + list.key + '\n' +
					'"' + key + '" must be a boolean or a string.\n\n' +
					'See http://keystonejs.com/docs/database/#lists-options for more information.');
			}

			if (value) {
				// determine
				fieldName = value === true ? key : value;
				options[key] = fieldName;
				list.map(key, fieldName);

				switch(key) {
					case 'createdAt':
					case 'updatedAt':
						fields[fieldName] = { type: Date, hidden: true, index: true };
					break;

					case 'createdBy':
					case 'updatedBy':
						fields[fieldName] = { type: Types.Relationship, ref: userModel, hidden: true, index: true };
					break;
				}
			}
		} else {
			throw new Error('Invalid List "track" option for ' + list.key + '\n' +
				'valid field options are "createdAt", "createdBy", "updatedAt", an "updatedBy".\n\n' +
				'See http://keystonejs.com/docs/database/#lists-options for more information.');
		}

	});

	// simulate standard meta by mapping to existing createdAt/updatedAt fields
	if (list.get('track simulate standard meta')) {
		list.map('createdOn', options.createdAt);
		list.schema.virtual('createdOn')
			.get(function () {
				return this.get('createdAt');
			});

		list.map('updatedOn', options.updatedAt);
		list.schema.virtual('updatedOn')
			.get(function () {
				return this.get('updatedAt');
			});
	}

	// add track fields to schema
	list.add(fields);

	list.tracking = options;

	// add the pre-save schema plugin
	list.schema.pre('save', function (next) {

		var now = new Date();

		// set createdAt/createdBy on new docs
		if (this.isNew) {
			if (options.createdAt) {
				this.set(options.createdAt, now);
			}
			if (options.createdBy && this._req_user) {
				this.set(options.createdBy, this._req_user._id);
			}
		}

		// set updatedAt/updatedBy when doc is modified
		if (this.isNew || this.isModified()) {
			if (options.updatedAt) {
				this.set(options.updatedAt, now);
			}
			if (options.updatedBy && this._req_user) {
				this.set(options.updatedBy, this._req_user._id);
			}
		}

		next();

	});

};

methods.getRelated = function(paths, callback, nocollapse) {

	var item = this,
		list = this.list,
		queue = {};

	if ('function' !== typeof callback) {
		throw new Error('List.getRelated(paths, callback, nocollapse) requires a callback function.');
	}

	if ('string' === typeof paths) {
		var pathsArr = paths.split(' ');
		var lastPath = '';
		paths = [];
		for (var i = 0; i < pathsArr.length; i++) {
			lastPath += (lastPath.length ? ' ' : '') + pathsArr[i];
			if (lastPath.indexOf('[') < 0 || lastPath.charAt(lastPath.length - 1) === ']') {
				paths.push(lastPath);
				lastPath = '';
			}
		}
	}

	_.each(paths, function(options) {

		var populateString = '';

		if ('string' === typeof options) {
			if (options.indexOf('[') > 0) {
				populateString = options.substring(options.indexOf('[') + 1, options.indexOf(']'));
				options = options.substr(0,options.indexOf('['));
			}
			options = { path: options };
		}
		options.populate = options.populate || [];
		options.related = options.related || [];

		var relationship = list.relationships[options.path];
		if (!relationship) throw new Error('List.getRelated: list ' + list.key + ' does not have a relationship ' + options.path + '.');

		var refList = keystone.list(relationship.ref);
		if (!refList) throw new Error('List.getRelated: list ' + relationship.ref + ' does not exist.');

		var relField = refList.fields[relationship.refPath];
		if (!relField || relField.type !== 'relationship') throw new Error('List.getRelated: relationship ' + relationship.ref + ' on list ' + list.key + ' refers to a path (' + relationship.refPath + ') which is not a relationship field.');

		if (populateString.length) {

			_.each(populateString.split(' '), function(key) {
				if (refList.relationships[key])
					options.related.push(key);
				else
					options.populate.push(key);
			});

		}

		queue[relationship.path] = function(done) {

			var query = refList.model.find().where(relField.path);

			if (options.populate)
				query.populate(options.populate);

			if (relField.many) {
				query.in([item.id]);
			} else {
				query.equals(item.id);
			}

			query.sort(options.sort || relationship.sort || refList.defaultSort);

			if (options.related.length) {
				query.exec(function(err, results) {
					if (err || !results.length) {
						return done(err, results);
					}
					async.parallel(results.map(function(item) {
							return function(done) {
								item.populateRelated(options.related, done);
							};
						}),
						function(err) {
							done(err, results);
						}
					);
				});
			} else {
				query.exec(done);
			}

		};

		if (!item._populatedRelationships) item._populatedRelationships = {};
		item._populatedRelationships[relationship.path] = true;

	});

	async.parallel(queue, function(err, results) {
		if (!nocollapse && results && paths.length === 1) {
			results = results[paths[0]];
		}
		callback(err, results);
	});

};

methods.populateRelated = function(rel, callback) {

	var item = this;

	if ('function' !== typeof callback) {
		throw new Error('List.populateRelated(rel, callback) requires a callback function.');
	}

	this.getRelated(rel, function(err, results) {
		_.each(results, function(data, key) {
			item[key] = data;
		});
		callback(err, results);
	}, true);

};

options.transform = function(doc, ret) {
	if (doc._populatedRelationships) {
		_.each(doc._populatedRelationships, function(on, key) {
			if (!on) return;
			ret[key] = doc[key];
		});
	}
};
<commit_msg>Default auto key to id when '', hopefully fixes #668<commit_after>var keystone = require('../'),
	Types = require('./fieldTypes'),
	_ = require('underscore'),
	async = require('async'),
	utils = require('keystone-utils');

var methods = module.exports.methods = {};
var options = module.exports.options = {};

exports.sortable = function() {

	var list = this;

	this.schema.add({
		sortOrder: { type: Number, index: true }
	});

	this.schema.pre('save', function(next) {

		var sortOrderType = this.schema.path('sortOrder');
		if (typeof sortOrderType !== 'undefined' && sortOrderType instanceof keystone.mongoose.Schema.Types.Number) {
			return next();
		}

		var item = this;
		list.model.findOne().sort('-sortOrder').exec(function(err, max) {
			item.sortOrder = (max && max.sortOrder) ? max.sortOrder + 1 : 0;
			next();
		});

	});

};

exports.autokey = function() {

	var autokey = this.autokey = this.get('autokey'),
		list = this,
		def = {};

	if (!autokey.from) {
		var fromMsg = 'Invalid List Option (autokey) for ' + list.key + ' (from is required)\n';
		throw new Error(fromMsg);
	}
	if (!autokey.path) {
		var pathMsg = 'Invalid List Option (autokey) for ' + list.key + ' (path is required)\n';
		throw new Error(pathMsg);
	}

	if ('string' === typeof autokey.from) {
		autokey.from = autokey.from.split(' ');
	}

	autokey.from = autokey.from.map(function(i) {
		i = i.split(':');
		return { path: i[0], format: i[1] };
	});

	def[autokey.path] = {
		type: String,
		index: true
	};

	if (autokey.unique) {
		def[autokey.path].index = { unique: true };
	}

	this.schema.add(def);

	var getUniqueKey = function(doc, src, callback) {

		var q = list.model.find().where(autokey.path, src);

		if (_.isObject(autokey.unique)) {
			_.each(autokey.unique, function(k, v) {
				if (_.isString(v) && v.charAt(0) === ':') {
					q.where(k, doc.get(v.substr(1)));
				} else {
					q.where(k, v);
				}
			});
		}

		q.exec(function(err, results) {
			if (err) {
				callback(err);
			// deliberate use of implicit type coercion with == because doc.id may need to become a String
			} else if (results.length && (results.length > 1 || results[0].id != doc.id)) { // jshint ignore:line
				var inc = src.match(/^(.+)\-(\d+)$/);
				if (inc && inc.length === 3) {
					src = inc[1];
					inc = '-' + ((inc[2] * 1) + 1);
				} else {
					inc = '-1';
				}
				return getUniqueKey(doc, src + inc, callback);
			} else {
				doc.set(autokey.path, src);
				return callback();
			}
		});
	};

	this.schema.pre('save', function(next) {

		var modified = false,
			values = [];

		autokey.from.forEach(function(ops) {
			if (list.fields[ops.path]) {
				values.push(list.fields[ops.path].format(this, ops.format));
				if (list.fields[ops.path].isModified(this)) {
					modified = true;
				}
			} else {
				values.push(this.get(ops.path));
				// virtual paths are always assumed to have changed, except 'id'
				if (ops.path !== 'id' && list.schema.pathType(ops.path) === 'virtual' || this.isModified(ops.path)) {
					modified = true;
				}
			}
		}, this);

		// if has a value and is unmodified or fixed, don't update it
		if ((!modified || autokey.fixed) && this.get(autokey.path)) {
			return next();
		}

		var newKey = utils.slug(values.join(' ')) || this.id;

		if (autokey.unique) {
			return getUniqueKey(this, newKey, next);
		} else {
			this.set(autokey.path, newKey);
			return next();
		}

	});

};

/**
 * List track option
 *
 * When enabled, it tracks when a document are created/updated,
 * as well as the user who created/updated it.
 */
exports.track = function() {

	var list = this,
		options = list.get('track'),
		userModel = keystone.get('user model'),
		defaultOptions = {
			createdAt: false,
			createdBy: false,
			updatedAt: false,
			updatedBy: false
		},
		fields = {};

	// ensure track is a boolean or an object
	if (!_.isBoolean(options) && !_.isObject(options) ) {
		throw new Error('Invalid List "track" option for ' + list.key + '\n' +
			'"track" must be a boolean or an object.\n\n' +
			'See http://keystonejs.com/docs/database/#lists-options for more information.');
	}

	if (_.isBoolean(options)) {
		// shorthand: { track: true } sets all tracked fields to true
		if (options) {
			options = {
				createdAt: true,
				createdBy: true,
				updatedAt: true,
				updatedBy: true
			};
		} else {
			// otherwise user doesn't want tracking
			return;
		}
	}

	// enable createdAt/updatedAt when simulating standard meta
	if (list.get('track simulate standard meta')) {
		options.createdAt = true;
		options.updatedAt = true;
	}

	// if all track fields are set to false, then user doesn't want to track anything
	if (!options.createdAt && !options.createdBy && !options.updatedAt && !options.updatedBy) {
		return;
	}

	// merge user options with default options
	options = _.extend({}, defaultOptions, options);

	// validate option fields
	_.each(options, function(value, key) {

		var fieldName;

		// make sure the key isn't already defined as a field
		if (_.has(list.fields, key)) {
			throw new Error('Invalid List "track" option for ' + list.key + '\n' +
				'"' + key + '" is already defined in the Schema.');
		}

		// make sure it's a valid track option field
		if (_.has(defaultOptions, key)) {

			// make sure the option field value is either a boolean or a string
			if (!_.isBoolean(value) && !_.isString(value)) {
				throw new Error('Invalid List "track" option for ' + list.key + '\n' +
					'"' + key + '" must be a boolean or a string.\n\n' +
					'See http://keystonejs.com/docs/database/#lists-options for more information.');
			}

			if (value) {
				// determine
				fieldName = value === true ? key : value;
				options[key] = fieldName;
				list.map(key, fieldName);

				switch(key) {
					case 'createdAt':
					case 'updatedAt':
						fields[fieldName] = { type: Date, hidden: true, index: true };
					break;

					case 'createdBy':
					case 'updatedBy':
						fields[fieldName] = { type: Types.Relationship, ref: userModel, hidden: true, index: true };
					break;
				}
			}
		} else {
			throw new Error('Invalid List "track" option for ' + list.key + '\n' +
				'valid field options are "createdAt", "createdBy", "updatedAt", an "updatedBy".\n\n' +
				'See http://keystonejs.com/docs/database/#lists-options for more information.');
		}

	});

	// simulate standard meta by mapping to existing createdAt/updatedAt fields
	if (list.get('track simulate standard meta')) {
		list.map('createdOn', options.createdAt);
		list.schema.virtual('createdOn')
			.get(function () {
				return this.get('createdAt');
			});

		list.map('updatedOn', options.updatedAt);
		list.schema.virtual('updatedOn')
			.get(function () {
				return this.get('updatedAt');
			});
	}

	// add track fields to schema
	list.add(fields);

	list.tracking = options;

	// add the pre-save schema plugin
	list.schema.pre('save', function (next) {

		var now = new Date();

		// set createdAt/createdBy on new docs
		if (this.isNew) {
			if (options.createdAt) {
				this.set(options.createdAt, now);
			}
			if (options.createdBy && this._req_user) {
				this.set(options.createdBy, this._req_user._id);
			}
		}

		// set updatedAt/updatedBy when doc is modified
		if (this.isNew || this.isModified()) {
			if (options.updatedAt) {
				this.set(options.updatedAt, now);
			}
			if (options.updatedBy && this._req_user) {
				this.set(options.updatedBy, this._req_user._id);
			}
		}

		next();

	});

};

methods.getRelated = function(paths, callback, nocollapse) {

	var item = this,
		list = this.list,
		queue = {};

	if ('function' !== typeof callback) {
		throw new Error('List.getRelated(paths, callback, nocollapse) requires a callback function.');
	}

	if ('string' === typeof paths) {
		var pathsArr = paths.split(' ');
		var lastPath = '';
		paths = [];
		for (var i = 0; i < pathsArr.length; i++) {
			lastPath += (lastPath.length ? ' ' : '') + pathsArr[i];
			if (lastPath.indexOf('[') < 0 || lastPath.charAt(lastPath.length - 1) === ']') {
				paths.push(lastPath);
				lastPath = '';
			}
		}
	}

	_.each(paths, function(options) {

		var populateString = '';

		if ('string' === typeof options) {
			if (options.indexOf('[') > 0) {
				populateString = options.substring(options.indexOf('[') + 1, options.indexOf(']'));
				options = options.substr(0,options.indexOf('['));
			}
			options = { path: options };
		}
		options.populate = options.populate || [];
		options.related = options.related || [];

		var relationship = list.relationships[options.path];
		if (!relationship) throw new Error('List.getRelated: list ' + list.key + ' does not have a relationship ' + options.path + '.');

		var refList = keystone.list(relationship.ref);
		if (!refList) throw new Error('List.getRelated: list ' + relationship.ref + ' does not exist.');

		var relField = refList.fields[relationship.refPath];
		if (!relField || relField.type !== 'relationship') throw new Error('List.getRelated: relationship ' + relationship.ref + ' on list ' + list.key + ' refers to a path (' + relationship.refPath + ') which is not a relationship field.');

		if (populateString.length) {

			_.each(populateString.split(' '), function(key) {
				if (refList.relationships[key])
					options.related.push(key);
				else
					options.populate.push(key);
			});

		}

		queue[relationship.path] = function(done) {

			var query = refList.model.find().where(relField.path);

			if (options.populate)
				query.populate(options.populate);

			if (relField.many) {
				query.in([item.id]);
			} else {
				query.equals(item.id);
			}

			query.sort(options.sort || relationship.sort || refList.defaultSort);

			if (options.related.length) {
				query.exec(function(err, results) {
					if (err || !results.length) {
						return done(err, results);
					}
					async.parallel(results.map(function(item) {
							return function(done) {
								item.populateRelated(options.related, done);
							};
						}),
						function(err) {
							done(err, results);
						}
					);
				});
			} else {
				query.exec(done);
			}

		};

		if (!item._populatedRelationships) item._populatedRelationships = {};
		item._populatedRelationships[relationship.path] = true;

	});

	async.parallel(queue, function(err, results) {
		if (!nocollapse && results && paths.length === 1) {
			results = results[paths[0]];
		}
		callback(err, results);
	});

};

methods.populateRelated = function(rel, callback) {

	var item = this;

	if ('function' !== typeof callback) {
		throw new Error('List.populateRelated(rel, callback) requires a callback function.');
	}

	this.getRelated(rel, function(err, results) {
		_.each(results, function(data, key) {
			item[key] = data;
		});
		callback(err, results);
	}, true);

};

options.transform = function(doc, ret) {
	if (doc._populatedRelationships) {
		_.each(doc._populatedRelationships, function(on, key) {
			if (!on) return;
			ret[key] = doc[key];
		});
	}
};
<|endoftext|>


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

// perjury.js -- command-line driver for perjury test scripts
//
// Copyright 2016 fuzzy.ai <evan@fuzzy.ai>
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* jshint esversion: 6 */

"use strict";

const path = require('path');

const _ = require('lodash');
const debug = require('debug')('perjury:command-line');

// This registers a hook so that coffeescript modules can be loaded

require('coffee-script/register');

const argv = require('yargs')
  .help('h')
  .argv;

let cwd = process.cwd();

let runTests = (testFileNames, callback) => {
  let broken = 0,
    successes = 0,
    failures = 0;

  let runNext = (filenames, callback) => {
    if (filenames.length > 0) {
      let testFileName = filenames[0];
      let testPath = path.join(cwd, testFileName);
      let runner = require(testPath);
      runner((err, suiteBroken, suiteSuccesses, suiteFailures) => {
        if (err) {
          console.error(err);
        }
        debug(`Finished suite ${testFileName}: ${suiteBroken}, ${suiteSuccesses}, ${suiteFailures}`);
        if (_.isNumber(suiteBroken)) {
          broken += suiteBroken;

        }
        if (_.isNumber(suiteSuccesses)) {
          successes += suiteSuccesses;
        }
        if (_.isNumber(suiteFailures)) {
          failures += suiteFailures;
        }
        runNext(filenames.slice(1), callback);
      });
    } else {
      callback(null);
    }
  };

  runNext(testFileNames, (err) => {
    if (err) {
      console.error(err);
    }
    debug(`Finished suites: ${broken}, ${successes}, ${failures}`);
    callback(null, broken, successes, failures);
  });
};

runTests(argv._, (err, broken, successes, failures) => {
  if (err) {
    console.error(err);
  } else {
    console.log("SUMMARY");
    console.log(`\tBroken:\t${broken}`);
    console.log(`\tSuccesses:\t${successes}`);
    console.log(`\tFailures:\t${failures}`);
    if (broken > 0 || failures > 0) {
      process.exit(1);
    } else {
      process.exit(0);
    }
  }
});
<commit_msg>Better async and summation in command-line script<commit_after>#!/usr/bin/env node

// perjury.js -- command-line driver for perjury test scripts
//
// Copyright 2016 fuzzy.ai <evan@fuzzy.ai>
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* jshint esversion: 6 */

"use strict";

const path = require('path');

const _ = require('lodash');
const async = require('async');
const debug = require('debug')('perjury:command-line');

// This registers a hook so that coffeescript modules can be loaded

require('coffee-script/register');

const argv = require('yargs')
  .help('h')
  .argv;

let cwd = process.cwd();

let broken = 0,
  successes = 0,
  failures = 0;

const runTestSuite = (testFileName, callback) => {
  let testPath = path.join(cwd, testFileName);
  let runner = require(testPath);
  if (!_.isFunction(runner)) {
    callback(new Error(`Path ${testFileName} does not return a function`));
  } else {
    runner((err, suiteBroken, suiteSuccesses, suiteFailures) => {
      if (err) {
        callback(err);
      } else if (!_.isNumber(suiteBroken)) {
        callback(new Error(`suiteBroken for ${testFileName} should be a number, is ${suiteBroken}`));
      } else if (!_.isNumber(suiteSuccesses)) {
        callback(new Error(`suiteSuccesses for ${testFileName} should be a number, is ${suiteSuccesses}`));
      } else if (!_.isNumber(suiteFailures)) {
        callback(new Error(`suiteFailures for ${testFileName} should be a number, is ${suiteFailures}`));
      } else {
        debug(`Finished suite ${testFileName}: ${suiteBroken}, ${suiteSuccesses}, ${suiteFailures}`);
        broken += suiteBroken;
        successes += suiteSuccesses;
        failures += suiteFailures;
        callback(null);
      }
    });
  }
};

async.eachSeries(argv._, runTestSuite, (err) => {
  if (err) {
    console.error(err);
  } else {
    console.log("SUMMARY");
    console.log(`\tBroken:\t\t${broken}`);
    console.log(`\tSuccesses:\t${successes}`);
    console.log(`\tFailures:\t${failures}`);
    if (broken > 0 || failures > 0) {
      process.exit(1);
    } else {
      process.exit(0);
    }
  }
});
<|endoftext|>


<commit_before>var echarts = require('echarts/lib/echarts');
var graphicGL = require('../../util/graphicGL');
var retrieve = require('../../util/retrieve');
var BarsGeometry = require('../../util/geometry/Bars3DGeometry');
var LabelsBuilder = require('../../component/common/LabelsBuilder');
var vec3 = require('qtek/lib/dep/glmatrix').vec3;

function getShader(shading) {
    var shader = graphicGL.createShader('ecgl.' + shading);
    shader.define('both', 'VERTEX_COLOR');
    return shader;
}

module.exports = echarts.extendChartView({

    type: 'bar3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new graphicGL.Node();

        var materials = {};
        graphicGL.COMMON_SHADERS.forEach(function (shading) {
            materials[shading] = new graphicGL.Material({
                shader: getShader(shading)
            });
        });

        this._materials = materials;

        this._api = api;

        this._labelsBuilder = new LabelsBuilder(256, 256, api);
        var self = this;
        this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
            if (self._data) {
                var layout = self._data.getItemLayout(dataIndex);
                var start = layout[0];
                var dir = layout[1];
                var height = layout[2][1];
                return vec3.scaleAndAdd([], start, dir, distance + height);
            }
            else {
                return [0, 0];
            }
        };

        // Give a large render order.
        this._labelsBuilder.getMesh().renderOrder = 100;
    },

    render: function (seriesModel, ecModel, api) {

        // Swap barMesh
        var tmp = this._prevBarMesh;
        this._prevBarMesh = this._barMesh;
        this._barMesh = tmp;

        if (!this._barMesh) {
            this._barMesh = new graphicGL.Mesh({
                geometry: new BarsGeometry(),
                shadowDepthMaterial: new graphicGL.Material({
                    shader: new graphicGL.Shader({
                        vertex: graphicGL.Shader.source('ecgl.sm.depth.vertex'),
                        fragment: graphicGL.Shader.source('ecgl.sm.depth.fragment')
                    })
                }),
                // Render after axes
                renderOrder: 10,
                // Render normal in normal pass
                renderNormal: true
            });
        }

        this.groupGL.remove(this._prevBarMesh);
        this.groupGL.add(this._barMesh);
        this.groupGL.add(this._labelsBuilder.getMesh());

        var coordSys = seriesModel.coordinateSystem;
        this._doRender(seriesModel, api);
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);

            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._barMesh.material.shader[methodName]('fragment', 'SRGB_DECODE');
        }

        this._data = seriesModel.getData();

        this._labelsBuilder.updateData(this._data);

        this._labelsBuilder.updateLabels();

        this._updateAnimation(seriesModel);
    },

    _updateAnimation: function (seriesModel) {
        graphicGL.updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevNormal', 'normal']],
            this._prevBarMesh,
            this._barMesh,
            seriesModel
        );
    },

    _doRender: function (seriesModel, api) {
        var data = seriesModel.getData();
        var shading = seriesModel.get('shading');
        var enableNormal = shading !== 'color';
        var self = this;
        var barMesh = this._barMesh;

        if (this._materials[shading]) {
            barMesh.material = this._materials[shading];
        }
        else {
            if (__DEV__) {
                console.warn('Unkown shading ' + shading);
            }
            barMesh.material = this._materials.lambert;
        }
        graphicGL.setMaterialFromModel(
            shading, barMesh.material, seriesModel, api
        );

        barMesh.geometry.enableNormal = enableNormal;

        barMesh.geometry.resetOffset();

        // Bevel settings
        var bevelSize = seriesModel.get('bevelSize');
        var bevelSegments = seriesModel.get('bevelSmoothness');
        barMesh.geometry.bevelSegments = bevelSegments;

        barMesh.geometry.bevelSize = bevelSize;

        var colorArr = [];
        var vertexColors = new Float32Array(data.count() * 4);
        var colorOffset = 0;
        var barCount = 0;
        var hasTransparent = false;

        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                return;
            }
            var color = data.getItemVisual(idx, 'color');

            var opacity = data.getItemVisual(idx, 'opacity');
            if (opacity == null) {
                opacity = 1;
            }

            graphicGL.parseColor(color, colorArr);
            colorArr[3] *= opacity;
            vertexColors[colorOffset++] = colorArr[0];
            vertexColors[colorOffset++] = colorArr[1];
            vertexColors[colorOffset++] = colorArr[2];
            vertexColors[colorOffset++] = colorArr[3];

            if (colorArr[3] > 0) {
                barCount++;
            }
            if (colorArr[3] < 0.99) {
                hasTransparent = true;
            }
        });

        barMesh.geometry.setBarCount(barCount);

        var orient = data.getLayout('orient');

        // Map of dataIndex and barIndex.
        var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
        var barCount = 0;
        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                barIndexOfData[idx] = -1;
                return;
            }
            var layout = data.getItemLayout(idx);
            var start = layout[0];
            var dir = layout[1];
            var size = layout[2];

            var idx4 = idx * 4;
            colorArr[0] = vertexColors[idx4++];
            colorArr[1] = vertexColors[idx4++];
            colorArr[2] = vertexColors[idx4++];
            colorArr[3] = vertexColors[idx4++];
            if (colorArr[3] > 0) {
                self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
            }

            barIndexOfData[idx] = barCount++;
        });

        barMesh.geometry.dirty();
        barMesh.geometry.updateBoundingBox();

        var material = barMesh.material;
        material.transparent = hasTransparent;
        material.depthMask = !hasTransparent;
        barMesh.geometry.sortTriangles = hasTransparent;

        this._initHandler(seriesModel, api);
    },

    _initHandler: function (seriesModel, api) {
        var data = seriesModel.getData();
        var barMesh = this._barMesh;
        var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';

        barMesh.seriesIndex = seriesModel.seriesIndex;

        var lastDataIndex = -1;
        barMesh.off('mousemove');
        barMesh.off('mouseout');
        barMesh.on('mousemove', function (e) {
            var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
            if (dataIndex !== lastDataIndex) {
                this._downplay(lastDataIndex);
                this._highlight(dataIndex);
                this._labelsBuilder.updateLabels([dataIndex]);

                if (isCartesian3D) {
                    api.dispatchAction({
                        type: 'grid3DShowAxisPointer',
                        value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex)]
                    });
                }
            }

            lastDataIndex = dataIndex;
            barMesh.dataIndex = dataIndex;
        }, this);
        barMesh.on('mouseout', function (e) {
            this._downplay(lastDataIndex);
            this._labelsBuilder.updateLabels();
            lastDataIndex = -1;
            barMesh.dataIndex = -1;

            if (isCartesian3D) {
                api.dispatchAction({
                    type: 'grid3DHideAxisPointer'
                });
            }
        }, this);
    },

    _highlight: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var itemModel = data.getItemModel(dataIndex);
        var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
        var emphasisColor = emphasisItemStyleModel.get('color');
        var emphasisOpacity = emphasisItemStyleModel.get('opacity');
        if (emphasisColor == null) {
            var color = data.getItemVisual(dataIndex, 'color');
            emphasisColor = echarts.color.lift(color, -0.4);
        }
        if (emphasisOpacity == null) {
            emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
        }
        var colorArr = graphicGL.parseColor(emphasisColor);
        colorArr[3] *= emphasisOpacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    _downplay: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var color = data.getItemVisual(dataIndex, 'color');
        var opacity = data.getItemVisual(dataIndex, 'opacity');

        var colorArr = graphicGL.parseColor(color);
        colorArr[3] *= opacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
});<commit_msg>Fix bar emphasis wrong when some bar are ignored<commit_after>var echarts = require('echarts/lib/echarts');
var graphicGL = require('../../util/graphicGL');
var retrieve = require('../../util/retrieve');
var BarsGeometry = require('../../util/geometry/Bars3DGeometry');
var LabelsBuilder = require('../../component/common/LabelsBuilder');
var vec3 = require('qtek/lib/dep/glmatrix').vec3;

function getShader(shading) {
    var shader = graphicGL.createShader('ecgl.' + shading);
    shader.define('both', 'VERTEX_COLOR');
    return shader;
}

module.exports = echarts.extendChartView({

    type: 'bar3D',

    __ecgl__: true,

    init: function (ecModel, api) {

        this.groupGL = new graphicGL.Node();

        var materials = {};
        graphicGL.COMMON_SHADERS.forEach(function (shading) {
            materials[shading] = new graphicGL.Material({
                shader: getShader(shading)
            });
        });

        this._materials = materials;

        this._api = api;

        this._labelsBuilder = new LabelsBuilder(256, 256, api);
        var self = this;
        this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
            if (self._data) {
                var layout = self._data.getItemLayout(dataIndex);
                var start = layout[0];
                var dir = layout[1];
                var height = layout[2][1];
                return vec3.scaleAndAdd([], start, dir, distance + height);
            }
            else {
                return [0, 0];
            }
        };

        // Give a large render order.
        this._labelsBuilder.getMesh().renderOrder = 100;
    },

    render: function (seriesModel, ecModel, api) {

        // Swap barMesh
        var tmp = this._prevBarMesh;
        this._prevBarMesh = this._barMesh;
        this._barMesh = tmp;

        if (!this._barMesh) {
            this._barMesh = new graphicGL.Mesh({
                geometry: new BarsGeometry(),
                shadowDepthMaterial: new graphicGL.Material({
                    shader: new graphicGL.Shader({
                        vertex: graphicGL.Shader.source('ecgl.sm.depth.vertex'),
                        fragment: graphicGL.Shader.source('ecgl.sm.depth.fragment')
                    })
                }),
                // Render after axes
                renderOrder: 10,
                // Render normal in normal pass
                renderNormal: true
            });
        }

        this.groupGL.remove(this._prevBarMesh);
        this.groupGL.add(this._barMesh);
        this.groupGL.add(this._labelsBuilder.getMesh());

        var coordSys = seriesModel.coordinateSystem;
        this._doRender(seriesModel, api);
        if (coordSys && coordSys.viewGL) {
            coordSys.viewGL.add(this.groupGL);

            var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
            this._barMesh.material.shader[methodName]('fragment', 'SRGB_DECODE');
        }

        this._data = seriesModel.getData();

        this._labelsBuilder.updateData(this._data);

        this._labelsBuilder.updateLabels();

        this._updateAnimation(seriesModel);
    },

    _updateAnimation: function (seriesModel) {
        graphicGL.updateVertexAnimation(
            [['prevPosition', 'position'],
            ['prevNormal', 'normal']],
            this._prevBarMesh,
            this._barMesh,
            seriesModel
        );
    },

    _doRender: function (seriesModel, api) {
        var data = seriesModel.getData();
        var shading = seriesModel.get('shading');
        var enableNormal = shading !== 'color';
        var self = this;
        var barMesh = this._barMesh;

        if (this._materials[shading]) {
            barMesh.material = this._materials[shading];
        }
        else {
            if (__DEV__) {
                console.warn('Unkown shading ' + shading);
            }
            barMesh.material = this._materials.lambert;
        }
        graphicGL.setMaterialFromModel(
            shading, barMesh.material, seriesModel, api
        );

        barMesh.geometry.enableNormal = enableNormal;

        barMesh.geometry.resetOffset();

        // Bevel settings
        var bevelSize = seriesModel.get('bevelSize');
        var bevelSegments = seriesModel.get('bevelSmoothness');
        barMesh.geometry.bevelSegments = bevelSegments;

        barMesh.geometry.bevelSize = bevelSize;

        var colorArr = [];
        var vertexColors = new Float32Array(data.count() * 4);
        var colorOffset = 0;
        var barCount = 0;
        var hasTransparent = false;

        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                return;
            }
            var color = data.getItemVisual(idx, 'color');

            var opacity = data.getItemVisual(idx, 'opacity');
            if (opacity == null) {
                opacity = 1;
            }

            graphicGL.parseColor(color, colorArr);
            colorArr[3] *= opacity;
            vertexColors[colorOffset++] = colorArr[0];
            vertexColors[colorOffset++] = colorArr[1];
            vertexColors[colorOffset++] = colorArr[2];
            vertexColors[colorOffset++] = colorArr[3];

            if (colorArr[3] > 0) {
                barCount++;
            }
            if (colorArr[3] < 0.99) {
                hasTransparent = true;
            }
        });

        barMesh.geometry.setBarCount(barCount);

        var orient = data.getLayout('orient');

        // Map of dataIndex and barIndex.
        var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
        var barCount = 0;
        data.each(function (idx) {
            if (!data.hasValue(idx)) {
                barIndexOfData[idx] = -1;
                return;
            }
            var layout = data.getItemLayout(idx);
            var start = layout[0];
            var dir = layout[1];
            var size = layout[2];

            var idx4 = idx * 4;
            colorArr[0] = vertexColors[idx4++];
            colorArr[1] = vertexColors[idx4++];
            colorArr[2] = vertexColors[idx4++];
            colorArr[3] = vertexColors[idx4++];
            if (colorArr[3] > 0) {
                self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
                barIndexOfData[idx] = barCount++;
            }
        });

        barMesh.geometry.dirty();
        barMesh.geometry.updateBoundingBox();

        var material = barMesh.material;
        material.transparent = hasTransparent;
        material.depthMask = !hasTransparent;
        barMesh.geometry.sortTriangles = hasTransparent;

        this._initHandler(seriesModel, api);
    },

    _initHandler: function (seriesModel, api) {
        var data = seriesModel.getData();
        var barMesh = this._barMesh;
        var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';

        barMesh.seriesIndex = seriesModel.seriesIndex;

        var lastDataIndex = -1;
        barMesh.off('mousemove');
        barMesh.off('mouseout');
        barMesh.on('mousemove', function (e) {
            var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
            if (dataIndex !== lastDataIndex) {
                this._downplay(lastDataIndex);
                this._highlight(dataIndex);
                this._labelsBuilder.updateLabels([dataIndex]);

                if (isCartesian3D) {
                    api.dispatchAction({
                        type: 'grid3DShowAxisPointer',
                        value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex)]
                    });
                }
            }

            lastDataIndex = dataIndex;
            barMesh.dataIndex = dataIndex;
        }, this);
        barMesh.on('mouseout', function (e) {
            this._downplay(lastDataIndex);
            this._labelsBuilder.updateLabels();
            lastDataIndex = -1;
            barMesh.dataIndex = -1;

            if (isCartesian3D) {
                api.dispatchAction({
                    type: 'grid3DHideAxisPointer'
                });
            }
        }, this);
    },

    _highlight: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var itemModel = data.getItemModel(dataIndex);
        var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
        var emphasisColor = emphasisItemStyleModel.get('color');
        var emphasisOpacity = emphasisItemStyleModel.get('opacity');
        if (emphasisColor == null) {
            var color = data.getItemVisual(dataIndex, 'color');
            emphasisColor = echarts.color.lift(color, -0.4);
        }
        if (emphasisOpacity == null) {
            emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
        }
        var colorArr = graphicGL.parseColor(emphasisColor);
        colorArr[3] *= emphasisOpacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    _downplay: function (dataIndex) {
        var data = this._data;
        if (!data) {
            return;
        }
        var barIndex = this._barIndexOfData[dataIndex];
        if (barIndex < 0) {
            return;
        }

        var color = data.getItemVisual(dataIndex, 'color');
        var opacity = data.getItemVisual(dataIndex, 'opacity');

        var colorArr = graphicGL.parseColor(color);
        colorArr[3] *= opacity;

        this._barMesh.geometry.setColor(barIndex, colorArr);

        this._api.getZr().refresh();
    },

    remove: function () {
        this.groupGL.removeAll();
    },

    dispose: function () {
        this.groupGL.removeAll();
    }
});<|endoftext|>


<commit_before>import React, { useState, useMemo } from 'react';
import {
    SubTitle,
    Row,
    Label,
    Field,
    Select,
    Loader,
    useEventManager,
    useCalendarUserSettings,
    useNotifications,
    useApi,
    useLoading,
    Checkbox
} from 'react-components';
import { c } from 'ttag';
import { updateCalendarUserSettings } from 'proton-shared/lib/api/calendars';
import updateLongLocale from 'proton-shared/lib/i18n/updateLongLocale';

import TimezoneSelector from '../../../components/TimezoneSelector';
import { SETTINGS_DATE_FORMAT, SETTINGS_TIME_FORMAT } from '../../../constants';
import { getTimezone } from 'proton-shared/lib/date/timezone';

const TimeSection = () => {
    const year = useMemo(() => new Date().getFullYear(), []);
    const [timezone] = useState(() => getTimezone());
    const api = useApi();
    const { call } = useEventManager();
    const { createNotification } = useNotifications();

    const [loadingDateFormat, withLoadingDateFormat] = useLoading();
    const [loadingTimeFormat, withLoadingTimeFormat] = useLoading();
    const [loadingAutoDetect, withLoadingAutoDetect] = useLoading();
    const [loadingPrimaryTimeZone, withLoadingPrimaryTimeZone] = useLoading();
    const [loadingSecondaryTimeZone, withLoadingSecondaryTimeZone] = useLoading();
    const [loadingDisplaySecondaryTimezone, withLoadingDisplaySecondaryTimezone] = useLoading();

    const [calendarSettings, loadingCalendarSettings] = useCalendarUserSettings();

    const handleChange = async (data) => {
        await api(updateCalendarUserSettings(data));
        await call();
        createNotification({ text: c('Success').t`Preference saved` });
    };

    const handleTimeFormat = async (value) => {
        await api(updateCalendarUserSettings({ TimeFormat: value }));
        await call();
        updateLongLocale({ displayAMPM: value === SETTINGS_TIME_FORMAT.H12 });
        createNotification({ text: c('Success').t`Preference saved` });
    };

    if (loadingCalendarSettings) {
        return (
            <>
                <SubTitle>{c('Title').t`Region & time zone`}</SubTitle>
                <Loader />
            </>
        );
    }

    const {
        AutoDetectPrimaryTimezone,
        DisplaySecondaryTimezone,
        DateFormat,
        TimeFormat,
        PrimaryTimezone,
        SecondaryTimezone
    } = calendarSettings;

    const primaryTimezoneValue = AutoDetectPrimaryTimezone ? timezone : PrimaryTimezone || timezone;
    const secondaryTimezoneValue = DisplaySecondaryTimezone
        ? SecondaryTimezone || timezone
        : SecondaryTimezone || timezone;

    return (
        <>
            <SubTitle>{c('Title').t`Region & time zone`}</SubTitle>
            <Row>
                {c('Label').t`Date format`}
                <Field>
                    <Select
                        id="date-format-select"
                        loading={loadingDateFormat}
                        onChange={({ target }) => withLoadingDateFormat(handleChange({ DateFormat: +target.value }))}
                        value={DateFormat}
                        options={[
                            { text: `12/31/${year}`, value: SETTINGS_DATE_FORMAT.DDMMYYYY },
                            { text: `31/12/${year}`, value: SETTINGS_DATE_FORMAT.MMDDYYYY },
                            { text: `${year}-12-31`, value: SETTINGS_DATE_FORMAT.YYYYMMDD }
                        ]}
                    />
                </Field>
            </Row>
            <Row>
                {c('Label').t`Time format`}
                <Field>
                    <Select
                        id="time-format-select"
                        loading={loadingTimeFormat}
                        onChange={({ target }) => withLoadingTimeFormat(handleTimeFormat(+target.value))}
                        value={TimeFormat}
                        options={[
                            { text: '12h', value: SETTINGS_TIME_FORMAT.H12 },
                            { text: '24h', value: SETTINGS_TIME_FORMAT.H24 }
                        ]}
                    />
                </Field>
            </Row>
            <Row>
                {c('Primary timezone').t`Primary time zone`}
                <Field className="pt0-25">

                        <Checkbox
                            disabled={loadingAutoDetect}
                            checked={!!AutoDetectPrimaryTimezone}
                            onChange={({ target }) =>
                                withLoadingAutoDetect(
                                    handleChange({
                                        AutoDetectPrimaryTimezone: +target.checked,
                                        // Set a timezone if it's the first time
                                        PrimaryTimezone: !PrimaryTimezone ? primaryTimezoneValue : undefined
                                    })
                                )
                            }
                        >{c('Checkbox').t`Auto-detect`}</Checkbox>

                        <TimezoneSelector
                            loading={loadingPrimaryTimeZone}
                            disabled={!!AutoDetectPrimaryTimezone}
                            timezone={primaryTimezoneValue}
                            onChange={(PrimaryTimezone) =>
                                withLoadingPrimaryTimeZone(handleChange({ PrimaryTimezone }))
                            }
                        />

                </Field>
            </Row>
            <Row>
                {c('Secondary timezone').t`Secondary time zone`}
                <Field className="pt0-25">

                        <Checkbox
                            disabled={loadingDisplaySecondaryTimezone}
                            checked={!!DisplaySecondaryTimezone}
                            onChange={({ target }) =>
                                withLoadingDisplaySecondaryTimezone(
                                    handleChange({
                                        DisplaySecondaryTimezone: +target.checked,
                                        // Set a timezone if it's the first time
                                        SecondaryTimezone: !SecondaryTimezone ? secondaryTimezoneValue : undefined
                                    })
                                )
                            }
                        >{c('Checkbox').t`Show secondary time zone`}</Checkbox>

                        <TimezoneSelector
                            loading={loadingSecondaryTimeZone}
                            disabled={!DisplaySecondaryTimezone}
                            timezone={secondaryTimezoneValue}
                            onChange={(SecondaryTimezone) =>
                                withLoadingSecondaryTimeZone(handleChange({ SecondaryTimezone }))
                            }
                        />

                </Field>
            </Row>
        </>
    );
};

export default TimeSection;
<commit_msg>Fix #108 - Hide date format<commit_after>import React, { useState, useMemo } from 'react';
import {
    SubTitle,
    Row,
    Label,
    Field,
    Select,
    Loader,
    useEventManager,
    useCalendarUserSettings,
    useNotifications,
    useApi,
    useLoading,
    Checkbox
} from 'react-components';
import { c } from 'ttag';
import { updateCalendarUserSettings } from 'proton-shared/lib/api/calendars';
import updateLongLocale from 'proton-shared/lib/i18n/updateLongLocale';

import TimezoneSelector from '../../../components/TimezoneSelector';
import { SETTINGS_DATE_FORMAT, SETTINGS_TIME_FORMAT } from '../../../constants';
import { getTimezone } from 'proton-shared/lib/date/timezone';

const TimeSection = () => {
    const year = useMemo(() => new Date().getFullYear(), []);
    const [timezone] = useState(() => getTimezone());
    const api = useApi();
    const { call } = useEventManager();
    const { createNotification } = useNotifications();

    const [loadingDateFormat, withLoadingDateFormat] = useLoading();
    const [loadingTimeFormat, withLoadingTimeFormat] = useLoading();
    const [loadingAutoDetect, withLoadingAutoDetect] = useLoading();
    const [loadingPrimaryTimeZone, withLoadingPrimaryTimeZone] = useLoading();
    const [loadingSecondaryTimeZone, withLoadingSecondaryTimeZone] = useLoading();
    const [loadingDisplaySecondaryTimezone, withLoadingDisplaySecondaryTimezone] = useLoading();

    const [calendarSettings, loadingCalendarSettings] = useCalendarUserSettings();

    const handleChange = async (data) => {
        await api(updateCalendarUserSettings(data));
        await call();
        createNotification({ text: c('Success').t`Preference saved` });
    };

    const handleTimeFormat = async (value) => {
        await api(updateCalendarUserSettings({ TimeFormat: value }));
        await call();
        updateLongLocale({ displayAMPM: value === SETTINGS_TIME_FORMAT.H12 });
        createNotification({ text: c('Success').t`Preference saved` });
    };

    if (loadingCalendarSettings) {
        return (
            <>
                <SubTitle>{c('Title').t`Region & time zone`}</SubTitle>
                <Loader />
            </>
        );
    }

    const {
        AutoDetectPrimaryTimezone,
        DisplaySecondaryTimezone,
        DateFormat,
        TimeFormat,
        PrimaryTimezone,
        SecondaryTimezone
    } = calendarSettings;

    const primaryTimezoneValue = AutoDetectPrimaryTimezone ? timezone : PrimaryTimezone || timezone;
    const secondaryTimezoneValue = DisplaySecondaryTimezone
        ? SecondaryTimezone || timezone
        : SecondaryTimezone || timezone;

    return (
        <>
            <SubTitle>{c('Title').t`Region & time zone`}</SubTitle>
            <Row>
                {c('Label').t`Date format`}
                <Field>
                    <Select
                        id="date-format-select"
                        loading={loadingDateFormat}
                        onChange={({ target }) => withLoadingDateFormat(handleChange({ DateFormat: +target.value }))}
                        value={DateFormat}
                        options={[
                            { text: `12/31/${year}`, value: SETTINGS_DATE_FORMAT.DDMMYYYY },
                            { text: `31/12/${year}`, value: SETTINGS_DATE_FORMAT.MMDDYYYY }
                        ]}
                    />
                </Field>
            </Row>
            <Row>
                {c('Label').t`Time format`}
                <Field>
                    <Select
                        id="time-format-select"
                        loading={loadingTimeFormat}
                        onChange={({ target }) => withLoadingTimeFormat(handleTimeFormat(+target.value))}
                        value={TimeFormat}
                        options={[
                            { text: '12h', value: SETTINGS_TIME_FORMAT.H12 },
                            { text: '24h', value: SETTINGS_TIME_FORMAT.H24 }
                        ]}
                    />
                </Field>
            </Row>
            <Row>
                {c('Primary timezone').t`Primary time zone`}
                <Field className="pt0-25">

                        <Checkbox
                            disabled={loadingAutoDetect}
                            checked={!!AutoDetectPrimaryTimezone}
                            onChange={({ target }) =>
                                withLoadingAutoDetect(
                                    handleChange({
                                        AutoDetectPrimaryTimezone: +target.checked,
                                        // Set a timezone if it's the first time
                                        PrimaryTimezone: !PrimaryTimezone ? primaryTimezoneValue : undefined
                                    })
                                )
                            }
                        >{c('Checkbox').t`Auto-detect`}</Checkbox>

                        <TimezoneSelector
                            loading={loadingPrimaryTimeZone}
                            disabled={!!AutoDetectPrimaryTimezone}
                            timezone={primaryTimezoneValue}
                            onChange={(PrimaryTimezone) =>
                                withLoadingPrimaryTimeZone(handleChange({ PrimaryTimezone }))
                            }
                        />

                </Field>
            </Row>
            <Row>
                {c('Secondary timezone').t`Secondary time zone`}
                <Field className="pt0-25">

                        <Checkbox
                            disabled={loadingDisplaySecondaryTimezone}
                            checked={!!DisplaySecondaryTimezone}
                            onChange={({ target }) =>
                                withLoadingDisplaySecondaryTimezone(
                                    handleChange({
                                        DisplaySecondaryTimezone: +target.checked,
                                        // Set a timezone if it's the first time
                                        SecondaryTimezone: !SecondaryTimezone ? secondaryTimezoneValue : undefined
                                    })
                                )
                            }
                        >{c('Checkbox').t`Show secondary time zone`}</Checkbox>

                        <TimezoneSelector
                            loading={loadingSecondaryTimeZone}
                            disabled={!DisplaySecondaryTimezone}
                            timezone={secondaryTimezoneValue}
                            onChange={(SecondaryTimezone) =>
                                withLoadingSecondaryTimeZone(handleChange({ SecondaryTimezone }))
                            }
                        />

                </Field>
            </Row>
        </>
    );
};

export default TimeSection;
<|endoftext|>


<commit_before>module.exports = (function() {
    "use strict";

    var _ = require("underscore");
    var pathlib = require("path");

    var UseMap = require("./lib/usemap");
    var UseLoader = require("./lib/loader");

    var UseImporter = function() {
        var self = this,
            useMap = new UseMap();

        // public api

        /**
         * Require module by name
         * @param  {String} name Valid/configured name for module
         * @return {*}
         */
        this.use = function(name) {
            if (!useMap.isConfigured) {
                throw new Error("USE_IMPORTER_NOT_CONFIGURED");
            }
            var namePath = useMap.getPath(name);
            if (_.isUndefined(namePath)) {
                throw new Error("USE_IMPORTER_MODULE_NOT_FOUND");
            }
            return require(namePath);
        };

        /**
         * Loads config information from a use.json or project.json file on the
         * requesting module"s filepath
         * @param  {String} filePath Optional. Path to a specific JSON config
         *                           file to load.
         * @return {Function}        Returns the use function. Useful for
         *                           chaining.
         */
        this.use.load = function() {
            if (arguments.length > 0) {
                self.load(arguments[0]);
            } else {
                self.load();
            }
            return self.use;
        };

        /**
         * Configures use-import
         * @param  {Object} map     Object with name => module relative path
         *                          key-value pairs.
         * @param  {String} rootDir Optional. The root directory the module
         *                          paths are given in relation to. Defaults to
         *                          the root directory of the first module to
         *                          require use-import.
         * @return {Function}       Returns the `use` function. Useful for
         *                          chaining.
         */
        this.use.config = function(map) {
            if (arguments.length > 1 && !_.isEmpty(arguments[1])) {
                useMap.config(map, arguments[1]);
            } else if (!useMap.isConfigured) {
                useMap.config(map, pathlib.dirname(module.parent.filename));
            } else {
                useMap.config(map);
            }
            return self.use;
        };

        /**
         * Returns the relative file path for the given name
         * @param  {String} name Valid name for a module
         * @return {String}      Filepath if found, undefined otherwise
         */
        this.use.resolve = function(name) {
            if (!useMap.isConfigured) {
                return undefined;
            }
            return useMap.getPath(name);
        };

        /**
         * Clears out all loaded data. Mostly useful for unit tests, or other
         * situations where there might not be just one entry point.
         */
        this.use.unload = function() {
            useMap.dispose();
        };

        /* getter for isLoaded */
        this.use.__defineGetter__("isLoaded", function() {
            return useMap.isConfigured;
        });

        // protected functions

        this.load = function() {
            // check for filePath property
            var filePath;
            if (arguments.length > 0 && !_.isEmpty(arguments[0])) {
                filePath = arguments[0];
            }
            if (!useMap.isConfigured ||
                (!_.isUndefined(filePath) && !useMap.isFileLoaded(filePath))) {
                var loader = new UseLoader();
                var r;
                if (!_.isUndefined(filePath)) {
                    r = loader.loadFile(filePath, useMap);
                } else {
                    r = loader.load(module.parent.filename, useMap);
                }
                if (!r) {
                    throw new Error("USE_IMPORTER_CONFIG_FILE_NOT_FOUND");
                }
            } else {
                throw new Error("USE_IMPORTER_LOAD_CALLED_TWICE");
            }
        };
    };

    var useImporter = new UseImporter();
    return useImporter.use;
})();<commit_msg>fix use.config bug<commit_after>module.exports = (function() {
    "use strict";

    var _ = require("underscore");
    var pathlib = require("path");

    var UseMap = require("./lib/usemap");
    var UseLoader = require("./lib/loader");

    var UseImporter = function() {
        var self = this,
            useMap = new UseMap();

        // public api

        /**
         * Require module by name
         * @param  {String} name Valid/configured name for module
         * @return {*}
         */
        this.use = function(name) {
            if (!useMap.isConfigured) {
                throw new Error("USE_IMPORTER_NOT_CONFIGURED");
            }
            var namePath = useMap.getPath(name);
            if (_.isUndefined(namePath)) {
                throw new Error("USE_IMPORTER_MODULE_NOT_FOUND");
            }
            return require(namePath);
        };

        /**
         * Loads config information from a use.json or project.json file on the
         * requesting module"s filepath
         * @param  {String} filePath Optional. Path to a specific JSON config
         *                           file to load.
         * @return {Function}        Returns the use function. Useful for
         *                           chaining.
         */
        this.use.load = function() {
            if (arguments.length > 0) {
                self.load(arguments[0]);
            } else {
                self.load();
            }
            return self.use;
        };

        /**
         * Configures use-import
         * @param  {Object} map     Object with name => module relative path
         *                          key-value pairs.
         * @param  {String} rootDir Optional. The root directory the module
         *                          paths are given in relation to. Defaults to
         *                          the root directory of the first module to
         *                          require use-import.
         * @return {Function}       Returns the `use` function. Useful for
         *                          chaining.
         */
        this.use.config = function(map) {
            if (arguments.length > 1 && !_.isEmpty(arguments[1])) {
                useMap.config(map, arguments[1]);
            } else if (!useMap.isConfigured) {
                useMap.config(map, {
                    rootDir: pathlib.dirname(module.parent.filename)
                });
            } else {
                useMap.config(map);
            }
            return self.use;
        };

        /**
         * Returns the relative file path for the given name
         * @param  {String} name Valid name for a module
         * @return {String}      Filepath if found, undefined otherwise
         */
        this.use.resolve = function(name) {
            if (!useMap.isConfigured) {
                return undefined;
            }
            return useMap.getPath(name);
        };

        /**
         * Clears out all loaded data. Mostly useful for unit tests, or other
         * situations where there might not be just one entry point.
         */
        this.use.unload = function() {
            useMap.dispose();
        };

        /* getter for isLoaded */
        this.use.__defineGetter__("isLoaded", function() {
            return useMap.isConfigured;
        });

        // protected functions

        this.load = function() {
            // check for filePath property
            var filePath;
            if (arguments.length > 0 && !_.isEmpty(arguments[0])) {
                filePath = arguments[0];
            }
            if (!useMap.isConfigured ||
                (!_.isUndefined(filePath) && !useMap.isFileLoaded(filePath))) {
                var loader = new UseLoader();
                var r;
                if (!_.isUndefined(filePath)) {
                    r = loader.loadFile(filePath, useMap);
                } else {
                    r = loader.load(module.parent.filename, useMap);
                }
                if (!r) {
                    throw new Error("USE_IMPORTER_CONFIG_FILE_NOT_FOUND");
                }
            } else {
                throw new Error("USE_IMPORTER_LOAD_CALLED_TWICE");
            }
        };
    };

    var useImporter = new UseImporter();
    return useImporter.use;
})();<|endoftext|>


<commit_before>import { createMutator, updateMutator, deleteMutator, Utils, Connectors, registerCallback } from 'meteor/vulcan:lib';
import Users from './collection'; // TODO: circular dependency?

const performCheck = (mutation, user, document) => {
  if (!mutation.check(user, document))
    throw new Error(
      Utils.encodeIntlError({ id: `app.mutation_not_allowed`, value: `"${mutation.name}" on _id "${document._id}"` })
    );
};

const createMutation = {
  name: 'createUser',

  check(user, document) {
    if (!user) return false;
    // OpenCRUD backwards compatibility
    return Users.canDo(user, ['user.create', 'users.new']);
  },

  mutation(root, { data }, context) {
    const { Users, currentUser } = context;
    performCheck(this, currentUser, data);

    return createMutator({
      collection: Users,
      data,
      currentUser,
      validate: true,
      context,
    });
  },
};

const updateMutation = {
  name: 'updateUser',

  check(user, document) {
    if (!user || !document) return false;
    // OpenCRUD backwards compatibility
    return Users.owns(user, document) ? Users.canDo(user, ['user.update.own', 'users.edit.own']) : Users.canDo(user, [`user.update.all`, `users.edit.all`]);
  },

  async mutation(root, { selector, data }, context) {
    const { Users, currentUser } = context;

    const document = await Connectors.get(Users, selector);
    performCheck(this, currentUser, document);

    return updateMutator({
      collection: Users,
      selector,
      data,
      currentUser,
      validate: true,
      context,
    });
  },
};

const deleteMutation = {
  name: 'deleteUser',

  check(user, document) {
    if (!user || !document) return false;
    // OpenCRUD backwards compatibility
    return Users.owns(user, document) ? Users.canDo(user, ['user.delete.own', 'users.remove.own']) : Users.canDo(user, [`user.delete.all`, `users.remove.all`]);
  },

  async mutation(root, { selector }, context) {

    const { Users, currentUser } = context;

    const document = await Connectors.get(Users, selector);
    performCheck(this, currentUser, document);

    return deleteMutator({
      collection: Users,
      selector,
      currentUser,
      validate: true,
      context,
    });
  },
};
const mutations = {
  create: createMutation,
  update: updateMutation,
  delete: deleteMutation,

  // OpenCRUD backwards compatibility

  new: createMutation,
  edit: updateMutation,
  remove: deleteMutation,
};

export default mutations;

registerCallback({
  name:'user.create.validate',
  iterator: {document:'the document being inserted'},
  properties: [
    { document: 'The document being inserted' },
    { currentUser: 'The current user' },
    { validationErrors: 'An object that can be used to accumulate validation errors' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Validate a document before insertion (can be skipped when inserting directly on server).`,
});
registerCallback({
  name:'user.create.before',
  iterator: {document:'the document being inserted'},
  properties: [
    { document: 'The document being inserted' },
    { currentUser: 'The current user' },
    { validationErrors: 'An object that can be used to accumulate validation errors' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Perform operations on a new document before it's inserted in the database.`,
});
registerCallback({
  name:'user.create.after',
  iterator: {document:'the document after being inserted in the database'},
  properties: [
    { currentUser: 'The current user' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Perform operations on a new document after it's inserted in the database but *before* the mutation returns it.`,
});
registerCallback({
  name:'user.create.async',
  iterator: {data:'the document after being inserted in the database'},
  properties: [
    {insertedDocument: 'The document that was inserted to the collection'},
    { currentUser: 'The current user' },
    {collection: 'The Users collection'}
  ],
  runs: 'async',
  returns: 'document',
  description: `Perform operations on a new document after it's inserted in the database asynchronously.`,
});
registerCallback({
  name: 'user.update.validate',
  iterator: {data: 'The client data'},
  properties: [
    {document: 'The document being updated'},
    {currentUser: 'The current user.'},
    {validationErrors: 'an object that can be used to accumulate validation errors.'},
  ],
  runs: 'sync',
  description: 'Validate a document before update (can be skipped when updating directly on server).'
});
registerCallback({
  name: 'user.update.before',
  iterator: {data:'The client data'},
  properties: [
    {document: 'The document being edited'},
    {currentUser: 'The current user'},
    {newDocument: 'A preview of the future document'},
  ],
  runs: 'sync',
  description: `Perform operations on a document before it's updated on the database.`,
});
registerCallback({
  name: 'user.update.after',
  iterator: {newdocument: 'The document after the update'},
  properties: [
    {document: 'The document before the update'},
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Perform operations on a document after it's updated in the database but *before* the mutation returns it.`
});
registerCallback({
  name: 'user.update.async',
  properties: [
    {newDocument: 'The document after the update'},
    {document: 'The document before the update'},
    {currentUser: 'The current user'},
    {collection: 'The Users collection'},
  ],
  runs: 'async',
  description: `Perform operations on a document after it's updated in the database asynchronously.`
});
registerCallback({
  name: 'user.delete.validate',
  iterator: {document: 'The document being deleted'},
  properties: [
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Validate a document before deletion (can be skipped when deleting directly on the server)`
});
registerCallback({
  name: 'user.delete.before',
  iterator: {document: 'The document being deleted'},
  properties: [
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Perform operations on a document before it's deleted from the database`,
});
registerCallback({
  name: 'user.delete.async',
  properties:[
    {document: 'The document being deleted'},
    {currentUser: 'The current user'},
    {collection: 'The Users collection'},
  ],
  runs: 'async',
  description: `Perform operations on a document after it's deleted from the database asynchronously.`
});
<commit_msg>Better use mutations<commit_after>import { createMutator, updateMutator, deleteMutator, Utils, Connectors, registerCallback } from 'meteor/vulcan:lib';
import Users from './collection'; // TODO: circular dependency?

const performCheck = (mutation, user, document) => {
  if (!mutation.check(user, document))
    throw new Error(
      Utils.encodeIntlError({ id: `app.mutation_not_allowed`, value: `"${mutation.name}" on _id "${document._id}"` })
    );
};

const createMutation = {
  name: 'createUser',

  check(user, document) {
    if (!user) return false;
    // OpenCRUD backwards compatibility
    return Users.canDo(user, ['user.create', 'users.new']);
  },

  mutation(root, { data }, context) {
    const { Users, currentUser } = context;
    performCheck(this, currentUser, data);

    return createMutator({
      collection: Users,
      data,
      currentUser,
      validate: true,
      context,
    });
  },
};

const updateMutation = {
  name: 'updateUser',

  check(user, document) {
    if (!user || !document) return false;
    // OpenCRUD backwards compatibility
    return Users.owns(user, document) ? Users.canDo(user, ['user.update.own', 'users.edit.own']) : Users.canDo(user, [`user.update.all`, `users.edit.all`]);
  },

  async mutation(root, { selector, data }, context) {
    const { Users, currentUser } = context;

    const document = await Connectors.get(Users, selector);

    if (!document) {
      throw new Error(`Could not find document to update for selector: ${JSON.stringify(selector)}`);
    }

    performCheck(this, currentUser, document);

    return updateMutator({
      collection: Users,
      selector,
      data,
      currentUser,
      validate: true,
      context,
    });
  },
};

const deleteMutation = {
  name: 'deleteUser',

  check(user, document) {
    if (!user || !document) return false;
    // OpenCRUD backwards compatibility
    return Users.owns(user, document) ? Users.canDo(user, ['user.delete.own', 'users.remove.own']) : Users.canDo(user, [`user.delete.all`, `users.remove.all`]);
  },

  async mutation(root, { selector }, context) {

    const { Users, currentUser } = context;

    const document = await Connectors.get(Users, selector);

    if (!document) {
      throw new Error(`Could not find document to delete for selector: ${JSON.stringify(selector)}`);
    }

    performCheck(this, currentUser, document);

    return deleteMutator({
      collection: Users,
      selector,
      currentUser,
      validate: true,
      context,
    });
  },
};
const mutations = {
  create: createMutation,
  update: updateMutation,
  delete: deleteMutation,

  // OpenCRUD backwards compatibility

  new: createMutation,
  edit: updateMutation,
  remove: deleteMutation,
};

export default mutations;

registerCallback({
  name:'user.create.validate',
  iterator: {document:'the document being inserted'},
  properties: [
    { document: 'The document being inserted' },
    { currentUser: 'The current user' },
    { validationErrors: 'An object that can be used to accumulate validation errors' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Validate a document before insertion (can be skipped when inserting directly on server).`,
});
registerCallback({
  name:'user.create.before',
  iterator: {document:'the document being inserted'},
  properties: [
    { document: 'The document being inserted' },
    { currentUser: 'The current user' },
    { validationErrors: 'An object that can be used to accumulate validation errors' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Perform operations on a new document before it's inserted in the database.`,
});
registerCallback({
  name:'user.create.after',
  iterator: {document:'the document after being inserted in the database'},
  properties: [
    { currentUser: 'The current user' },
  ],
  runs: 'sync',
  returns: 'document',
  description: `Perform operations on a new document after it's inserted in the database but *before* the mutation returns it.`,
});
registerCallback({
  name:'user.create.async',
  iterator: {data:'the document after being inserted in the database'},
  properties: [
    {insertedDocument: 'The document that was inserted to the collection'},
    { currentUser: 'The current user' },
    {collection: 'The Users collection'}
  ],
  runs: 'async',
  returns: 'document',
  description: `Perform operations on a new document after it's inserted in the database asynchronously.`,
});
registerCallback({
  name: 'user.update.validate',
  iterator: {data: 'The client data'},
  properties: [
    {document: 'The document being updated'},
    {currentUser: 'The current user.'},
    {validationErrors: 'an object that can be used to accumulate validation errors.'},
  ],
  runs: 'sync',
  description: 'Validate a document before update (can be skipped when updating directly on server).'
});
registerCallback({
  name: 'user.update.before',
  iterator: {data:'The client data'},
  properties: [
    {document: 'The document being edited'},
    {currentUser: 'The current user'},
    {newDocument: 'A preview of the future document'},
  ],
  runs: 'sync',
  description: `Perform operations on a document before it's updated on the database.`,
});
registerCallback({
  name: 'user.update.after',
  iterator: {newdocument: 'The document after the update'},
  properties: [
    {document: 'The document before the update'},
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Perform operations on a document after it's updated in the database but *before* the mutation returns it.`
});
registerCallback({
  name: 'user.update.async',
  properties: [
    {newDocument: 'The document after the update'},
    {document: 'The document before the update'},
    {currentUser: 'The current user'},
    {collection: 'The Users collection'},
  ],
  runs: 'async',
  description: `Perform operations on a document after it's updated in the database asynchronously.`
});
registerCallback({
  name: 'user.delete.validate',
  iterator: {document: 'The document being deleted'},
  properties: [
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Validate a document before deletion (can be skipped when deleting directly on the server)`
});
registerCallback({
  name: 'user.delete.before',
  iterator: {document: 'The document being deleted'},
  properties: [
    {currentUser: 'The current user'},
  ],
  runs: 'sync',
  description: `Perform operations on a document before it's deleted from the database`,
});
registerCallback({
  name: 'user.delete.async',
  properties:[
    {document: 'The document being deleted'},
    {currentUser: 'The current user'},
    {collection: 'The Users collection'},
  ],
  runs: 'async',
  description: `Perform operations on a document after it's deleted from the database asynchronously.`
});
<|endoftext|>


<commit_before>// Config object to be passed to Msal on creation
const msalConfig = {
    auth: {
        clientId: "e3b9ad76-9763-4827-b088-80c7a7888f79",
        authority: "https://login.microsoftonline.com/tfp/msidlabb2c.onmicrosoft.com/B2C_1_SISOPolicy/",
        knownAuthorities: ["login.microsoftonline.com"]
    },
    cache: {
        cacheLocation: "localStorage", // This configures where your cache will be stored
        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
    },
    system: {
        telemetry: {
            applicationName: 'msalVanillaTestApp',
            applicationVersion: 'test1.0',
            telemetryEmitter: (events) => {
                console.log("Telemetry Events", events);
            }
        }
    }
};

// Add here scopes for id token to be used at MS Identity Platform endpoints.
const loginRequest = {
    scopes: ["https://msidlabb2c.onmicrosoft.com/msidlabb2capi/read"],
    forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};<commit_msg>Remove telemetry config from 2.0 sample<commit_after>// Config object to be passed to Msal on creation
const msalConfig = {
    auth: {
        clientId: "e3b9ad76-9763-4827-b088-80c7a7888f79",
        authority: "https://login.microsoftonline.com/tfp/msidlabb2c.onmicrosoft.com/B2C_1_SISOPolicy/",
        knownAuthorities: ["login.microsoftonline.com"]
    },
    cache: {
        cacheLocation: "localStorage", // This configures where your cache will be stored
        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
    }
};

// Add here scopes for id token to be used at MS Identity Platform endpoints.
const loginRequest = {
    scopes: ["https://msidlabb2c.onmicrosoft.com/msidlabb2capi/read"],
    forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};<|endoftext|>