<commit_before>/**
 * @package assets
 */

(function($) {

	/**
	 * This plugin creates a Symphony duplicator.
	 *
	 * @name $.symphonyDuplicator
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.instances='> li:not(.template)'] Selector to find children to use as instances
	 * @param {String} [options.templates='> li.template'] Selector to find children to use as templates
	 * @param {String} [options.headers='> :first-child'] Selector to find the header part of each instance
	 * @param {String} [options.perselect=false] Default option for the selector
	 * @param {Boolean} [options.orderable=false] Can instances be ordered
	 * @param {Boolean} [options.collapsible=false] Can instances be collapsed
	 * @param {Boolean} [options.constructable=true] Allow construction of new instances
	 * @param {Boolean} [options.destructable=true] Allow destruction of instances
	 * @param {Integer} [optionss.minimum=0] Do not allow instances to be removed below this limit
	 * @param {Integer} [options.maximum=1000] Do not allow instances to be added above this limit
	 * @param {String} [options.speed='fast'] Animation speed
	 *
	 *	@example

			$('.duplicator').symphonyDuplicator({
				orderable: true,
				collapsible: true
			});
	 */
	$.fn.symphonyDuplicator = function(options) {
		var objects = this,
			settings = {
				instances:			'> li:not(.template)',
				templates:			'> li.template',
				headers:			'> :first-child',
				preselect:			false,
				orderable:			false,
				collapsible:		false,
				constructable:		true,
				destructable:		true,
				minimum:			0,
				maximum:			1000,
				speed:				'fast'
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		// Language strings
		Symphony.Language.add({
			'Add item': false,
			'Remove item': false
		});

	/*-----------------------------------------------------------------------*/

		objects.each(function duplicators() {
			var object = $(this),
				instances = object.find(settings.instances).addClass('instance'),
				templates = object.find(settings.templates).addClass('template'),
				items = instances.add(templates),
				headers = items.find(settings.headers),
				duplicator = object.parent('.frame'),
				apply = $('<fieldset class="apply" />'),
				selector = $('<select />'),
				constructor = $('<button class="constructor">' + Symphony.Language.get('Add item') + '</button>');

			// Check duplicator frame
			if(duplicator.length == 0) {
				duplicator = $('
').insertBefore(object).prepend(object);
			}
			else {
				duplicator.addClass('frame').addClass('empty');
			}

		/*-------------------------------------------------------------------*/

			// Construct instances
			apply.on('click.duplicator', 'button.constructor:not(.disabled)', function construct(event, speed) {
				var instance = templates.filter('[data-type="' + $(this).prev('select').val() + '"]').clone();

				event.preventDefault();

				instance.trigger('constructstart.duplicator');
				instance.trigger('construct.duplicator'); /* deprecated */
				instance.hide().appendTo(object);

				// Duplicator is not empty
				duplicator.removeClass('empty');

				// Set speed
				if(!speed) {
					speed = settings.speed;
				}

				// Show instance
				instance.trigger('constructshow.duplicator');
				instance.slideDown(speed, function() {

					// Focus first input
					instance.find('input[type!="hidden"]:first').focus();
					instance.trigger('constructstop.duplicator');
				});
			});

			// Destruct instances
			duplicator.on('click.duplicator', 'a.destructor:not(.disabled)', function destruct(event) {
				var instance = $(this).parents('.instance:first');

				instance.trigger('destructstart.duplicator');
				instance.trigger('destruct.duplicator'); /* deprecated */
				instance.slideUp(settings.speed, function() {
					$(this).remove();

					// Check if duplicator is empty
					if(duplicator.find('.instance').length == 0) {
						duplicator.addClass('empty');
					}

					instance.trigger('destructstop.duplicator');
				});
			});

			// Lock constructor
			duplicator.on('constructstop.duplicator', '.instance', function lockConstructor() {
				if(duplicator.find('.instance').length >= settings.maximum) {
					constructor.addClass('disabled');
				}
			});

			// Unlock constructor
			duplicator.on('destructstart.duplicator', '.instance', function unlockConstructor() {
				if(duplicator.find('.instance').length <= settings.maximum) {
					constructor.removeClass('disabled');
				}
			});

			// Lock destructor
			duplicator.on('destructstart.duplicator', '.instance', function lockDestructor() {
				if(duplicator.find('.instance').length - 1 == settings.minimum) {
					duplicator.find('a.destructor').addClass('disabled');
				}
			});

			// Unlock destructor
			duplicator.on('constructstop.duplicator', '.instance', function unlockDestructor() {
				if(duplicator.find('.instance').length > settings.minimum) {
					duplicator.find('a.destructor').removeClass('disabled');
				}
			});

			// Lock unique instances
			duplicator.on('constructstop.duplicator', '.instance', function lockUnique(event) {
				var instance = $(this);

				if(instance.is('.unique')) {
					selector.find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', true);

					// Preselect first available instance
					selector.find('option').attr('selected', false).filter(':not(:disabled):first').attr('selected', true);

					// All selected
					if(selector.find('option:not(:disabled)').length == 0) {
						selector.attr('disabled', 'disabled');
					}
				}
			});

			// Unlock unique instances
			duplicator.on('destructstart.duplicator', '.instance', function unlockUnique(event) {
				var instance = $(this),
					option;

				if(instance.is('.unique')) {
					option = selector.attr('disabled', false).find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', false);

					// Preselect instance if it's the only active one
					if(selector.find('option:not(:disabled)').length == 1) {
						option.attr('selected', true);
					}
				}
			});

			// Build field indexes
			duplicator.on('constructstop.duplicator refresh.duplicator', '.instance', function buildIndexes(event) {
				var instance = $(this),
					position = duplicator.find('.instance').index(instance);

				// Loop over named fields
				instance.find('*[name]').each(function() {
					var field = $(this),
						exp = /\[\-?[0-9]+\]/,
						name = field.attr('name');

					// Set index
					if(exp.test(name)) {
						field.attr('name', name.replace(exp, '[' + position + ']'));
					}
				});
			});

			// Refresh field indexes
			duplicator.on('orderstop.orderable', function refreshIndexes(event) {
				duplicator.find('.instance').trigger('refresh.duplicator');
			});

		/*-------------------------------------------------------------------*/

			// Create content area
			headers.each(function wrapContent() {
				$(this).nextAll().wrapAll('
');
			});

			// Constructable interface
			if(settings.constructable === true) {
				duplicator.addClass('constructable');
				apply.append(selector).append(constructor);
				apply.appendTo(duplicator);

				// Populate selector
				templates.each(function createTemplates() {
					var template = $(this),
						title = template.find(settings.headers).attr('data-name') || template.find(settings.headers + ' :first-child').text(),
						value = template.attr('data-type');

					template.trigger('constructstart.duplicator');

					// Check type connection
					if(!value) {
						value = title;
						template.attr('data-type', value);
					}

					// Append options
					$('<option />', {
						text: title,
						value: value
					}).appendTo(selector);

					// Check uniqueness
					template.trigger('constructstop.duplicator');
				}).removeClass('template').addClass('instance').remove();
			}

			// Select default
			if(settings.preselect != false) {
				selector.find('option[value="' + settings.preselect + '"]').attr('selected', true);
			}

			// Single template
			if(templates.length <= 1) {
				apply.addClass('single');

				// Single unique template
				if(templates.is('.unique')) {
					constructor.trigger('click.duplicator', [0]);
					apply.hide();
				}
			}

			// Destructable interface
			if(settings.destructable === true) {
				duplicator.addClass('destructable');
				headers.append('' + Symphony.Language.get('Remove item') + '');
			}

			// Collapsible interface
			if(settings.collapsible) {
				duplicator.symphonyCollapsible({
					items: '.instance',
					handles: 'header'
				});
			}

			// Orderable interface
			if(settings.orderable) {
				duplicator.symphonyOrderable({
					items: '.instance',
					handles: 'header'
				});
			}

			// Catch errors
			instances.filter(':has(.invalid)').addClass('conflict');

			// Initialise existing instances
			instances.trigger('constructstop.duplicator');
			instances.find('input[name*="[label]"]').trigger('keyup.duplicator');

			// Check for existing instances
			if(instances.length > 0) {
				duplicator.removeClass('empty');
			}
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<commit_msg>Fix class name<commit_after>/**
 * @package assets
 */

(function($) {

	/**
	 * This plugin creates a Symphony duplicator.
	 *
	 * @name $.symphonyDuplicator
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.instances='> li:not(.template)'] Selector to find children to use as instances
	 * @param {String} [options.templates='> li.template'] Selector to find children to use as templates
	 * @param {String} [options.headers='> :first-child'] Selector to find the header part of each instance
	 * @param {String} [options.perselect=false] Default option for the selector
	 * @param {Boolean} [options.orderable=false] Can instances be ordered
	 * @param {Boolean} [options.collapsible=false] Can instances be collapsed
	 * @param {Boolean} [options.constructable=true] Allow construction of new instances
	 * @param {Boolean} [options.destructable=true] Allow destruction of instances
	 * @param {Integer} [optionss.minimum=0] Do not allow instances to be removed below this limit
	 * @param {Integer} [options.maximum=1000] Do not allow instances to be added above this limit
	 * @param {String} [options.speed='fast'] Animation speed
	 *
	 *	@example

			$('.duplicator').symphonyDuplicator({
				orderable: true,
				collapsible: true
			});
	 */
	$.fn.symphonyDuplicator = function(options) {
		var objects = this,
			settings = {
				instances:			'> li:not(.template)',
				templates:			'> li.template',
				headers:			'> :first-child',
				preselect:			false,
				orderable:			false,
				collapsible:		false,
				constructable:		true,
				destructable:		true,
				minimum:			0,
				maximum:			1000,
				speed:				'fast'
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		// Language strings
		Symphony.Language.add({
			'Add item': false,
			'Remove item': false
		});

	/*-----------------------------------------------------------------------*/

		objects.each(function duplicators() {
			var object = $(this),
				instances = object.find(settings.instances).addClass('instance'),
				templates = object.find(settings.templates).addClass('template'),
				items = instances.add(templates),
				headers = items.find(settings.headers),
				duplicator = object.parent('.frame'),
				apply = $('<fieldset class="apply" />'),
				selector = $('<select />'),
				constructor = $('<button class="constructor">' + Symphony.Language.get('Add item') + '</button>');

			// Check duplicator frame
			if(duplicator.length == 0) {
				duplicator = $('
').insertBefore(object).prepend(object);
			}
			else {
				duplicator.addClass('duplicator').addClass('empty');
			}

		/*-------------------------------------------------------------------*/

			// Construct instances
			apply.on('click.duplicator', 'button.constructor:not(.disabled)', function construct(event, speed) {
				var instance = templates.filter('[data-type="' + $(this).prev('select').val() + '"]').clone();

				event.preventDefault();

				instance.trigger('constructstart.duplicator');
				instance.trigger('construct.duplicator'); /* deprecated */
				instance.hide().appendTo(object);

				// Duplicator is not empty
				duplicator.removeClass('empty');

				// Set speed
				if(!speed) {
					speed = settings.speed;
				}

				// Show instance
				instance.trigger('constructshow.duplicator');
				instance.slideDown(speed, function() {

					// Focus first input
					instance.find('input[type!="hidden"]:first').focus();
					instance.trigger('constructstop.duplicator');
				});
			});

			// Destruct instances
			duplicator.on('click.duplicator', 'a.destructor:not(.disabled)', function destruct(event) {
				var instance = $(this).parents('.instance:first');

				instance.trigger('destructstart.duplicator');
				instance.trigger('destruct.duplicator'); /* deprecated */
				instance.slideUp(settings.speed, function() {
					$(this).remove();

					// Check if duplicator is empty
					if(duplicator.find('.instance').length == 0) {
						duplicator.addClass('empty');
					}

					instance.trigger('destructstop.duplicator');
				});
			});

			// Lock constructor
			duplicator.on('constructstop.duplicator', '.instance', function lockConstructor() {
				if(duplicator.find('.instance').length >= settings.maximum) {
					constructor.addClass('disabled');
				}
			});

			// Unlock constructor
			duplicator.on('destructstart.duplicator', '.instance', function unlockConstructor() {
				if(duplicator.find('.instance').length <= settings.maximum) {
					constructor.removeClass('disabled');
				}
			});

			// Lock destructor
			duplicator.on('destructstart.duplicator', '.instance', function lockDestructor() {
				if(duplicator.find('.instance').length - 1 == settings.minimum) {
					duplicator.find('a.destructor').addClass('disabled');
				}
			});

			// Unlock destructor
			duplicator.on('constructstop.duplicator', '.instance', function unlockDestructor() {
				if(duplicator.find('.instance').length > settings.minimum) {
					duplicator.find('a.destructor').removeClass('disabled');
				}
			});

			// Lock unique instances
			duplicator.on('constructstop.duplicator', '.instance', function lockUnique(event) {
				var instance = $(this);

				if(instance.is('.unique')) {
					selector.find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', true);

					// Preselect first available instance
					selector.find('option').attr('selected', false).filter(':not(:disabled):first').attr('selected', true);

					// All selected
					if(selector.find('option:not(:disabled)').length == 0) {
						selector.attr('disabled', 'disabled');
					}
				}
			});

			// Unlock unique instances
			duplicator.on('destructstart.duplicator', '.instance', function unlockUnique(event) {
				var instance = $(this),
					option;

				if(instance.is('.unique')) {
					option = selector.attr('disabled', false).find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', false);

					// Preselect instance if it's the only active one
					if(selector.find('option:not(:disabled)').length == 1) {
						option.attr('selected', true);
					}
				}
			});

			// Build field indexes
			duplicator.on('constructstop.duplicator refresh.duplicator', '.instance', function buildIndexes(event) {
				var instance = $(this),
					position = duplicator.find('.instance').index(instance);

				// Loop over named fields
				instance.find('*[name]').each(function() {
					var field = $(this),
						exp = /\[\-?[0-9]+\]/,
						name = field.attr('name');

					// Set index
					if(exp.test(name)) {
						field.attr('name', name.replace(exp, '[' + position + ']'));
					}
				});
			});

			// Refresh field indexes
			duplicator.on('orderstop.orderable', function refreshIndexes(event) {
				duplicator.find('.instance').trigger('refresh.duplicator');
			});

		/*-------------------------------------------------------------------*/

			// Create content area
			headers.each(function wrapContent() {
				$(this).nextAll().wrapAll('
');
			});

			// Constructable interface
			if(settings.constructable === true) {
				duplicator.addClass('constructable');
				apply.append(selector).append(constructor);
				apply.appendTo(duplicator);

				// Populate selector
				templates.each(function createTemplates() {
					var template = $(this),
						title = template.find(settings.headers).attr('data-name') || template.find(settings.headers + ' :first-child').text(),
						value = template.attr('data-type');

					template.trigger('constructstart.duplicator');

					// Check type connection
					if(!value) {
						value = title;
						template.attr('data-type', value);
					}

					// Append options
					$('<option />', {
						text: title,
						value: value
					}).appendTo(selector);

					// Check uniqueness
					template.trigger('constructstop.duplicator');
				}).removeClass('template').addClass('instance').remove();
			}

			// Select default
			if(settings.preselect != false) {
				selector.find('option[value="' + settings.preselect + '"]').attr('selected', true);
			}

			// Single template
			if(templates.length <= 1) {
				apply.addClass('single');

				// Single unique template
				if(templates.is('.unique')) {
					constructor.trigger('click.duplicator', [0]);
					apply.hide();
				}
			}

			// Destructable interface
			if(settings.destructable === true) {
				duplicator.addClass('destructable');
				headers.append('' + Symphony.Language.get('Remove item') + '');
			}

			// Collapsible interface
			if(settings.collapsible) {
				duplicator.symphonyCollapsible({
					items: '.instance',
					handles: 'header'
				});
			}

			// Orderable interface
			if(settings.orderable) {
				duplicator.symphonyOrderable({
					items: '.instance',
					handles: 'header'
				});
			}

			// Catch errors
			instances.filter(':has(.invalid)').addClass('conflict');

			// Initialise existing instances
			instances.trigger('constructstop.duplicator');
			instances.find('input[name*="[label]"]').trigger('keyup.duplicator');

			// Check for existing instances
			if(instances.length > 0) {
				duplicator.removeClass('empty');
			}
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<|endoftext|>


<commit_before>'use strict';
var request = require('request'),
  geoCoder = require('../helpers/geocoder'),
  async = require('async');

//'https://api.fda.gov/drug/event.json?search=receivedate:[20040101+TO+20150101]&count=patient.patientsex',
//'http://54.165.240.32/drug/label.json?search=effective_time:[20090601+TO+20140731]&limit=50',

var FDA_DRUG_EVENT = 'https://api.fda.gov/drug/';
var FDA_DEVICE_EVENT = 'https://api.fda.gov/device/';
var FDA_FOOD_EVENT = 'https://api.fda.gov/food/';

var FDA_END_POINTS = {
  device: 'https://api.fda.gov/device/',
  drug: 'https://api.fda.gov/drug/',
  food: 'https://api.fda.gov/food/'
};
var FDA_END_TYPES = {
  event: 'event.json',
  enforcement: 'enforcement.json',
  label: 'label.json'
};

var geoCodeFoodData = function (data, callback) {
  var geoKeys = [];

  if (data && data instanceof Array) {
    data.map(function (item, index, array) {
      if (item.state && item.state.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeState(item.state);
      }
      else if (item.country && item.country.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeCountry(item.country);
      }
    });

    if (geoKeys.length > 0) {
      geoCoder.geoCodeString(geoKeys, function (err, data) {
        if (data) {

        }
      });
    } else {
      callback(data);
    }
  }
  else {
    callback([]);
  }
};

var geoCodeDrugData = function (data, callback) {
  var processedData = [];
  if (data && data instanceof Array) {
    data.map(function (item, index, array) {
      if (item.primarysourcecountry) {
        array[index].GeoLocation = geoCoder.geoCodeCountry(item.primarysourcecountry);
      }
    });
    callback(data);
  }
  else {
    callback([]);
  }
};

var formatSearchFields = function (value, fields) {
  var retSearchField = '';
  for (var idx in fields) {
    retSearchField += fields[idx].trim() + ':' + value.trim() + '+'
  }
  return retSearchField.substring(0, retSearchField.length - 1);//NOTE: Remove the last + character
};

function getAggregateSplashSearchData(req, res) {
  async.parallel([
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.deviceFields.value) {
          chosenFields = req.swagger.params.deviceFields.value.split(',');
        }
        getAPIData('device', 'enforcement', req, chosenFields, function (data) {
          callback(null, {key: 'device', value: data});
        });
      },
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.foodFields.value) {
          chosenFields = req.swagger.params.foodFields.value.split(',');
        }
        getAPIData('food', 'enforcement', req, chosenFields, function (data) {
          geoCodeFoodData(data, function (data) {
            callback(null, {key: 'food', value: data});
          });
        });
      },
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.drugFields.value) {
          chosenFields = req.swagger.params.drugFields.value.split(',');
        }
        getAPIData('drug', 'enforcement', req, chosenFields, function (data) {
          geoCodeDrugData(data, function (data) {
            callback(null, {key: 'drug', value: data});
          });
        });

      }
    ],
    function (err, data) {
      var returnData = {drug: [], device: [], food: []};
      for (var idx in data) {
        if (data[idx].value instanceof  Array) {
          returnData[data[idx].key] = data[idx].value;
        }
      }
      var statusMessage = '';
      statusMessage += returnData.drug.length > 0 ? returnData.drug.length + ' drug records, ' : 'No drug data, ';
      statusMessage += returnData.food.length > 0 ? returnData.food.length + ' food records, ' : 'No food data, ';
      statusMessage += returnData.device.length > 0 ? returnData.device.length + ' device records, ' : 'No device data ';
      returnData.status = statusMessage;
      res.json(returnData);
    }
  );
}

function getRangeCountData(req, callback) {
  var fdaUrl = FDA_DRUG_EVENT + 'event.json?search=receivedate:[' + req.swagger.params.start.value + '+TO+' + req.swagger.params.end.value + ']&count=' + req.swagger.params.field.value;
  getDataFromFdaApi(fdaUrl, function (data) {
    callback(data);
  });
}

function getEventSearchData(req, callback) {
  var limit = req.swagger.params.limit.value || 100;
  var start = req.swagger.params.skip.value || 0;
  var fdaUrl = FDA_DRUG_EVENT + 'event.json?search=' + req.swagger.params.query.value + '&limit=' + limit + '&skip=' + start;

  getDataFromFdaApi(fdaUrl, function (data) {
    callback(data);
  });
}

var getAPIData = function (endPointBase, typeOfEngPoint, req, fields, callback) {
  var limit = 100, start = 0, search;
  if (req.swagger.params.limit) {
    limit = req.swagger.params.limit.value || 100;
  }
  if (req.swagger.params.skip) {
    start = req.swagger.params.skip.value || 0;
  }
  if (req.swagger.params.query) {
    search = req.swagger.params.query.value;
  }
  if (fields.length > 0) {
    search = formatSearchFields(req.swagger.params.query.value, fields);
  }
  var fdaUrl = FDA_END_POINTS[endPointBase] + FDA_END_TYPES[typeOfEngPoint] + '?search=' + search;

  if (limit) {
    fdaUrl += '&limit=' + limit;
  }
  if (start) {
    fdaUrl += '&skip=' + start;
  }
  getDataFromFdaApi(fdaUrl, callback);
};

var getAPIRangeData = function (endPointBase, typeOfEngPoint, datefield, req, callback) {
  var fdaUrl = FDA_END_POINTS[endPointBase] + FDA_END_TYPES[typeOfEngPoint] + "?search=" + datefield
    + ':[' + req.swagger.params.start.value + '+TO+' + req.swagger.params.end.value + ']&count=' + req.swagger.params.field.value;
  getDataFromFdaApi(fdaUrl, callback);
};

function getDataFromFdaApi(fdaUrl, callback) {
  request.get({
      url: encodeURI(fdaUrl),
      json: true
    },
    function (error, response, body) {
      if (!error && (response.statusCode == 200 || 404)) {
        callback(response.statusCode == 404 ? body : body.results);
      } else {
        callback({error: 'Request Failed'});
      }
    }
  );
}

module.exports = {
  aggregateSplashSearch: function (req, res) {
    getAggregateSplashSearchData(req, res)
  },

  drugEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.fields.value.split(',');
    }
    getAPIData('drug', 'enforcement', req, chosenFields, function (data) {
      geoCodeDrugData(data, function (data) {
        res.json(data);
      });
    });
  },

  drugEventRangeCount: function (req, res) {
    getRangeCountData(req, function (data) {
      res.json(data);
    });
  },

  deviceEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.deviceFields.value.split(',');
    }
    getAPIData('device', 'enforcement', req, chosenFields, function (data) {
      res.json(data);
    });
  },

  deviceEventRangeCount: function (req, res) {
    getAPIRangeData('device', 'enforcement', 'report_date', req, function (data) {
      res.json(data);
    });
  },

  foodEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.fields.value.split(',');
    }
    getAPIData('food', 'enforcement', req, chosenFields, function (data) {
      geoCodeFoodData(data, function (data) {
        res.json(data);
      });
    });
  },

  foodEventRangeCount: function (req, res) {
    getAPIRangeData('food', 'enforcement', 'recall_initiation_date', req, function (data) {
      res.json(data);
    });
  },

  tests: {
    getRangeCountData: getRangeCountData,
    getEventSearchData: getEventSearchData,
    FDA_END_POINTS: FDA_END_POINTS,
    FDA_END_TYPES: FDA_END_TYPES,
    getAPIData: getAPIData,
    getAPIRangeData: getAPIRangeData
  }
};<commit_msg>Adding geolocation to Device data<commit_after>'use strict';
var request = require('request'),
  geoCoder = require('../helpers/geocoder'),
  async = require('async');

//'https://api.fda.gov/drug/event.json?search=receivedate:[20040101+TO+20150101]&count=patient.patientsex',
//'http://54.165.240.32/drug/label.json?search=effective_time:[20090601+TO+20140731]&limit=50',

var FDA_DRUG_EVENT = 'https://api.fda.gov/drug/';
var FDA_DEVICE_EVENT = 'https://api.fda.gov/device/';
var FDA_FOOD_EVENT = 'https://api.fda.gov/food/';

var FDA_END_POINTS = {
  device: 'https://api.fda.gov/device/',
  drug: 'https://api.fda.gov/drug/',
  food: 'https://api.fda.gov/food/'
};
var FDA_END_TYPES = {
  event: 'event.json',
  enforcement: 'enforcement.json',
  label: 'label.json'
};

var geoCodeFoodData = function (data, callback) {
  var geoKeys = [];

  if (data && data instanceof Array) {
    data.map(function (item, index, array) {
      if (item.state && item.state.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeState(item.state);
      }
      else if (item.country && item.country.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeCountry(item.country);
      }
    });

    if (geoKeys.length > 0) {
      geoCoder.geoCodeString(geoKeys, function (err, data) {
        if (data) {

        }
      });
    } else {
      callback(data);
    }
  }
  else {
    callback([]);
  }
};

var geoCodeDrugData = function (data, callback) {
  var geoKeys = [];

  if (data && data instanceof Array) {
    data.map(function (item, index, array) {
      if (item.state && item.state.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeState(item.state);
      }
      else if (item.country && item.country.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeCountry(item.country);
      }
    });

    if (geoKeys.length > 0) {
      geoCoder.geoCodeString(geoKeys, function (err, data) {
        if (data) {

        }
      });
    } else {
      callback(data);
    }
  }
  else {
    callback([]);
  }
};

var geoCodeDeviceData = function(data, callback){
  var geoKeys = [];

  if (data && data instanceof Array) {
    data.map(function (item, index, array) {
      if (item.state && item.state.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeState(item.state);
      }
      else if (item.country && item.country.length > 0) {
        array[index].GeoLocation = geoCoder.geoCodeCountry(item.country);
      }
    });

    if (geoKeys.length > 0) {
      geoCoder.geoCodeString(geoKeys, function (err, data) {
        if (data) {

        }
      });
    } else {
      callback(data);
    }
  }
  else {
    callback([]);
  }
};

var formatSearchFields = function (value, fields) {
  var retSearchField = '';
  for (var idx in fields) {
    retSearchField += fields[idx].trim() + ':' + value.trim() + '+'
  }
  return retSearchField.substring(0, retSearchField.length - 1);//NOTE: Remove the last + character
};

function getAggregateSplashSearchData(req, res) {
  async.parallel([
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.deviceFields.value) {
          chosenFields = req.swagger.params.deviceFields.value.split(',');
        }
        getAPIData('device', 'enforcement', req, chosenFields, function (data) {
          callback(null, {key: 'device', value: data});
        });
      },
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.foodFields.value) {
          chosenFields = req.swagger.params.foodFields.value.split(',');
        }
        getAPIData('food', 'enforcement', req, chosenFields, function (data) {
          geoCodeFoodData(data, function (data) {
            callback(null, {key: 'food', value: data});
          });
        });
      },
      function (callback) {
        var chosenFields = [];
        if (req.swagger.params.drugFields.value) {
          chosenFields = req.swagger.params.drugFields.value.split(',');
        }
        getAPIData('drug', 'enforcement', req, chosenFields, function (data) {
          geoCodeDrugData(data, function (data) {
            callback(null, {key: 'drug', value: data});
          });
        });

      }
    ],
    function (err, data) {
      var returnData = {drug: [], device: [], food: []};
      for (var idx in data) {
        if (data[idx].value instanceof  Array) {
          returnData[data[idx].key] = data[idx].value;
        }
      }
      var statusMessage = '';
      statusMessage += returnData.drug.length > 0 ? returnData.drug.length + ' drug records, ' : 'No drug data, ';
      statusMessage += returnData.food.length > 0 ? returnData.food.length + ' food records, ' : 'No food data, ';
      statusMessage += returnData.device.length > 0 ? returnData.device.length + ' device records, ' : 'No device data ';
      returnData.status = statusMessage;
      res.json(returnData);
    }
  );
}

function getRangeCountData(req, callback) {
  var fdaUrl = FDA_DRUG_EVENT + 'event.json?search=receivedate:[' + req.swagger.params.start.value + '+TO+' + req.swagger.params.end.value + ']&count=' + req.swagger.params.field.value;
  getDataFromFdaApi(fdaUrl, function (data) {
    callback(data);
  });
}

function getEventSearchData(req, callback) {
  var limit = req.swagger.params.limit.value || 100;
  var start = req.swagger.params.skip.value || 0;
  var fdaUrl = FDA_DRUG_EVENT + 'event.json?search=' + req.swagger.params.query.value + '&limit=' + limit + '&skip=' + start;

  getDataFromFdaApi(fdaUrl, function (data) {
    callback(data);
  });
}

var getAPIData = function (endPointBase, typeOfEngPoint, req, fields, callback) {
  var limit = 100, start = 0, search;
  if (req.swagger.params.limit) {
    limit = req.swagger.params.limit.value || 100;
  }
  if (req.swagger.params.skip) {
    start = req.swagger.params.skip.value || 0;
  }
  if (req.swagger.params.query) {
    search = req.swagger.params.query.value;
  }
  if (fields.length > 0) {
    search = formatSearchFields(req.swagger.params.query.value, fields);
  }
  var fdaUrl = FDA_END_POINTS[endPointBase] + FDA_END_TYPES[typeOfEngPoint] + '?search=' + search;

  if (limit) {
    fdaUrl += '&limit=' + limit;
  }
  if (start) {
    fdaUrl += '&skip=' + start;
  }
  getDataFromFdaApi(fdaUrl, callback);
};

var getAPIRangeData = function (endPointBase, typeOfEngPoint, datefield, req, callback) {
  var fdaUrl = FDA_END_POINTS[endPointBase] + FDA_END_TYPES[typeOfEngPoint] + "?search=" + datefield
    + ':[' + req.swagger.params.start.value + '+TO+' + req.swagger.params.end.value + ']&count=' + req.swagger.params.field.value;
  getDataFromFdaApi(fdaUrl, callback);
};

function getDataFromFdaApi(fdaUrl, callback) {
  request.get({
      url: encodeURI(fdaUrl),
      json: true
    },
    function (error, response, body) {
      if (!error && (response.statusCode == 200 || 404)) {
        callback(response.statusCode == 404 ? body : body.results);
      } else {
        callback({error: 'Request Failed'});
      }
    }
  );
}

module.exports = {
  aggregateSplashSearch: function (req, res) {
    getAggregateSplashSearchData(req, res)
  },

  drugEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.fields.value.split(',');
    }
    getAPIData('drug', 'enforcement', req, chosenFields, function (data) {
      geoCodeDrugData(data, function (data) {
        res.json(data);
      });
    });
  },

  drugEventRangeCount: function (req, res) {
    getRangeCountData(req, function (data) {
      res.json(data);
    });
  },

  deviceEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.deviceFields.value.split(',');
    }
    getAPIData('device', 'enforcement', req, chosenFields, function (data) {
      geoCodeDeviceData(data, function(processedData){
        res.json(processedData);
      });
    });
  },

  deviceEventRangeCount: function (req, res) {
    getAPIRangeData('device', 'enforcement', 'report_date', req, function (data) {
      res.json(data);
    });
  },

  foodEventSearch: function (req, res) {
    var chosenFields = [];
    if (req.swagger.params.fields.value) {
      chosenFields = req.swagger.params.fields.value.split(',');
    }
    getAPIData('food', 'enforcement', req, chosenFields, function (data) {
      geoCodeFoodData(data, function (data) {
        res.json(data);
      });
    });
  },

  foodEventRangeCount: function (req, res) {
    getAPIRangeData('food', 'enforcement', 'recall_initiation_date', req, function (data) {
      res.json(data);
    });
  },

  tests: {
    getRangeCountData: getRangeCountData,
    getEventSearchData: getEventSearchData,
    FDA_END_POINTS: FDA_END_POINTS,
    FDA_END_TYPES: FDA_END_TYPES,
    getAPIData: getAPIData,
    getAPIRangeData: getAPIRangeData
  }
};<|endoftext|>


<commit_before>/**
 * @package assets
 */

(function($) {

	/**
	 * This plugin creates a Symphony duplicator.
	 *
	 * @name $.symphonyDuplicator
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.instances='> li:not(.template)'] Selector to find children to use as instances
	 * @param {String} [options.templates='> li.template'] Selector to find children to use as templates
	 * @param {String} [options.headers='> :first-child'] Selector to find the header part of each instance
	 * @param {String} [options.perselect=false] Default option for the selector
	 * @param {Boolean} [options.orderable=false] Can instances be ordered
	 * @param {Boolean} [options.collapsible=false] Can instances be collapsed
	 * @param {Boolean} [options.constructable=true] Allow construction of new instances
	 * @param {Boolean} [options.destructable=true] Allow destruction of instances
	 * @param {Integer} [optionss.minimum=0] Do not allow instances to be removed below this limit
	 * @param {Integer} [options.maximum=1000] Do not allow instances to be added above this limit
	 * @param {String} [options.speed='fast'] Animation speed
	 *
	 *	@example

			$('.duplicator').symphonyDuplicator({
				orderable: true,
				collapsible: true
			});
	 */
	$.fn.symphonyDuplicator = function(options) {
		var objects = this,
			settings = {
				instances:			'> li:not(.template)',
				templates:			'> li.template',
				headers:			'> :first-child',
				preselect:			false,
				orderable:			false,
				collapsible:		false,
				constructable:		true,
				destructable:		true,
				minimum:			0,
				maximum:			1000,
				speed:				'fast'
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		// Language strings
		Symphony.Language.add({
			'Add item': false,
			'Remove item': false
		});

	/*-----------------------------------------------------------------------*/

		objects.each(function duplicators() {
			var object = $(this),
				instances = object.find(settings.instances).addClass('instance'),
				templates = object.find(settings.templates).addClass('template'),
				items = instances.add(templates),
				headers = items.find(settings.headers),
				duplicator = object.parent('.frame'),
				apply = $('<fieldset class="apply" />'),
				selector = $('<select />'),
				constructor = $('<button class="constructor">' + Symphony.Language.get('Add item') + '</button>');

			// Check duplicator frame
			if(duplicator.length == 0) {
				duplicator = $('
').insertBefore(object).prepend(object);
			}
			else {
				duplicator.addClass('duplicator').addClass('empty');
			}

		/*-------------------------------------------------------------------*/

			// Construct instances
			apply.on('click.duplicator', 'button.constructor:not(.disabled)', function construct(event, speed) {
				var instance = templates.filter('[data-type="' + $(this).prev('select').val() + '"]').clone();

				event.preventDefault();

				instance.trigger('constructstart.duplicator');
				instance.trigger('construct.duplicator'); /* deprecated */
				instance.hide().appendTo(object);

				// Duplicator is not empty
				duplicator.removeClass('empty');

				// Set speed
				if(!speed) {
					speed = settings.speed;
				}

				// Show instance
				instance.trigger('constructshow.duplicator');
				instance.slideDown(speed, function() {

					// Focus first input
					instance.find('input[type!="hidden"]:first').focus();
					instance.trigger('constructstop.duplicator');
				});
			});

			// Destruct instances
			duplicator.on('click.duplicator', 'a.destructor:not(.disabled)', function destruct(event) {
				var instance = $(this).parents('.instance:first');

				instance.trigger('destructstart.duplicator');
				instance.trigger('destruct.duplicator'); /* deprecated */
				instance.slideUp(settings.speed, function() {
					$(this).remove();

					// Check if duplicator is empty
					if(duplicator.find('.instance').length == 0) {
						duplicator.addClass('empty');
					}

					instance.trigger('destructstop.duplicator');
				});
			});

			// Lock constructor
			duplicator.on('constructstop.duplicator', '.instance', function lockConstructor() {
				if(duplicator.find('.instance').length >= settings.maximum) {
					constructor.addClass('disabled');
				}
			});

			// Unlock constructor
			duplicator.on('destructstart.duplicator', '.instance', function unlockConstructor() {
				if(duplicator.find('.instance').length <= settings.maximum) {
					constructor.removeClass('disabled');
				}
			});

			// Lock destructor
			duplicator.on('destructstart.duplicator', '.instance', function lockDestructor() {
				if(duplicator.find('.instance').length - 1 == settings.minimum) {
					duplicator.find('a.destructor').addClass('disabled');
				}
			});

			// Unlock destructor
			duplicator.on('constructstop.duplicator', '.instance', function unlockDestructor() {
				if(duplicator.find('.instance').length > settings.minimum) {
					duplicator.find('a.destructor').removeClass('disabled');
				}
			});

			// Lock unique instances
			duplicator.on('constructstop.duplicator', '.instance', function lockUnique(event) {
				var instance = $(this);

				if(instance.is('.unique')) {
					selector.find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', true);

					// Preselect first available instance
					selector.find('option').attr('selected', false).filter(':not(:disabled):first').attr('selected', true);

					// All selected
					if(selector.find('option:not(:disabled)').length == 0) {
						selector.attr('disabled', 'disabled');
					}
				}
			});

			// Unlock unique instances
			duplicator.on('destructstart.duplicator', '.instance', function unlockUnique(event) {
				var instance = $(this),
					option;

				if(instance.is('.unique')) {
					option = selector.attr('disabled', false).find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', false);

					// Preselect instance if it's the only active one
					if(selector.find('option:not(:disabled)').length == 1) {
						option.attr('selected', true);
					}
				}
			});

			// Build field indexes
			duplicator.on('constructstop.duplicator refresh.duplicator', '.instance', function buildIndexes(event) {
				var instance = $(this),
					position = duplicator.find('.instance').index(instance);

				// Loop over named fields
				instance.find('*[name]').each(function() {
					var field = $(this),
						exp = /\[\-?[0-9]+\]/,
						name = field.attr('name');

					// Set index
					if(exp.test(name)) {
						field.attr('name', name.replace(exp, '[' + position + ']'));
					}
				});
			});

			// Refresh field indexes
			duplicator.on('orderstop.orderable', function refreshIndexes(event) {
				duplicator.find('.instance').trigger('refresh.duplicator');
			});

		/*-------------------------------------------------------------------*/

			// Create content area
			headers.each(function wrapContent() {
				$(this).nextAll().wrapAll('
');
			});

			// Constructable interface
			if(settings.constructable === true) {
				duplicator.addClass('constructable');
				apply.append(selector).append(constructor);
				apply.appendTo(duplicator);

				// Populate selector
				templates.each(function createTemplates() {
					var template = $(this),
						title = template.find(settings.headers).attr('data-name') || template.find(settings.headers + ' :first-child').text(),
						value = template.attr('data-type');

					template.trigger('constructstart.duplicator');

					// Check type connection
					if(!value) {
						value = title;
						template.attr('data-type', value);
					}

					// Append options
					$('<option />', {
						text: title,
						value: value
					}).appendTo(selector);

					// Check uniqueness
					template.trigger('constructstop.duplicator');
				}).removeClass('template').addClass('instance').remove();
			}

			// Select default
			if(settings.preselect != false) {
				selector.find('option[value="' + settings.preselect + '"]').attr('selected', true);
			}

			// Single template
			if(templates.length <= 1) {
				apply.addClass('single');

				// Single unique template
				if(templates.is('.unique')) {
					constructor.trigger('click.duplicator', [0]);
					apply.hide();
				}
			}

			// Destructable interface
			if(settings.destructable === true) {
				duplicator.addClass('destructable');
				headers.append('' + Symphony.Language.get('Remove item') + '');
			}

			// Collapsible interface
			if(settings.collapsible) {
				duplicator.symphonyCollapsible({
					items: '.instance',
					handles: 'header'
				});
			}

			// Orderable interface
			if(settings.orderable) {
				duplicator.symphonyOrderable({
					items: '.instance',
					handles: 'header'
				});
			}

			// Catch errors
			instances.filter(':has(.invalid)').addClass('conflict');

			// Initialise existing instances
			instances.trigger('constructstop.duplicator');
			instances.find('input[name*="[label]"]').trigger('keyup.duplicator');

			// Check for existing instances
			if(instances.length > 0) {
				duplicator.removeClass('empty');
			}
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<commit_msg>Remove another funny whitespace character<commit_after>/**
 * @package assets
 */

(function($) {

	/**
	 * This plugin creates a Symphony duplicator.
	 *
	 * @name $.symphonyDuplicator
	 * @class
	 *
	 * @param {Object} options An object specifying containing the attributes specified below
	 * @param {String} [options.instances='> li:not(.template)'] Selector to find children to use as instances
	 * @param {String} [options.templates='> li.template'] Selector to find children to use as templates
	 * @param {String} [options.headers='> :first-child'] Selector to find the header part of each instance
	 * @param {String} [options.perselect=false] Default option for the selector
	 * @param {Boolean} [options.orderable=false] Can instances be ordered
	 * @param {Boolean} [options.collapsible=false] Can instances be collapsed
	 * @param {Boolean} [options.constructable=true] Allow construction of new instances
	 * @param {Boolean} [options.destructable=true] Allow destruction of instances
	 * @param {Integer} [optionss.minimum=0] Do not allow instances to be removed below this limit
	 * @param {Integer} [options.maximum=1000] Do not allow instances to be added above this limit
	 * @param {String} [options.speed='fast'] Animation speed
	 *
	 *	@example

			$('.duplicator').symphonyDuplicator({
				orderable: true,
				collapsible: true
			});
	 */
	$.fn.symphonyDuplicator = function(options) {
		var objects = this,
			settings = {
				instances:			'> li:not(.template)',
				templates:			'> li.template',
				headers:			'> :first-child',
				preselect:			false,
				orderable:			false,
				collapsible:		false,
				constructable:		true,
				destructable:		true,
				minimum:			0,
				maximum:			1000,
				speed:				'fast'
			};

		$.extend(settings, options);

	/*-----------------------------------------------------------------------*/

		// Language strings
		Symphony.Language.add({
			'Add item': false,
			'Remove item': false
		});

	/*-----------------------------------------------------------------------*/

		objects.each(function duplicators() {
			var object = $(this),
				instances = object.find(settings.instances).addClass('instance'),
				templates = object.find(settings.templates).addClass('template'),
				items = instances.add(templates),
				headers = items.find(settings.headers),
				duplicator = object.parent('.frame'),
				apply = $('<fieldset class="apply" />'),
				selector = $('<select />'),
				constructor = $('<button class="constructor">' + Symphony.Language.get('Add item') + '</button>');

			// Check duplicator frame
			if(duplicator.length == 0) {
				duplicator = $('
').insertBefore(object).prepend(object);
			}
			else {
				duplicator.addClass('duplicator').addClass('empty');
			}

		/*-------------------------------------------------------------------*/

			// Construct instances
			apply.on('click.duplicator', 'button.constructor:not(.disabled)', function construct(event, speed) {
				var instance = templates.filter('[data-type="' + $(this).prev('select').val() + '"]').clone();

				event.preventDefault();

				instance.trigger('constructstart.duplicator');
				instance.trigger('construct.duplicator'); /* deprecated */
				instance.hide().appendTo(object);

				// Duplicator is not empty
				duplicator.removeClass('empty');

				// Set speed
				if(!speed) {
					speed = settings.speed;
				}

				// Show instance
				instance.trigger('constructshow.duplicator');
				instance.slideDown(speed, function() {

					// Focus first input
					instance.find('input[type!="hidden"]:first').focus();
					instance.trigger('constructstop.duplicator');
				});
			});

			// Destruct instances
			duplicator.on('click.duplicator', 'a.destructor:not(.disabled)', function destruct(event) {
				var instance = $(this).parents('.instance:first');

				instance.trigger('destructstart.duplicator');
				instance.trigger('destruct.duplicator'); /* deprecated */
				instance.slideUp(settings.speed, function() {
					$(this).remove();

					// Check if duplicator is empty
					if(duplicator.find('.instance').length == 0) {
						duplicator.addClass('empty');
					}

					instance.trigger('destructstop.duplicator');
				});
			});

			// Lock constructor
			duplicator.on('constructstop.duplicator', '.instance', function lockConstructor() {
				if(duplicator.find('.instance').length >= settings.maximum) {
					constructor.addClass('disabled');
				}
			});

			// Unlock constructor
			duplicator.on('destructstart.duplicator', '.instance', function unlockConstructor() {
				if(duplicator.find('.instance').length <= settings.maximum) {
					constructor.removeClass('disabled');
				}
			});

			// Lock destructor
			duplicator.on('destructstart.duplicator', '.instance', function lockDestructor() {
				if(duplicator.find('.instance').length - 1 == settings.minimum) {
					duplicator.find('a.destructor').addClass('disabled');
				}
			});

			// Unlock destructor
			duplicator.on('constructstop.duplicator', '.instance', function unlockDestructor() {
				if(duplicator.find('.instance').length > settings.minimum) {
					duplicator.find('a.destructor').removeClass('disabled');
				}
			});

			// Lock unique instances
			duplicator.on('constructstop.duplicator', '.instance', function lockUnique(event) {
				var instance = $(this);

				if(instance.is('.unique')) {
					selector.find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', true);

					// Preselect first available instance
					selector.find('option').attr('selected', false).filter(':not(:disabled):first').attr('selected', true);

					// All selected
					if(selector.find('option:not(:disabled)').length == 0) {
						selector.attr('disabled', 'disabled');
					}
				}
			});

			// Unlock unique instances
			duplicator.on('destructstart.duplicator', '.instance', function unlockUnique(event) {
				var instance = $(this),
					option;

				if(instance.is('.unique')) {
					option = selector.attr('disabled', false).find('option[value="' + instance.attr('data-type') + '"]').attr('disabled', false);

					// Preselect instance if it's the only active one
					if(selector.find('option:not(:disabled)').length == 1) {
						option.attr('selected', true);
					}
				}
			});

			// Build field indexes
			duplicator.on('constructstop.duplicator refresh.duplicator', '.instance', function buildIndexes(event) {
				var instance = $(this),
					position = duplicator.find('.instance').index(instance);

				// Loop over named fields
				instance.find('*[name]').each(function() {
					var field = $(this),
						exp = /\[\-?[0-9]+\]/,
						name = field.attr('name');

					// Set index
					if(exp.test(name)) {
						field.attr('name', name.replace(exp, '[' + position + ']'));
					}
				});
			});

			// Refresh field indexes
			duplicator.on('orderstop.orderable', function refreshIndexes(event) {
				duplicator.find('.instance').trigger('refresh.duplicator');
			});

		/*-------------------------------------------------------------------*/

			// Create content area
			headers.each(function wrapContent() {
				$(this).nextAll().wrapAll('
');
			});

			// Constructable interface
			if(settings.constructable === true) {
				duplicator.addClass('constructable');
				apply.append(selector).append(constructor);
				apply.appendTo(duplicator);

				// Populate selector
				templates.each(function createTemplates() {
					var template = $(this),
						title = template.find(settings.headers).attr('data-name') || template.find(settings.headers + ' :first-child').text(),
						value = template.attr('data-type');

					template.trigger('constructstart.duplicator');

					// Check type connection
					if(!value) {
						value = title;
						template.attr('data-type', value);
					}

					// Append options
					$('<option />', {
						text: title,
						value: value
					}).appendTo(selector);

					// Check uniqueness
					template.trigger('constructstop.duplicator');
				}).removeClass('template').addClass('instance').remove();
			}

			// Select default
			if(settings.preselect != false) {
				selector.find('option[value="' + settings.preselect + '"]').attr('selected', true);
			}

			// Single template
			if(templates.length <= 1) {
				apply.addClass('single');

				// Single unique template
				if(templates.is('.unique')) {
					constructor.trigger('click.duplicator', [0]);
					apply.hide();
				}
			}

			// Destructable interface
			if(settings.destructable === true) {
				duplicator.addClass('destructable');
				headers.append('' + Symphony.Language.get('Remove item') + '');
			}

			// Collapsible interface
			if(settings.collapsible) {
				duplicator.symphonyCollapsible({
					items: '.instance',
					handles: 'header'
				});
			}

			// Orderable interface
			if(settings.orderable) {
				duplicator.symphonyOrderable({
					items: '.instance',
					handles: 'header'
				});
			}

			// Catch errors
			instances.filter(':has(.invalid)').addClass('conflict');

			// Initialise existing instances
			instances.trigger('constructstop.duplicator');
			instances.find('input[name*="[label]"]').trigger('keyup.duplicator');

			// Check for existing instances
			if(instances.length > 0) {
				duplicator.removeClass('empty');
			}
		});

	/*-----------------------------------------------------------------------*/

		return objects;
	};

})(jQuery.noConflict());
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    async = require('async'),
    Vendor = mongoose.model('Vendor'),
    _ = require('underscore');

/**
 * Find vendor by id
 */
exports.vendor = function(req, res, next, id) {

    Vendor.load(id, function(err, vendor) {
        if (err) return next(err);
        if (!vendor) {
            return res.failure('No results', 404);
        }
        req.vendor = vendor;
        next();
    });
};

/**
 * Find vendor by req.body.vendorId or req.params.vendorId
 * @todo this should be able to piggy back on exports.vendor by checkig for params and body if
 *    id doesn't exist ad the 4th param. However this was not working and causing errors.
 *
 */
exports.findByBodyOrParams = function(req, res, next) {

    var id = null;

    if(req.body && req.body.vendorId) {
        id = req.body.vendorId;
    } else if(req.params && req.params.vendorId) {
        id = req.params.vendorId;
    }

    if(!id) return res.failure('missing vendor id');

    Vendor.load(id, function(err, vendor) {
        if (err) return next(err);
        if (!vendor) {
            return res.failure('No results', 404);
        }
        req.vendor = vendor;
        next();
    });
};

/**
 * Create a vendor
 */
exports.create = function(req, res) {
    var vendor = new Vendor(req.body);

    vendor.save();
    res.ok(vendor);
};

/**
 * Update a vendor
 */
exports.update = function(req, res) {
    var vendor = req.vendor;

    vendor = _.extend(vendor, req.body);

    vendor.save(function(err) {
        Vendor.load(vendor._id, function(err, updatedVendor) {
            if (err) return next(err);
            res.ok(updatedVendor);
        });
    });
};

/**
 * Delete an vendor
 */
exports.destroy = function(req, res) {
    var vendor = req.vendor;

    vendor.remove(function(err) {
        if (err) {
            res.failure(err);
        } else {
            res.ok(vendor);
        }
    });
};

/**
 * Show an vendor
 */
exports.show = function(req, res) {
    res.ok(req.vendor);
};

exports.allForSalesRep = function(req, res) {

    var userId = req.user._id;

    Vendor
        .where('salesRep')
        .equals(userId)
        .find()
        .sort('-created')
        .populate('programIds programs salesRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });

};

/**
 * List of Vendors
 */
exports.all = function(req, res) {

    var where = {};
    var populate = 'programIds programs salesRep vendorRep';
    var select = '';

    // limit quotes to sales rep only.
    if (req.userHasRole('admin')) {
        // nothing, admin can see all!
    } else if (req.userHasRole('salesRep')) {
        where = {
            salesRep: req.user._id
        };
    } else if (req.userHasRole('vendorRep')) {
        where = {
            vendorRep: req.user._id
        };
    } else {
        populate = 'vendorRep';
        select = 'name _id logo customField geo tools tags searchString whiteLabel range website vendorRep legalTerms';
    }

    Vendor
        .find(where)
        .select(select)
        .sort('-name')
        .populate(populate)
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.listForUser = function(req, res) {

    var where = {};

    var id = req.params.userId;

    if (id) {
        where = {
            $or: [{
                salesRep: id
            }, {
                vendorRep: id
            }]
        };
    }

    Vendor
        .find(where)
        .sort('-name')
        .populate('programIds programs salesRep vendorRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.listNotForUser = function(req, res) {

    var where = {};

    var id = req.params.userId;

    if (id) {
        where = {
            $nor: [{
                salesRep: id
            }, {
                vendorRep: id
            }]
        };
    }

    Vendor
        .find(where)
        .sort('-name')
        .populate('programIds programs salesRep vendorRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.getAllNames = function(req, res) {
    Vendor
        .find()
        .select('_id name legalTerms')
        .sort('-created')
        .populate('programIds salesRep programs')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * Get distinct vendor tags
 *
 */
exports.getDistinctTags = function(req, res) {
    Vendor.distinct(req.params.tagType, {}, function (err, result) {
        if (err) res.failure(err);
        res.ok(result);
    });
};

/**
 * Get programs for a vendor
 *
 */
var Program = mongoose.model('Program');

exports.getCurrentVendorPrograms = function(req, res) {
    res.ok(req.vendor.programs);
};

exports.getAvailableVendorPrograms = function(req, res) {
    var theIds = _.pluck(req.vendor.programs, '_id');
    if (!theIds) theIds = [];
    Program.find().where('_id').nin(theIds).sort('-created').exec(function(err, programs) {
        if (err) {
            res.failure(err);
        } else {
            res.ok(programs);
        }
    });
};

exports.getSalesRep = function(req, res) {
    res.ok(req.vendor.salesRep);
};
<commit_msg>Add find method to vendor api<commit_after>/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    async = require('async'),
    Vendor = mongoose.model('Vendor'),
    _ = require('underscore');

/**
 * Find / query function, allows us to pass a mongodb style query over rest
 *
 * @todo change to GET!!! might require querystring module and will def require modifying angular service
 * @todo add to remaining controllers, currently only in application controller.
 *
 * @example { 'status' : 'open' } // gets all with status open
 * @example { 'status' : { '$nin' : ['open', 'archived', 'denied'] } } // gets all where status not in array
 *
 * @note these must be passed through JSON.stringify on the angular app side
 *
 */
exports.find = function(req, res, next) {

    // currently query is just request body
    var query = req.body;

/*
    if (req.userHasRole('salesRep')) {
        query.salesRep = req.user._id;
    } else if (req.userHasRole('vendorRep')) {
        query.vendorRep = req.user._id;
    }
*/

    Vendor
        .find(query)
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * Find vendor by id
 */
exports.vendor = function(req, res, next, id) {

    Vendor.load(id, function(err, vendor) {
        if (err) return next(err);
        if (!vendor) {
            return res.failure('No results', 404);
        }
        req.vendor = vendor;
        next();
    });
};

/**
 * Find vendor by req.body.vendorId or req.params.vendorId
 * @todo this should be able to piggy back on exports.vendor by checkig for params and body if
 *    id doesn't exist ad the 4th param. However this was not working and causing errors.
 *
 */
exports.findByBodyOrParams = function(req, res, next) {

    var id = null;

    if(req.body && req.body.vendorId) {
        id = req.body.vendorId;
    } else if(req.params && req.params.vendorId) {
        id = req.params.vendorId;
    }

    if(!id) return res.failure('missing vendor id');

    Vendor.load(id, function(err, vendor) {
        if (err) return next(err);
        if (!vendor) {
            return res.failure('No results', 404);
        }
        req.vendor = vendor;
        next();
    });
};

/**
 * Create a vendor
 */
exports.create = function(req, res) {
    var vendor = new Vendor(req.body);

    vendor.save();
    res.ok(vendor);
};

/**
 * Update a vendor
 */
exports.update = function(req, res) {
    var vendor = req.vendor;

    vendor = _.extend(vendor, req.body);

    vendor.save(function(err) {
        Vendor.load(vendor._id, function(err, updatedVendor) {
            if (err) return next(err);
            res.ok(updatedVendor);
        });
    });
};

/**
 * Delete an vendor
 */
exports.destroy = function(req, res) {
    var vendor = req.vendor;

    vendor.remove(function(err) {
        if (err) {
            res.failure(err);
        } else {
            res.ok(vendor);
        }
    });
};

/**
 * Show an vendor
 */
exports.show = function(req, res) {
    res.ok(req.vendor);
};

exports.allForSalesRep = function(req, res) {

    var userId = req.user._id;

    Vendor
        .where('salesRep')
        .equals(userId)
        .find()
        .sort('-created')
        .populate('programIds programs salesRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });

};

/**
 * List of Vendors
 */
exports.all = function(req, res) {

    var where = {};
    var populate = 'programIds programs salesRep vendorRep';
    var select = '';

    // limit quotes to sales rep only.
    if (req.userHasRole('admin')) {
        // nothing, admin can see all!
    } else if (req.userHasRole('salesRep')) {
        where = {
            salesRep: req.user._id
        };
    } else if (req.userHasRole('vendorRep')) {
        where = {
            vendorRep: req.user._id
        };
    } else {
        populate = 'vendorRep';
        select = 'name _id logo customField geo tools tags searchString whiteLabel range website vendorRep legalTerms';
    }

    Vendor
        .find(where)
        .select(select)
        .sort('-name')
        .populate(populate)
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.listForUser = function(req, res) {

    var where = {};

    var id = req.params.userId;

    if (id) {
        where = {
            $or: [{
                salesRep: id
            }, {
                vendorRep: id
            }]
        };
    }

    Vendor
        .find(where)
        .sort('-name')
        .populate('programIds programs salesRep vendorRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.listNotForUser = function(req, res) {

    var where = {};

    var id = req.params.userId;

    if (id) {
        where = {
            $nor: [{
                salesRep: id
            }, {
                vendorRep: id
            }]
        };
    }

    Vendor
        .find(where)
        .sort('-name')
        .populate('programIds programs salesRep vendorRep')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * List of Vendors
 */
exports.getAllNames = function(req, res) {
    Vendor
        .find()
        .select('_id name legalTerms')
        .sort('-created')
        .populate('programIds salesRep programs')
        .exec(function(err, vendors) {
            if (err) {
                res.failure(err);
            } else {
                res.ok(vendors);
            }
        });
};

/**
 * Get distinct vendor tags
 *
 */
exports.getDistinctTags = function(req, res) {
    Vendor.distinct(req.params.tagType, {}, function (err, result) {
        if (err) res.failure(err);
        res.ok(result);
    });
};

/**
 * Get programs for a vendor
 *
 */
var Program = mongoose.model('Program');

exports.getCurrentVendorPrograms = function(req, res) {
    res.ok(req.vendor.programs);
};

exports.getAvailableVendorPrograms = function(req, res) {
    var theIds = _.pluck(req.vendor.programs, '_id');
    if (!theIds) theIds = [];
    Program.find().where('_id').nin(theIds).sort('-created').exec(function(err, programs) {
        if (err) {
            res.failure(err);
        } else {
            res.ok(programs);
        }
    });
};

exports.getSalesRep = function(req, res) {
    res.ok(req.vendor.salesRep);
};
<|endoftext|>


<commit_before>$(function() {
  $('input[type=text][data-auto-permalink]').keyup(function() {
    var target = $(this).data('auto-permalink');
    $('#' + target).val(
      $(this).val().toLowerCase().replace(/[^a-z0-9 ]/g, '').replace(' ', '-')
    );
  });
});<commit_msg>Fix replacement of spaces in auto permalink<commit_after>$(function() {
  $('input[type=text][data-auto-permalink]').keyup(function() {
    var target = $(this).data('auto-permalink');
    $('#' + target).val(
      $(this).val().toLowerCase().replace(/[^a-z0-9 ]/g, '').replace(/ /g, '-')
    );
  });
});<|endoftext|>


<commit_before>const crypto = require('crypto');

module.exports.alias = [
	'rate',
	'rank'
];

module.exports.command = function screenshot(message) {
	if (!message.input) return message.channel.createMessage('I rate undefined a 11 out of 10');
	if (message.input.length > 100) message.input = `${message.input.substring(0, 100)}...`;
	const rank = parseInt(crypto.createHash('md5').update(message.content.toLowerCase()).digest('hex'), 16) % 11;
	return message.channel.createMessage(`I rate ${message.content} a ${rank} out of 10`);
};
<commit_msg>use message.input instead<commit_after>const crypto = require('crypto');

module.exports.alias = [
	'rate',
	'rank'
];

module.exports.command = function screenshot(message) {
	if (!message.input) return message.channel.createMessage('I rate undefined a 11 out of 10');
	const thing = message.input.length < 100 ? message.input : `${message.input.substring(0, 100)}...`;
	const rank = parseInt(crypto.createHash('md5').update(thing.toLowerCase()).digest('hex'), 16) % 11;
	return message.channel.createMessage(`I rate ${thing} a ${rank} out of 10`);
};
<|endoftext|>


<commit_before>define(["knockout", "jquery", "typeahead",
"less!app/less/typeahead"], function (ko, $) {
	ko.bindingHandlers.typeahead = {
		init: function (element, valueAccessor, allBindings) {
			// http://stackoverflow.com/a/19366003/1247130 get value to update properly when typeahead choice is selected.

			var templateName = ko.unwrap(allBindings().templateName);
			var mapping = ko.unwrap(allBindings().mappingFunction);
			var displayedProperty = ko.unwrap(allBindings().displayKey);

			var url = ko.unwrap(valueAccessor());
			var auth = (allBindings.has('authToken')) ? {
				"Authorization": "Bearer " + ko.unwrap(allBindings().authToken)
			} : {};
			var remoteData = {
				url: url,
				ajax: {
					headers: auth
				}
			};
			var resultsLimit = allBindings.get("limit") || 10;

			var suggestions = new Bloodhound({
				datumTokenizer: function (token) {
					return Bloodhound.tokenizers.whitespace(token);
				},
				queryTokenizer: Bloodhound.tokenizers.whitespace,
				remote: remoteData,
				limit: resultsLimit
			});
			suggestions.initialize();

			$(element)
				.typeahead({
					hint: true,
					highlight: true
				},
				{
					source: suggestions.ttAdapter(),
					displayKey: displayedProperty || function (item) {
						return item;
					},
					templates: {
						suggestion: function (item) {
							if (templateName) {
								var temp = document.createElement("div");
								var model = mapping ? mapping(item) : item;
								ko.renderTemplate(templateName, model, null, temp, "replaceChildren");

								return temp.innerHTML;
							}

							else {
								return item;
							}
						}
					}
				});
		}
	};
});<commit_msg>now updates value binding if bound to the input. will re init typeahed on the element if the url (valueaccessor) changes<commit_after>define(["knockout", "jquery", "typeahead",
"less!app/less/typeahead"], function (ko, $) {
	ko.bindingHandlers.typeahead = {
		update: function (element, valueAccessor, allBindings) {
			// http://stackoverflow.com/a/19366003/1247130 get value to update properly when typeahead choice is selected.

			var templateName = ko.unwrap(allBindings().templateName);
			var mapping = ko.unwrap(allBindings().mappingFunction);
			var displayedProperty = ko.unwrap(allBindings().displayKey);
			var value = allBindings.get('value');

			var url = ko.unwrap(valueAccessor());
			var auth = (allBindings.has('authToken')) ? {
				"Authorization": "Bearer " + ko.unwrap(allBindings().authToken)
			} : {};
			var remoteData = {
				url: url,
				ajax: {
					headers: auth
				}
			};
			var resultsLimit = allBindings.get("limit") || 10;

			var suggestions = new Bloodhound({
				datumTokenizer: function (token) {
					return Bloodhound.tokenizers.whitespace(token);
				},
				queryTokenizer: Bloodhound.tokenizers.whitespace,
				remote: remoteData,
				limit: resultsLimit
			});

			suggestions.initialize();

			$(element).typeahead('destroy');

			$(element)
				.typeahead({
					hint: true,
					highlight: true
				},
				{
					source: suggestions.ttAdapter(),
					displayKey: displayedProperty || function (item) {
						return item;
					},
					templates: {
						suggestion: function (item) {
							if (templateName) {
								var temp = document.createElement("div");
								var model = mapping ? mapping(item) : item;
								ko.renderTemplate(templateName, model, null, temp, "replaceChildren");

								return temp.innerHTML;
							}

							else {
								return item;
							}
						}
					}
				})
			.on("typeahead:selected typeahead:autocompleted", function (e, suggestion) {
				if (value && ko.isObservable(value)) {
					value(suggestion);
				}
			});
		}
	};
});<|endoftext|>


<commit_before>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe(FILL_ME_IN);
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe(FILL_ME_IN);
      expect(meglomaniac.henchWoman).toBe(FILL_ME_IN);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect(FILL_ME_IN).toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(FILL_ME_IN);
    expect(meglomaniac.calculateAge()).toBe(FILL_ME_IN);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(FILL_ME_IN);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(FILL_ME_IN);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(FILL_ME_IN);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(FILL_ME_IN);
    expect(colouredCircle.colour).toBe(FILL_ME_IN);

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe(FILL_ME_IN);
    expect(colouredCircle.describe()).toBe(FILL_ME_IN);
  });
});
<commit_msg>First 2 Exercises Completed<commit_after>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe("Joker");
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe("Harley");
      expect(meglomaniac.henchWoman).toBe(undefined);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect(FILL_ME_IN).toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(FILL_ME_IN);
    expect(meglomaniac.calculateAge()).toBe(FILL_ME_IN);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(FILL_ME_IN);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(FILL_ME_IN);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(FILL_ME_IN);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(FILL_ME_IN);
    expect(colouredCircle.colour).toBe(FILL_ME_IN);

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe(FILL_ME_IN);
    expect(colouredCircle.describe()).toBe(FILL_ME_IN);
  });
});
<|endoftext|>


<commit_before>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe(FILL_ME_IN);
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe(FILL_ME_IN);
      expect(meglomaniac.henchWoman).toBe(FILL_ME_IN);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect(FILL_ME_IN).toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(FILL_ME_IN);
    expect(meglomaniac.calculateAge()).toBe(FILL_ME_IN);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(FILL_ME_IN);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(FILL_ME_IN);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(FILL_ME_IN);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(FILL_ME_IN);
    expect(colouredCircle.colour).toBe(FILL_ME_IN);

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe(FILL_ME_IN);
    expect(colouredCircle.describe()).toBe(FILL_ME_IN);
  });
});
<commit_msg>Completed AboutObjects.js<commit_after>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe("Joker");
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe("Harley");
      expect(meglomaniac.henchWoman).toBe(undefined);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect("They are Pinky and the Brain Brain Brain Brain Brain").toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(2014);
    expect(meglomaniac.calculateAge()).toBe(44);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(true);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(false);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(false);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(true);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(false);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(undefined);
    expect(colouredCircle.colour).toBe("red");

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe("This circle has a radius of: 10");
    expect(colouredCircle.describe()).toBe("This circle has a radius of: 5");
  });
});
<|endoftext|>


<commit_before>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe(FILL_ME_IN);
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe(FILL_ME_IN);
      expect(meglomaniac.henchWoman).toBe(FILL_ME_IN);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect(FILL_ME_IN).toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(FILL_ME_IN);
    expect(meglomaniac.calculateAge()).toBe(FILL_ME_IN);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(FILL_ME_IN);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(FILL_ME_IN);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(FILL_ME_IN);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(FILL_ME_IN);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(FILL_ME_IN);
    expect(colouredCircle.colour).toBe(FILL_ME_IN);

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe(FILL_ME_IN);
    expect(colouredCircle.describe()).toBe(FILL_ME_IN);
  });
});
<commit_msg>made Objects tests pass<commit_after>describe("About Objects", function () {

  describe("Properties", function () {
    var meglomaniac;

    beforeEach(function () {
       meglomaniac = {  mastermind: "Joker", henchwoman: "Harley" };
    });

    it("should confirm objects are collections of properties", function () {
      expect(meglomaniac.mastermind).toBe("Joker");
    });

    it("should confirm that properties are case sensitive", function () {
      expect(meglomaniac.henchwoman).toBe("Harley");
      expect(meglomaniac.henchWoman).toBe(undefined);
    });
  });

  it("should know properties that are functions act like methods", function () {
    var meglomaniac = {
      mastermind : "Brain",
      henchman: "Pinky",
      battleCry: function (noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect("They are Pinky and the Brain Brain Brain Brain").toMatch(battleCry);
  });

  it("should confirm that when a function is attached to an object, 'this' refers to the object", function () {
    var currentDate = new Date()
    var currentYear = (currentDate.getFullYear());
    var meglomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function () {
        return currentYear - this.birthYear;
      }
    };

    expect(currentYear).toBe(2015);
    expect(meglomaniac.calculateAge()).toBe(45);
  });

  describe("'in' keyword", function () {
    var meglomaniac;
    beforeEach(function () {
      meglomaniac = {
        mastermind: "The Monarch",
        henchwoman: "Dr Girlfriend",
        theBomb: true
      };
    });

    it("should have the bomb", function () {

      var hasBomb = "theBomb" in meglomaniac;

      expect(hasBomb).toBe(true);
    });

    it("should not have the detonator however", function () {

      var hasDetonator = "theDetonator" in meglomaniac;

      expect(hasDetonator).toBe(false);
    });
  });

  it("should know that properties can be added and deleted", function () {
    var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" };

    expect("secretary" in meglomaniac).toBe(false);

    meglomaniac.secretary = "Agent Smith";
    expect("secretary" in meglomaniac).toBe(true);

    delete meglomaniac.henchman;
    expect("henchman" in meglomaniac).toBe(false);
  });

  it("should use prototype to add to all objects", function () {
    function Circle(radius)
    {
      this.radius = radius;
    }

    var simpleCircle = new Circle(10);
    var colouredCircle = new Circle(5);
    colouredCircle.colour = "red";

    expect(simpleCircle.colour).toBe(undefined);
    expect(colouredCircle.colour).toBe("red");

    Circle.prototype.describe = function () {
      return "This circle has a radius of: " + this.radius;
    };

    expect(simpleCircle.describe()).toBe("This circle has a radius of: 10");
    expect(colouredCircle.describe()).toBe("This circle has a radius of: 5");
  });
});
<|endoftext|>


<commit_before>import angular from 'angular';

angular.module('previewController', ['route-segment', 'selectedFilesService']).

controller('PreviewController', ['$scope', '$routeSegment', 'Alert', 'File', 'SelectedFiles', function($scope, $routeSegment, Alert, File, SelectedFiles) {
  var vm = this;

  vm.set_file_data = file => {
    $scope.file = file;
    $scope.url = '/filesystem/' + file.id + '/download';
  };

  $scope.$routeSegment = $routeSegment;
  $scope.id = $routeSegment.$routeParams.id;
  if ($scope.id !== undefined) {
    // Try to get file from the file list first, to avoid pinging the server.
    var file = SelectedFiles.get($scope.id);
    if (file) {
      vm.set_file_data(file);
    } else {
      // If the data isn't available, contact the server to fetch file info;
      // it may not have been loaded.
      var on_failure = error => {
        Alert.alerts.push({
          type: 'danger',
          message: 'Unable to retrieve metadata for file with UUID ' + $scope.id,
        });
      };
      File.get($scope.id).then(file => {
        vm.set_file_data(file);
      }, on_failure);
    }
  }
}]);
<commit_msg>Preview controller: add comments<commit_after>import angular from 'angular';

angular.module('previewController', ['route-segment', 'selectedFilesService']).

// Used to populate the preview pane, which displays:
// * the file in an iframe;
// * the filename;
// * a download link
//
// FIXME If the file being previewed belongs to a SIP that's already been started,
//       then the preview/download URL will 404. This looks really ugly to the
//       end user. It would be great to find a more elegant solution to this.
controller('PreviewController', ['$scope', '$routeSegment', 'Alert', 'File', 'SelectedFiles', function($scope, $routeSegment, Alert, File, SelectedFiles) {
  var vm = this;

  vm.set_file_data = file => {
    $scope.file = file;
    $scope.url = '/filesystem/' + file.id + '/download';
  };

  $scope.$routeSegment = $routeSegment;
  // The UUID of the file is located in the URL, which allows users to
  // share the URL with another user to let them preview the file.
  $scope.id = $routeSegment.$routeParams.id;
  if ($scope.id !== undefined) {
    // Try to get file from the file list first, to avoid pinging the server.
    var file = SelectedFiles.get($scope.id);
    if (file) {
      vm.set_file_data(file);
    } else {
      // If the data isn't available, contact the server to fetch file info;
      // it may not have been loaded.
      var on_failure = error => {
        Alert.alerts.push({
          type: 'danger',
          message: 'Unable to retrieve metadata for file with UUID ' + $scope.id,
        });
      };
      File.get($scope.id).then(file => {
        vm.set_file_data(file);
      }, on_failure);
    }
  }
}]);
<|endoftext|>