<commit_before>(function (ng, $, _, location, page) {
	"use strict";
	/**
	 * Main controller for the pipeline launch page.
	 * @param $http AngularJS http object
	 * @param CartService a reference to the cart service (to clear it)
	 * @param notifications notifications
	 * @param ParameterService for passing parameter information between modal and page
	 * @constructor
	 */
	function PipelineController($scope, $http, CartService, notifications, ParameterService) {
		var vm = this;

		vm.parameters = ParameterService.getOriginalSettings();
		vm.selectedParameters = ParameterService.getSelectedParameters();

		$scope.$on('PARAMETERS_SAVED', function () {
			vm.selectedParameters = ParameterService.getSelectedParameters();
		});

		$scope.$on('REFERENCE_FILE_UPLOADED', function(event, uploaded) {
			vm.uploadedReferenceFile = uploaded.id;
		});

		/*
		 * Whether or not the page is waiting for a response from the server.
		 */
		vm.loading = false;

		/**
		 * Update the selected parameters in the parameter service
		 * for the modal dialog whenever we select a new set of parameters
		 * from the drop-down.
		 */
		vm.parameterSelected = function () {
			ParameterService.setSelectedParameters(vm.selectedParameters);
		};

		/**
		 * Launch the pipeline
		 */
		vm.launch = function () {
			var
			// reference file id (use the most recently uploaded or the selected one)
			ref          = typeof vm.uploadedReferenceFile !== "undefined" ? vm.uploadedReferenceFile : Number(ng.element('option:selected').val()),
			// User defined name for the pipeline
			name         = ng.element('#pipeline-name').val(),
			// All the selected sample single or pair-end files
			radioBtns    = ng.element("input[type='radio']:checked"),
			// Holds all the ids for the selected single-end
			single       = [],
			// Holds all the ids for the selected paired-end
			paired       = [],
			remoteSingle = [],
			remotePaired = [],
			// User-written description of the analysis
			description = ng.element('#analysis-description').val(),
			// Projects to share results with
			shared = [];

			if (name === null || name.length === 0) {
				vm.error = page.i18n.required;
			} else {
				// Hide the launch buttons and display a message that it has been sent.
				vm.loading = true;

				// Get a list of paired and single end files to run.
				_.forEach(radioBtns, function (c) {
					c = $(c);
					if (c.hasClass("remote")) {
						if (c.attr('data-type') === 'single_end') {
							remoteSingle.push(c.val());
						}
						else {
							remotePaired.push(c.val());
						}
					}
					else {
						if (c.attr('data-type') === 'single_end') {
							single.push(Number(c.val()));
						}
						else {
							paired.push(Number(c.val()));
						}
					}
				});

				ng.element('.share-project:checked').each(function() {
					var box = $(this);
					shared.push(box.val());
				});

				var currentSettings = ParameterService.getSelectedParameters().currentSettings;
				var selectedParameters = {
					"id"        : currentSettings.id,
					"parameters": currentSettings.parameters
				};

				// Create the parameter object;
				var params = {};
				if ($.isNumeric(ref)) {
					params['ref'] = ref;
				}
				if (single.length > 0) {
					params['single'] = single;
				}
				if (paired.length > 0) {
					params['paired'] = paired;
				}

				if (remoteSingle.length > 0) {
					params['remoteSingle'] = remoteSingle;
				}
				if (remotePaired.length > 0) {
					params['remotePaired'] = remotePaired;
				}

				if (_.keys(selectedParameters).length > 0 && selectedParameters.id !== 'no_parameters') {
					params['selectedParameters'] = selectedParameters;
				}
				params['name'] = name;
				params['description'] = description;

				if(shared.length > 0){
					params['sharedProjects'] = shared;
				}

				$http({
					url     : page.urls.startUrl,
					method  : 'POST',
					dataType: 'json',
					params  : params,
					headers : {
						"Content-Type": "application/json"
					}
				})
          .then(function(response) {
          	var data = response.data;
						if (data.success) {
							vm.success = true;
						}
						else {
							if (data.error) {
								vm.error = data.error;
							}
							else if (data.parameterError) {
								vm.paramError = data.parameters;
							}
							else if (data.pipelineError) {
								notifications.show({type: 'error', msg: data.pipelineError});
							}
						}
					});
			}
		};

		/**
		 * Remove a sample from the pipeline to be run.
		 *
		 * @param projectId the project id of the sample to remove
		 * @param sampleId the sample if to remove
		 */
		vm.removeSample = function (projectId, sampleId) {
			CartService.removeSample(projectId, sampleId).then(function () {
				ng.element('#sample-' + sampleId).remove();
				if (ng.element('.sample-container').length === 0) {
					location.reload();
				}
			});
		};

		/**
		 * Remove a sample from the pipeline to be run.
		 *
		 * @param projectId the project id of the sample to remove
		 * @param sampleId the sample if to remove
		 */
		vm.removeRemoteSample = function (sampleId) {
			CartService.removeRemoteSample(sampleId).then(function () {
				//need funky selection style here because css selectors don't like slashes
				ng.element("[id*='remote-sample-" + sampleId + "']").remove();
				if (ng.element('.sample-container').length === 0) {
					location.reload();
				}
			});
		};

		/**
		 * Clear the cart and redirect to the projects page
		 */
		vm.clearAndRedirect = function () {
			var clearPromise = CartService.clear();

			// after the cart is cleared, redirect the browser
			clearPromise.then(function () {
				window.location = page.urls.projectsPage;
			})
		};
	}

	/**
	 * Opens the modal dialog when the "Customize" button is pressed.
	 * @param $uibModal reference to the modal dialog.
	 */
	function ParameterModalController($uibModal) {
		var vm = this;

		vm.openModal = function () {
			$uibModal.open({
				templateUrl: '/parameters.html',
				controller : 'ParameterController as paras'
			});
		};
	}

	/**
	 * Controller for handling interaction with the modal dialog.
	 *
	 * @param $rootScope the root scope
	 * @param $http angular http reference
	 * @param $uibModalInstance the modal dialog
	 * @param ParameterService the service for handling parameter state
	 */
	function ParameterController($rootScope, $http, $uibModalInstance, ParameterService) {
		var vm = this;

		vm.selectedParameters = ParameterService.getSelectedParameters().currentSettings;
		vm.parameterSetName = vm.selectedParameters.label;
		vm.parametersModified = ParameterService.parametersModified;
		vm.saveParameters = false;

		/**
		 * When the "Use these parameters" button is pressed, mark
		 * that the parameters were updated in the service, optionally
		 * save the parameters to the server and close the modal.
		 */
		vm.update = function () {
			ParameterService.parametersModified = true;
			if (vm.saveParameters) {
				vm.saveAndUse();
			}
			$uibModalInstance.close();
		};

		/**
		 * Straight up close the modal.
		 */
		vm.close = function () {
			$uibModalInstance.dismiss();
		};

		/**
		 * Reset the specified value back to the default value.
		 * @param index the index in the list of parameters we can set.
		 */
		vm.reset = function (index) {
			ParameterService.resetCurrentSelectionIndex(index);
		};

		/**
		 * Persist the current parameter set to the server, add the
		 * saved set to the list of parameters on the page, and select
		 * the parameters.
		 */
		vm.saveAndUse = function () {
			var parametersToSave = {
				pipelineId      : page.pipeline.pipelineId,
				parameterSetName: vm.parameterSetName,
				// vm.selectedParameters.parameters is an array of maps, this will reduce it down
				// into a single map with key-value pairs from each parameter name to its corresponding
				// value. The final parameter to reduce is the empty map, that's our initial state.
				parameterValues : vm.selectedParameters.parameters.reduce(function (prev, curr) {
					prev[curr.name] = curr.value;
					return prev;
				}, {})
			};

			$http({
				url             : page.urls.saveParametersUrl,
				method          : "POST",
				headers         : {
					"Content-Type": "application/json"
				},
				transformRequest: undefined,
				data            : JSON.stringify(parametersToSave)
      }).then(function(data) {
				$uibModalInstance.dismiss();
				// on success, we can re-use the selected parameters in
				// this controller; update the id and label, then append
				// it to PIPELINE.parameters to have it magically appear!
				ParameterService.resetCurrentSelection();
				vm.selectedParameters.id = data.id;
				vm.selectedParameters.label = vm.parameterSetName;
				ParameterService.addSettingsToFront(vm.selectedParameters);
				$rootScope.$emit('PARAMETERS_SAVED');
			});
		};

		/**
		 * If any value is changed, mark that we're modifying parameters by
		 * changing the id of the parameter set to be custom (so the server knows
		 * to not add a reference to a set of saved parameters) and add
		 * a marker to the parameter set name to show the user that the
		 * params have been modified.
		 */
		vm.valueChanged = function () {
			vm.parametersModified = true;
			vm.selectedParameters.id = "custom";
			if (vm.parameterSetName.indexOf("(*)") == -1) {
				vm.parameterSetName = vm.parameterSetName + " (*)";
			}
		};
	}

	/**
	 * Service for handling parameter state.
	 */
	function ParameterService() {
		var svc = this;

		// Check to see if there are any parameters, if not put a default
		if(page.pipeline.parameters.length === 0) {
			page.pipeline.parameters.push({
				id: "no_parameters",
				label: "",
				parameters: []
			});
    }

		/**
		 * Duplicated copy of the original set of parameters on the page
		 * so that we can quickly roll back to default values for any
		 * parameter set.
		 */
    var originalSettings = page.pipeline.parameters.map(function (params) {
      return {
        currentSettings: ng.copy(params),
        defaultSettings: ng.copy(params)
      }
    });

		var selectedParameters = originalSettings[0];

		/**
		 * Get the settings that the page currently has.
		 */
		svc.getOriginalSettings = function () {
			return originalSettings;
		};

		/**
		 * Add customized parameters to the drop-down, we'll duplicate
		 * the values in here so that we can go back to defaults.
		 *
		 * @param settingsToAdd the settings to add to the current set of settings.
		 */
		svc.addSettingsToFront = function (settingsToAdd) {
			var savedParameters = {
				currentSettings: ng.copy(settingsToAdd),
				defaultSettings: ng.copy(settingsToAdd)
			};
			originalSettings.unshift(savedParameters);
			selectedParameters = originalSettings[0];
		};

		/**
		 * Get the currently selected parameters from the page.
		 */
		svc.getSelectedParameters = function () {
			return selectedParameters;
		};

		/**
		 * Set the current set of parameters on the page.
		 *
		 * @param currentSelection the parameters that are currently selected
		 */
		svc.setSelectedParameters = function (currentSelection) {
			selectedParameters = currentSelection;
		};

		/**
		 * Reset one of the values in the currently selected
		 * parameters back to its default value.
		 * @param index the index of the parameter to reset.
		 */
		svc.resetCurrentSelectionIndex = function (index) {
			selectedParameters.currentSettings.parameters[index] = ng.copy(selectedParameters.defaultSettings.parameters[index]);
		};

		/**
		 * Completely reset the current settings back to the set of default values.
		 */
		svc.resetCurrentSelection = function () {
			selectedParameters.currentSettings = ng.copy(selectedParameters.defaultSettings);
		}
  }

  function FileUploadCtrl($rootScope, Upload) {
	    var vm = this;

	    vm.referenceUploadStarted = false;

	    vm.upload = function (files) {
	    	if (files && files.length > 0) {
	    		vm.referenceUploadStarted = true;
		    	Upload.upload({
		    		url: page.urls.upload,
		    		file: files[0]
		    	}).progress(function (evt) {
		    		vm.progress = parseInt(100.0 * evt.loaded / evt.total);
          }).then(function(response) {
		    		vm.uploaded = {
		        			id: response["uploaded-file-id"],
		        			name: response["uploaded-file-name"]
		        	};
		    		vm.uploadError = false;
		        	$rootScope.$emit('REFERENCE_FILE_UPLOADED', vm.uploaded);
		        	vm.referenceUploadStarted = false;
		    	}).error(function(response) {
		    		vm.uploadError = response.error;
		    		vm.referenceUploadStarted = false;
		    	});
	    	}
	    };
  }

  ng.module('irida.pipelines', ['irida.cart', 'ngFileUpload'])
		.controller('PipelineController', ['$rootScope', '$http', 'CartService', 'notifications', 'ParameterService', PipelineController])
		.controller('ParameterModalController', ["$uibModal", ParameterModalController])
		.controller('ParameterController', ['$rootScope', '$http', '$uibModalInstance', 'ParameterService', ParameterController])
		.controller('FileUploadCtrl', ['$rootScope', 'Upload', FileUploadCtrl])
		.service('ParameterService', [ParameterService])
	;
})(window.angular, window.jQuery, window._, window.location, window.PAGE);
<commit_msg>fixed uploading reference<commit_after>(function (ng, $, _, location, page) {
	"use strict";
	/**
	 * Main controller for the pipeline launch page.
	 * @param $http AngularJS http object
	 * @param CartService a reference to the cart service (to clear it)
	 * @param notifications notifications
	 * @param ParameterService for passing parameter information between modal and page
	 * @constructor
	 */
	function PipelineController($scope, $http, CartService, notifications, ParameterService) {
		var vm = this;

		vm.parameters = ParameterService.getOriginalSettings();
		vm.selectedParameters = ParameterService.getSelectedParameters();

		$scope.$on('PARAMETERS_SAVED', function () {
			vm.selectedParameters = ParameterService.getSelectedParameters();
		});

		$scope.$on('REFERENCE_FILE_UPLOADED', function(event, uploaded) {
			vm.uploadedReferenceFile = uploaded.id;
		});

		/*
		 * Whether or not the page is waiting for a response from the server.
		 */
		vm.loading = false;

		/**
		 * Update the selected parameters in the parameter service
		 * for the modal dialog whenever we select a new set of parameters
		 * from the drop-down.
		 */
		vm.parameterSelected = function () {
			ParameterService.setSelectedParameters(vm.selectedParameters);
		};

		/**
		 * Launch the pipeline
		 */
		vm.launch = function () {
			var
			// reference file id (use the most recently uploaded or the selected one)
			ref          = typeof vm.uploadedReferenceFile !== "undefined" ? vm.uploadedReferenceFile : Number(ng.element('option:selected').val()),
			// User defined name for the pipeline
			name         = ng.element('#pipeline-name').val(),
			// All the selected sample single or pair-end files
			radioBtns    = ng.element("input[type='radio']:checked"),
			// Holds all the ids for the selected single-end
			single       = [],
			// Holds all the ids for the selected paired-end
			paired       = [],
			remoteSingle = [],
			remotePaired = [],
			// User-written description of the analysis
			description = ng.element('#analysis-description').val(),
			// Projects to share results with
			shared = [];

			if (name === null || name.length === 0) {
				vm.error = page.i18n.required;
			} else {
				// Hide the launch buttons and display a message that it has been sent.
				vm.loading = true;

				// Get a list of paired and single end files to run.
				_.forEach(radioBtns, function (c) {
					c = $(c);
					if (c.hasClass("remote")) {
						if (c.attr('data-type') === 'single_end') {
							remoteSingle.push(c.val());
						}
						else {
							remotePaired.push(c.val());
						}
					}
					else {
						if (c.attr('data-type') === 'single_end') {
							single.push(Number(c.val()));
						}
						else {
							paired.push(Number(c.val()));
						}
					}
				});

				ng.element('.share-project:checked').each(function() {
					var box = $(this);
					shared.push(box.val());
				});

				var currentSettings = ParameterService.getSelectedParameters().currentSettings;
				var selectedParameters = {
					"id"        : currentSettings.id,
					"parameters": currentSettings.parameters
				};

				// Create the parameter object;
				var params = {};
				if ($.isNumeric(ref)) {
					params['ref'] = ref;
				}
				if (single.length > 0) {
					params['single'] = single;
				}
				if (paired.length > 0) {
					params['paired'] = paired;
				}

				if (remoteSingle.length > 0) {
					params['remoteSingle'] = remoteSingle;
				}
				if (remotePaired.length > 0) {
					params['remotePaired'] = remotePaired;
				}

				if (_.keys(selectedParameters).length > 0 && selectedParameters.id !== 'no_parameters') {
					params['selectedParameters'] = selectedParameters;
				}
				params['name'] = name;
				params['description'] = description;

				if(shared.length > 0){
					params['sharedProjects'] = shared;
				}

				$http({
					url     : page.urls.startUrl,
					method  : 'POST',
					dataType: 'json',
					params  : params,
					headers : {
						"Content-Type": "application/json"
					}
				})
          .then(function(response) {
          	var data = response.data;
						if (data.success) {
							vm.success = true;
						}
						else {
							if (data.error) {
								vm.error = data.error;
							}
							else if (data.parameterError) {
								vm.paramError = data.parameters;
							}
							else if (data.pipelineError) {
								notifications.show({type: 'error', msg: data.pipelineError});
							}
						}
					});
			}
		};

		/**
		 * Remove a sample from the pipeline to be run.
		 *
		 * @param projectId the project id of the sample to remove
		 * @param sampleId the sample if to remove
		 */
		vm.removeSample = function (projectId, sampleId) {
			CartService.removeSample(projectId, sampleId).then(function () {
				ng.element('#sample-' + sampleId).remove();
				if (ng.element('.sample-container').length === 0) {
					location.reload();
				}
			});
		};

		/**
		 * Remove a sample from the pipeline to be run.
		 *
		 * @param projectId the project id of the sample to remove
		 * @param sampleId the sample if to remove
		 */
		vm.removeRemoteSample = function (sampleId) {
			CartService.removeRemoteSample(sampleId).then(function () {
				//need funky selection style here because css selectors don't like slashes
				ng.element("[id*='remote-sample-" + sampleId + "']").remove();
				if (ng.element('.sample-container').length === 0) {
					location.reload();
				}
			});
		};

		/**
		 * Clear the cart and redirect to the projects page
		 */
		vm.clearAndRedirect = function () {
			var clearPromise = CartService.clear();

			// after the cart is cleared, redirect the browser
			clearPromise.then(function () {
				window.location = page.urls.projectsPage;
			})
		};
	}

	/**
	 * Opens the modal dialog when the "Customize" button is pressed.
	 * @param $uibModal reference to the modal dialog.
	 */
	function ParameterModalController($uibModal) {
		var vm = this;

		vm.openModal = function () {
			$uibModal.open({
				templateUrl: '/parameters.html',
				controller : 'ParameterController as paras'
			});
		};
	}

	/**
	 * Controller for handling interaction with the modal dialog.
	 *
	 * @param $rootScope the root scope
	 * @param $http angular http reference
	 * @param $uibModalInstance the modal dialog
	 * @param ParameterService the service for handling parameter state
	 */
	function ParameterController($rootScope, $http, $uibModalInstance, ParameterService) {
		var vm = this;

		vm.selectedParameters = ParameterService.getSelectedParameters().currentSettings;
		vm.parameterSetName = vm.selectedParameters.label;
		vm.parametersModified = ParameterService.parametersModified;
		vm.saveParameters = false;

		/**
		 * When the "Use these parameters" button is pressed, mark
		 * that the parameters were updated in the service, optionally
		 * save the parameters to the server and close the modal.
		 */
		vm.update = function () {
			ParameterService.parametersModified = true;
			if (vm.saveParameters) {
				vm.saveAndUse();
			}
			$uibModalInstance.close();
		};

		/**
		 * Straight up close the modal.
		 */
		vm.close = function () {
			$uibModalInstance.dismiss();
		};

		/**
		 * Reset the specified value back to the default value.
		 * @param index the index in the list of parameters we can set.
		 */
		vm.reset = function (index) {
			ParameterService.resetCurrentSelectionIndex(index);
		};

		/**
		 * Persist the current parameter set to the server, add the
		 * saved set to the list of parameters on the page, and select
		 * the parameters.
		 */
		vm.saveAndUse = function () {
			var parametersToSave = {
				pipelineId      : page.pipeline.pipelineId,
				parameterSetName: vm.parameterSetName,
				// vm.selectedParameters.parameters is an array of maps, this will reduce it down
				// into a single map with key-value pairs from each parameter name to its corresponding
				// value. The final parameter to reduce is the empty map, that's our initial state.
				parameterValues : vm.selectedParameters.parameters.reduce(function (prev, curr) {
					prev[curr.name] = curr.value;
					return prev;
				}, {})
			};

			$http({
				url             : page.urls.saveParametersUrl,
				method          : "POST",
				headers         : {
					"Content-Type": "application/json"
				},
				transformRequest: undefined,
				data            : JSON.stringify(parametersToSave)
      }).then(function(data) {
				$uibModalInstance.dismiss();
				// on success, we can re-use the selected parameters in
				// this controller; update the id and label, then append
				// it to PIPELINE.parameters to have it magically appear!
				ParameterService.resetCurrentSelection();
				vm.selectedParameters.id = data.id;
				vm.selectedParameters.label = vm.parameterSetName;
				ParameterService.addSettingsToFront(vm.selectedParameters);
				$rootScope.$emit('PARAMETERS_SAVED');
			});
		};

		/**
		 * If any value is changed, mark that we're modifying parameters by
		 * changing the id of the parameter set to be custom (so the server knows
		 * to not add a reference to a set of saved parameters) and add
		 * a marker to the parameter set name to show the user that the
		 * params have been modified.
		 */
		vm.valueChanged = function () {
			vm.parametersModified = true;
			vm.selectedParameters.id = "custom";
			if (vm.parameterSetName.indexOf("(*)") == -1) {
				vm.parameterSetName = vm.parameterSetName + " (*)";
			}
		};
	}

	/**
	 * Service for handling parameter state.
	 */
	function ParameterService() {
		var svc = this;

		// Check to see if there are any parameters, if not put a default
		if(page.pipeline.parameters.length === 0) {
			page.pipeline.parameters.push({
				id: "no_parameters",
				label: "",
				parameters: []
			});
    }

		/**
		 * Duplicated copy of the original set of parameters on the page
		 * so that we can quickly roll back to default values for any
		 * parameter set.
		 */
    var originalSettings = page.pipeline.parameters.map(function (params) {
      return {
        currentSettings: ng.copy(params),
        defaultSettings: ng.copy(params)
      }
    });

		var selectedParameters = originalSettings[0];

		/**
		 * Get the settings that the page currently has.
		 */
		svc.getOriginalSettings = function () {
			return originalSettings;
		};

		/**
		 * Add customized parameters to the drop-down, we'll duplicate
		 * the values in here so that we can go back to defaults.
		 *
		 * @param settingsToAdd the settings to add to the current set of settings.
		 */
		svc.addSettingsToFront = function (settingsToAdd) {
			var savedParameters = {
				currentSettings: ng.copy(settingsToAdd),
				defaultSettings: ng.copy(settingsToAdd)
			};
			originalSettings.unshift(savedParameters);
			selectedParameters = originalSettings[0];
		};

		/**
		 * Get the currently selected parameters from the page.
		 */
		svc.getSelectedParameters = function () {
			return selectedParameters;
		};

		/**
		 * Set the current set of parameters on the page.
		 *
		 * @param currentSelection the parameters that are currently selected
		 */
		svc.setSelectedParameters = function (currentSelection) {
			selectedParameters = currentSelection;
		};

		/**
		 * Reset one of the values in the currently selected
		 * parameters back to its default value.
		 * @param index the index of the parameter to reset.
		 */
		svc.resetCurrentSelectionIndex = function (index) {
			selectedParameters.currentSettings.parameters[index] = ng.copy(selectedParameters.defaultSettings.parameters[index]);
		};

		/**
		 * Completely reset the current settings back to the set of default values.
		 */
		svc.resetCurrentSelection = function () {
			selectedParameters.currentSettings = ng.copy(selectedParameters.defaultSettings);
		}
  }

  function FileUploadCtrl($rootScope, Upload) {
	    var vm = this;

	    vm.referenceUploadStarted = false;

	    vm.upload = function(files) {
	      if (files && files.length > 0) {
	        vm.referenceUploadStarted = true;
	        Upload.upload({
	          url: page.urls.upload,
	          file: files[0]
	        }).progress(function(evt) {
	          vm.progress = parseInt(100.0 * evt.loaded / evt.total);
	        }).then(function(response) {
	          var data = response.data;
	          vm.uploaded = {
	            id: data["uploaded-file-id"],
	            name: data["uploaded-file-name"]
	          };
	          vm.uploadError = false;
	          $rootScope.$emit('REFERENCE_FILE_UPLOADED', vm.uploaded);
	          vm.referenceUploadStarted = false;
	        }, function(response) {
	          vm.referenceUploadStarted = false;
	          window.notifications.show({msg: response.data.error, type: 'error'});
	        });
	      }
	    };
  }

  ng.module('irida.pipelines', ['irida.cart', 'ngFileUpload'])
		.controller('PipelineController', ['$rootScope', '$http', 'CartService', 'notifications', 'ParameterService', PipelineController])
		.controller('ParameterModalController', ["$uibModal", ParameterModalController])
		.controller('ParameterController', ['$rootScope', '$http', '$uibModalInstance', 'ParameterService', ParameterController])
		.controller('FileUploadCtrl', ['$rootScope', 'Upload', FileUploadCtrl])
		.service('ParameterService', [ParameterService])
	;
})(window.angular, window.jQuery, window._, window.location, window.PAGE);
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import Toggle from 'react-toggle';
import ReactTooltip from 'react-tooltip';
import colorForPerformance from 'parser/shared/modules/features/Checklist2/helpers/colorForPerformance';

class PerformanceBar extends React.Component {
  static propTypes = {
    percent: PropTypes.number.isRequired,
  };

  render() {
    return (

        <div
          className="performance-bar"
          style={{
            width: `${this.props.percent * 100}%`,
            transition: 'background-color 800ms',
            backgroundColor: colorForPerformance(this.props.percent),
          }}
        />

    );
  }
}

class HealingEfficiencyBreakdown extends React.Component {
  static propTypes = {
    tracker: PropTypes.object.isRequired,
  };

  constructor() {
    super();
    this.state = {
      showHealing: true,
      showDamage: false,
      detailedView: false,
      showCooldowns: false,
    };
  }

  HealingEfficiencyTable = (props) => {
    const { tracker } = props;
    const { spells, topHpm, topDpm, topHpet, topDpet } = tracker.getAllSpellStats(this.state.showCooldowns);

    const spellArray = Object.keys(spells).map(function (key) {
      return spells[key];
    });
    spellArray.sort((a, b) => {
      if (a.hpm  b.hpm) {
        return -1;
      }
      else {
        if (a.dpm  b.dpm) {
          return -1;
        }
      }
      return 0;
    });

    const spellRows = spellArray.map((spellDetail => {
      if (spellDetail.casts > 0) {
        return this.HealingEfficiencySpellRow(spellDetail, topHpm, topDpm, topHpet, topDpet);
      }
      return null;
    }));

    return spellRows;
  };

  HealingEfficiencySpellRow = (spellDetail, topHpm, topDpm, topHpet, topDpet) => {
    return (

          <SpellIcon id={spellDetail.spell.id} /> {spellDetail.spell.name}

        {this.state.detailedView ? <this.DetailView spellDetail={spellDetail} /> : <this.BarView spellDetail={spellDetail} topHpm={topHpm} topDpm={topDpm} topHpet={topHpet} topDpet={topDpet} />}

    );
  };

  BarHeader = () => {
    return (
      <>
        {this.state.showHealing &&
        <>

            <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

            <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

        </>
        }
        {this.state.showDamage &&
        <>

            <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

            <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

        </>
        }
      </>
    );
  };

  BarView = (props) => {
    const { spellDetail, topHpm, topDpm, topHpet, topDpet } = props;
    const hasHealing = spellDetail.healingDone;
    const hasDamage = spellDetail.damageDone > 0;
    let width = 30;
    if (this.state.showHealing) width -= 10;
    if (this.state.showDamage) width -= 10;

    return (
      <>
        {this.state.showHealing &&
        <>
          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          <PerformanceBar percent={spellDetail.hpm / topHpm} />

          {hasHealing ? formatNumber(spellDetail.hpet) : '-'}
          <PerformanceBar percent={spellDetail.hpet / topHpet} />
        </>
        }
        {this.state.showDamage &&
        <>
          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          <PerformanceBar percent={spellDetail.dpm / topDpm} />

          {hasHealing ? formatNumber(spellDetail.dpet) : '-'}
          <PerformanceBar percent={spellDetail.dpet / topDpet} />
        </>
        }
      </>
    );
  };

  DetailHeader = () => {
    return (
      <>

          <dfn data-tip={`Total Casts (Number of targets hit)`}>Casts</dfn>

        Mana Spent
        {this.state.showHealing &&
        <>
          Healing Done
          Overhealing

            <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

            <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

        </>
        }
        {this.state.showDamage &&
        <>
          Damage Done

            <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

            <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

        </>
        }
      </>
    );
  };

  DetailView = (props) => {
    const { spellDetail } = props;
    const hasHealing = spellDetail.healingDone;
    const hasOverhealing = spellDetail.healingDone > 0 || spellDetail.overhealingDone > 0;
    const hasDamage = spellDetail.damageDone > 0;

    return (
      <>
        {spellDetail.casts} ({Math.floor(spellDetail.healingHits + spellDetail.damageHits)})

          {formatNumber(spellDetail.manaSpent)}
          {' (' + formatPercentage(spellDetail.manaPercentSpent) + '%)'}

        {this.state.showHealing &&
        <>

            {hasHealing ? formatNumber(spellDetail.healingDone) : '-'}
            {hasHealing ? ' (' + formatPercentage(spellDetail.percentHealingDone) + '%)' : ''}

            {hasOverhealing ? formatNumber(spellDetail.overhealingDone) : '-'}
            {hasOverhealing ? ' (' + formatPercentage(spellDetail.percentOverhealingDone) + '%)' : ''}

          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.hpet * 1000) : '-'}
        </>
        }
        {this.state.showDamage &&
        <>

            {hasDamage ? formatNumber(spellDetail.damageDone) : '-'}
            {hasDamage ? ' (' + formatPercentage(spellDetail.percentDamageDone) + '%)' : ''}

          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          {hasDamage ? formatNumber(spellDetail.dpet * 1000) : '-'}
        </>
        }
      </>
    );
  };

  componentDidUpdate() {
    ReactTooltip.rebuild();
  }

  render() {
    const { tracker } = this.props;

    return (

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showDamage: event.target.checked })}
                id="damage-toggle"
              />

                Show Damage

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showHealing: event.target.checked })}
                id="healing-toggle"
              />

                Show Healing

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showCooldowns: event.target.checked })}
                id="cooldown-toggle"
              />

                Show Cooldowns

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ detailedView: event.target.checked })}
                id="detailed-toggle"
              />

                Detailed View

                  Ability
                  {this.state.detailedView ? <this.DetailHeader /> : <this.BarHeader />}

                <this.HealingEfficiencyTable tracker={tracker} showHealing={this.state.showHealing} showDamage={this.state.showDamage} />

    );
  }
}

export default HealingEfficiencyBreakdown;
<commit_msg>making col header better for bar view<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import Toggle from 'react-toggle';
import ReactTooltip from 'react-tooltip';
import colorForPerformance from 'parser/shared/modules/features/Checklist2/helpers/colorForPerformance';

class PerformanceBar extends React.Component {
  static propTypes = {
    percent: PropTypes.number.isRequired,
  };

  render() {
    return (

        <div
          className="performance-bar"
          style={{
            width: `${this.props.percent * 100}%`,
            transition: 'background-color 800ms',
            backgroundColor: colorForPerformance(this.props.percent),
          }}
        />

    );
  }
}

class HealingEfficiencyBreakdown extends React.Component {
  static propTypes = {
    tracker: PropTypes.object.isRequired,
  };

  constructor() {
    super();
    this.state = {
      showHealing: true,
      showDamage: false,
      detailedView: false,
      showCooldowns: false,
    };
  }

  HealingEfficiencyTable = (props) => {
    const { tracker } = props;
    const { spells, topHpm, topDpm, topHpet, topDpet } = tracker.getAllSpellStats(this.state.showCooldowns);

    const spellArray = Object.keys(spells).map(function (key) {
      return spells[key];
    });
    spellArray.sort((a, b) => {
      if (a.hpm  b.hpm) {
        return -1;
      }
      else {
        if (a.dpm  b.dpm) {
          return -1;
        }
      }
      return 0;
    });

    const spellRows = spellArray.map((spellDetail => {
      if (spellDetail.casts > 0) {
        return this.HealingEfficiencySpellRow(spellDetail, topHpm, topDpm, topHpet, topDpet);
      }
      return null;
    }));

    return spellRows;
  };

  HealingEfficiencySpellRow = (spellDetail, topHpm, topDpm, topHpet, topDpet) => {
    return (

          <SpellIcon id={spellDetail.spell.id} /> {spellDetail.spell.name}

        {this.state.detailedView ? <this.DetailView spellDetail={spellDetail} /> : <this.BarView spellDetail={spellDetail} topHpm={topHpm} topDpm={topDpm} topHpet={topHpet} topDpet={topDpet} />}

    );
  };

  BarHeader = () => {
    return (
      <>
        {this.state.showHealing &&
        <>
          Healing per mana spent
          Healing per second spent casting
        </>
        }
        {this.state.showDamage &&
        <>
          Damage per mana spent
          Damage per second spent casting
        </>
        }
      </>
    );
  };

  BarView = (props) => {
    const { spellDetail, topHpm, topDpm, topHpet, topDpet } = props;
    const hasHealing = spellDetail.healingDone;
    const hasDamage = spellDetail.damageDone > 0;
    let width = 30;
    if (this.state.showHealing) width -= 10;
    if (this.state.showDamage) width -= 10;

    return (
      <>
        {this.state.showHealing &&
        <>
          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          <PerformanceBar percent={spellDetail.hpm / topHpm} />

          {hasHealing ? formatNumber(spellDetail.hpet) : '-'}
          <PerformanceBar percent={spellDetail.hpet / topHpet} />
        </>
        }
        {this.state.showDamage &&
        <>
          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          <PerformanceBar percent={spellDetail.dpm / topDpm} />

          {hasHealing ? formatNumber(spellDetail.dpet) : '-'}
          <PerformanceBar percent={spellDetail.dpet / topDpet} />
        </>
        }
      </>
    );
  };

  DetailHeader = () => {
    return (
      <>

          <dfn data-tip={`Total Casts (Number of targets hit)`}>Casts</dfn>

        Mana Spent
        {this.state.showHealing &&
        <>
          Healing Done
          Overhealing

            <dfn data-tip={`Healing per mana spent casting the spell`}>HPM</dfn>

            <dfn data-tip={`Healing per second spent casting the spell`}>HPET</dfn>

        </>
        }
        {this.state.showDamage &&
        <>
          Damage Done

            <dfn data-tip={`Damage per mana spent casting the spell`}>DPM</dfn>

            <dfn data-tip={`Damage per second spent casting the spell`}>DPET</dfn>

        </>
        }
      </>
    );
  };

  DetailView = (props) => {
    const { spellDetail } = props;
    const hasHealing = spellDetail.healingDone;
    const hasOverhealing = spellDetail.healingDone > 0 || spellDetail.overhealingDone > 0;
    const hasDamage = spellDetail.damageDone > 0;

    return (
      <>
        {spellDetail.casts} ({Math.floor(spellDetail.healingHits + spellDetail.damageHits)})

          {formatNumber(spellDetail.manaSpent)}
          {' (' + formatPercentage(spellDetail.manaPercentSpent) + '%)'}

        {this.state.showHealing &&
        <>

            {hasHealing ? formatNumber(spellDetail.healingDone) : '-'}
            {hasHealing ? ' (' + formatPercentage(spellDetail.percentHealingDone) + '%)' : ''}

            {hasOverhealing ? formatNumber(spellDetail.overhealingDone) : '-'}
            {hasOverhealing ? ' (' + formatPercentage(spellDetail.percentOverhealingDone) + '%)' : ''}

          {hasHealing ? formatNumber(spellDetail.hpm) : '-'}
          {hasHealing ? formatNumber(spellDetail.hpet * 1000) : '-'}
        </>
        }
        {this.state.showDamage &&
        <>

            {hasDamage ? formatNumber(spellDetail.damageDone) : '-'}
            {hasDamage ? ' (' + formatPercentage(spellDetail.percentDamageDone) + '%)' : ''}

          {hasDamage ? formatNumber(spellDetail.dpm) : '-'}
          {hasDamage ? formatNumber(spellDetail.dpet * 1000) : '-'}
        </>
        }
      </>
    );
  };

  componentDidUpdate() {
    ReactTooltip.rebuild();
  }

  render() {
    const { tracker } = this.props;

    return (

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showDamage: event.target.checked })}
                id="damage-toggle"
              />

                Show Damage

              <Toggle
                defaultChecked
                icons={false}
                onChange={event => this.setState({ showHealing: event.target.checked })}
                id="healing-toggle"
              />

                Show Healing

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ showCooldowns: event.target.checked })}
                id="cooldown-toggle"
              />

                Show Cooldowns

              <Toggle
                defaultChecked={false}
                icons={false}
                onChange={event => this.setState({ detailedView: event.target.checked })}
                id="detailed-toggle"
              />

                Detailed View

                  Ability
                  {this.state.detailedView ? <this.DetailHeader /> : <this.BarHeader />}

                <this.HealingEfficiencyTable tracker={tracker} showHealing={this.state.showHealing} showDamage={this.state.showDamage} />

    );
  }
}

export default HealingEfficiencyBreakdown;
<|endoftext|>


<commit_before>/* global document window */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import SprkMastheadMenuIcon from './components/SprkMastheadMenuIcon/SprkMastheadMenuIcon';
import SprkMastheadLittleNav from './components/SprkMastheadLittleNav/SprkMastheadLittleNav';
import SprkMastheadNarrowNav from './components/SprkMastheadNarrowNav/SprkMastheadNarrowNav';
import SprkMastheadBigNav from './components/SprkMastheadBigNav/SprkMastheadBigNav';
import SprkLink from '../SprkLink/SprkLink';

class SprkMasthead extends Component {
  constructor() {
    super();
    this.state = {
      narrowNavOpen: false,
      isScrolled: false,
    };
    this.toggleNarrowNav = this.toggleNarrowNav.bind(this);
  }

  componentDidMount() {
    window.addEventListener('scroll', () => {
      if (window.scrollY >= 10) {
        this.setState({ isScrolled: true });
      } else {
        this.setState({ isScrolled: false });
      }
    });
    window.addEventListener('orientationchange', () => {
      this.setState({ narrowNavOpen: false });
    });
  }

  toggleNarrowNav() {
    document.body.classList.toggle('sprk-u-Overflow--hidden');
    document.documentElement.classList.toggle('sprk-u-Overflow--hidden');

    this.setState(prevState => ({
      narrowNavOpen: !prevState.narrowNavOpen,
    }));

    // Don't add height: 100% if site's html & body el already have it (reapplying makes page jump)
    if (document.documentElement.style.height !== '100%') {
      document.documentElement.classList.toggle('sprk-u-Height--100');
    }
    if (document.body.style.height !== '100%') {
      document.body.classList.toggle('sprk-u-Height--100');
    }
  }

  render() {
    const {
      additionalClasses,
      analyticsString,
      bigNavLinks,
      idString,
      littleNavLinks,
      narrowNavLinks,
      narrowSelector,
      siteLogo,
      selector,
      utilityContents,
      variant,
    } = this.props;
    const { isScrolled, narrowNavOpen } = this.state;

    return (

          <SprkMastheadMenuIcon
            toggleNarrowNav={this.toggleNarrowNav}
            isOpen={narrowNavOpen}
          />

            <SprkLink variant="unstyled" href="/">
              {siteLogo}
            </SprkLink>

          {(littleNavLinks.length > 0 || utilityContents.length > 0) && (
            <SprkMastheadLittleNav
              selector={selector}
              spacing={variant === 'extended' ? 'medium' : 'large'}
              links={littleNavLinks}
              utilityContents={utilityContents}
            />
          )}

        {bigNavLinks.length > 0 && <SprkMastheadBigNav links={bigNavLinks} />}
        {narrowNavLinks.length > 0 && (
          <SprkMastheadNarrowNav
            selector={narrowSelector}
            links={narrowNavLinks}
            isOpen={narrowNavOpen}
          />
        )}

    );
  }
}

SprkMasthead.propTypes = {
  // classes to be added to the masthead
  additionalClasses: PropTypes.string,
  // assigned to data-analytics
  analyticsString: PropTypes.string,
  // array of link objects to use in building the big nav
  bigNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          text: PropTypes.string,
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        }),
      ),
    }),
  ),
  // assigned to data-id
  idString: PropTypes.string,
  // array of link objects to use in building the little nav
  littleNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
          text: PropTypes.string,
        }),
      ),
    }),
  ),
  // array of link objects to use in building the narrow nav
  narrowNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          text: PropTypes.string,
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        }),
      ),
    }),
  ),
  // object containing an array of objects to use in building the narrow selector
  narrowSelector: PropTypes.shape({
    choiceFunction: PropTypes.func,
    footer: PropTypes.node,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        information: PropTypes.string,
        text: PropTypes.string,
        title: PropTypes.string,
        value: PropTypes.string,
      }),
    ),
  }),
  // object containing an array of objects to use in building the selector
  selector: PropTypes.shape({
    choiceFunction: PropTypes.func,
    footer: PropTypes.node,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        information: PropTypes.string,
        text: PropTypes.string,
        title: PropTypes.string,
        value: PropTypes.string,
      }),
    ),
  }),
  // expects a component to render the logo
  siteLogo: PropTypes.node,
  // an array containing components to render into the utility area
  utilityContents: PropTypes.arrayOf(PropTypes.node),
  // the variant name to render
  variant: PropTypes.oneOf(['default', 'extended']),
};

SprkMasthead.defaultProps = {
  littleNavLinks: [],
  narrowNavLinks: [],
  bigNavLinks: [],
  utilityContents: [],
  variant: 'default',
};

export default SprkMasthead;
<commit_msg>start SprkMasthead update<commit_after>/* global document window */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import SprkMastheadMenuIcon from './components/SprkMastheadMenuIcon/SprkMastheadMenuIcon';
import SprkMastheadLittleNav from './components/SprkMastheadLittleNav/SprkMastheadLittleNav';
import SprkMastheadNarrowNav from './components/SprkMastheadNarrowNav/SprkMastheadNarrowNav';
import SprkMastheadBigNav from './components/SprkMastheadBigNav/SprkMastheadBigNav';
import SprkLink from '../SprkLink/SprkLink';

class SprkMasthead extends Component {
  constructor() {
    super();
    this.state = {
      narrowNavOpen: false,
      isScrolled: false,
    };
    this.toggleNarrowNav = this.toggleNarrowNav.bind(this);
  }

  componentDidMount() {
    window.addEventListener('scroll', () => {
      if (window.scrollY >= 10) {
        this.setState({ isScrolled: true });
      } else {
        this.setState({ isScrolled: false });
      }
    });
    window.addEventListener('orientationchange', () => {
      this.setState({ narrowNavOpen: false });
    });
  }

  toggleNarrowNav() {
    document.body.classList.toggle('sprk-u-Overflow--hidden');
    document.documentElement.classList.toggle('sprk-u-Overflow--hidden');

    this.setState(prevState => ({
      narrowNavOpen: !prevState.narrowNavOpen,
    }));

    // Don't add height: 100% if site's html & body el already have it (reapplying makes page jump)
    if (document.documentElement.style.height !== '100%') {
      document.documentElement.classList.toggle('sprk-u-Height--100');
    }
    if (document.body.style.height !== '100%') {
      document.body.classList.toggle('sprk-u-Height--100');
    }
  }

  render() {
    const {
      additionalClasses,
      analyticsString,
      bigNavLinks,
      idString,
      littleNavLinks,
      narrowNavLinks,
      narrowSelector,
      siteLogo,
      selector,
      utilityContents,
      variant,
      logoLink,
    } = this.props;
    const { isScrolled, narrowNavOpen } = this.state;

    return (

          <SprkMastheadMenuIcon
            toggleNarrowNav={this.toggleNarrowNav}
            isOpen={narrowNavOpen}
          />

            <SprkLink variant="unstyled" href={logoLink}>
              {siteLogo}
            </SprkLink>

          {(littleNavLinks.length > 0 || utilityContents.length > 0) && (
            <SprkMastheadLittleNav
              selector={selector}
              spacing={variant === 'extended' ? 'medium' : 'large'}
              links={littleNavLinks}
              utilityContents={utilityContents}
            />
          )}

        {bigNavLinks.length > 0 && <SprkMastheadBigNav links={bigNavLinks} />}
        {narrowNavLinks.length > 0 && (
          <SprkMastheadNarrowNav
            selector={narrowSelector}
            links={narrowNavLinks}
            isOpen={narrowNavOpen}
          />
        )}

    );
  }
}

SprkMasthead.propTypes = {
  // classes to be added to the masthead
  additionalClasses: PropTypes.string,
  // assigned to data-analytics
  analyticsString: PropTypes.string,
  // array of link objects to use in building the big nav
  bigNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          text: PropTypes.string,
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        }),
      ),
    }),
  ),
  // assigned to data-id
  idString: PropTypes.string,
  // array of link objects to use in building the little nav
  littleNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
          text: PropTypes.string,
        }),
      ),
    }),
  ),
  // array of link objects to use in building the narrow nav
  narrowNavLinks: PropTypes.arrayOf(
    PropTypes.shape({
      element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
      text: PropTypes.string,
      subNavLinks: PropTypes.arrayOf(
        PropTypes.shape({
          text: PropTypes.string,
          element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        }),
      ),
    }),
  ),
  // object containing an array of objects to use in building the narrow selector
  narrowSelector: PropTypes.shape({
    choiceFunction: PropTypes.func,
    footer: PropTypes.node,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        information: PropTypes.string,
        text: PropTypes.string,
        title: PropTypes.string,
        value: PropTypes.string,
      }),
    ),
  }),
  // object containing an array of objects to use in building the selector
  selector: PropTypes.shape({
    choiceFunction: PropTypes.func,
    footer: PropTypes.node,
    items: PropTypes.arrayOf(
      PropTypes.shape({
        element: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
        information: PropTypes.string,
        text: PropTypes.string,
        title: PropTypes.string,
        value: PropTypes.string,
      }),
    ),
  }),
  // expects a component to render the logo
  siteLogo: PropTypes.node,
  // an array containing components to render into the utility area
  utilityContents: PropTypes.arrayOf(PropTypes.node),
  // the variant name to render
  variant: PropTypes.oneOf(['default', 'extended']),
  // the href to render for the logo link
  logoLink: PropTypes.string,
};

SprkMasthead.defaultProps = {
  littleNavLinks: [],
  narrowNavLinks: [],
  bigNavLinks: [],
  utilityContents: [],
  variant: 'default',
  logoLink: '/',
};

export default SprkMasthead;
<|endoftext|>


<commit_before>var Promise			= require( "bluebird" );
var fs				= Promise.promisifyAll( require( "fs" ) );
var path			= require( "path" );

var CPUInterface = function()
{
	var self = this;
};

CPUInterface.prototype.Compose = function( platform )
{
	console.log( "CPU: Composing BBB cpu interface..." );

	// Temporary container used for cpu detection and info loading
	var cpu =
	{
		targetCPU: platform.cpu
	};

	var self = this;

	// Compose the CPU interface object
	return  self.LoadInfo( cpu )
			.then( self.CheckSupport )
			.then( self.LoadInterfaceImplementation );
};

CPUInterface.prototype.LoadInfo = function( cpu )
{
	console.log( "CPU: Loading BBB cpu info..." );

	return FindBeagleboneEEPROM()
			.then( ReadEEPROM )
			.then( ParseInfo )
			.then( function( info )
			{
				// Add revision and serial details to the interface object
				cpu.info =
				{
					revision: 	info.revision,
					serial:		info.serial
				}

				console.log( "CPU Info: " + JSON.stringify( cpu.info ) );

				return cpu;
			} );

	// Helper functions
	function FindBeagleboneEEPROM()
	{
		console.log( "CPU: Looking for BBB eeprom..." );

		return Promise.any([ fs.openAsync( "/sys/bus/nvmem/devices/at24-0/nvmem", "r" ),
						fs.openAsync( "/sys/class/nvmem/at24-0/nvmem", "r" ),
						fs.openAsync( "/sys/bus/i2c/devices/0-0050/eeprom", "r" ) ] )
						.catch( function( err )
						{
							throw new Error( "Failed to find BBB eeprom" );
						} );
	}

	function ReadEEPROM( fd )
	{
		console.log( "CPU: Opening bbb eeprom..." );

		return fs.readAsync( fd, new Buffer(244), 0, 244, 0 )
				.then( function (bytesRead, buffer)
				{
					console.log( buffer );
					console.log( "CPU: Got bbb eeprom data" );
					return buffer;
				});
	};

	function ParseInfo( data )
	{
		console.log( "CPU: parsing BBB eeprom.." );

		return Promise.try( function()
		{
			var revision = data.slice( 0, 16 );
			var serial = data.slice( 16, 28 );

			console.log( "CPU: Parsed BBB eeprom." );

			return { "revision": revision, "serial": serial };
		} );
	};
}

CPUInterface.prototype.CheckSupport = function( cpu )
{
	console.log( "CPU: Checking BBB support..." );

	return fs.readFileAsync( path.resolve( __dirname, "cpu/revisionInfo.json" ) )
			.then( JSON.parse )
			.then( function( json )
			{
				console.log( "CPU: Checking details against revision file..." );

				// Lookup cpu details in the json file, based on revision
				var details = json[ cpu.info.revision ];

				if( details !== undefined )
				{
					// Board is supported. Add the retrieved details to the interface object
					for( var prop in details )
					{
						cpu.info[ prop ] = details[ prop ];
					}

					// Add the info to the target CPU Interface
					cpu.targetCPU.info = cpu.info;

					return cpu;
				}
				else
				{
					throw new Error( "Detected CPU was not in list of supported models." );
				}
			} );
};

CPUInterface.prototype.LoadInterfaceImplementation = function( cpu )
{
	console.log( "CPU: Loading CPU interface implementation" );

	// Load and apply the interface implementation to the actual CPU interface
	require( "./cpu/setup.js" )( cpu.targetCPU );

	console.log( "CPU: Loaded CPU interface implementation" );
	return cpu;
};

module.exports = new CPUInterface();
<commit_msg>Second fix for read<commit_after>var Promise			= require( "bluebird" );
var fs				= Promise.promisifyAll( require( "fs" ) );
var path			= require( "path" );

var readAsync 		= Promise.promisify(fs.read, {multiArgs:true});

var CPUInterface = function()
{
	var self = this;
};

CPUInterface.prototype.Compose = function( platform )
{
	console.log( "CPU: Composing BBB cpu interface..." );

	// Temporary container used for cpu detection and info loading
	var cpu =
	{
		targetCPU: platform.cpu
	};

	var self = this;

	// Compose the CPU interface object
	return  self.LoadInfo( cpu )
			.then( self.CheckSupport )
			.then( self.LoadInterfaceImplementation );
};

CPUInterface.prototype.LoadInfo = function( cpu )
{
	console.log( "CPU: Loading BBB cpu info..." );

	return FindBeagleboneEEPROM()
			.then( ReadEEPROM )
			.then( ParseInfo )
			.then( function( info )
			{
				// Add revision and serial details to the interface object
				cpu.info =
				{
					revision: 	info.revision,
					serial:		info.serial
				}

				console.log( "CPU Info: " + JSON.stringify( cpu.info ) );

				return cpu;
			} );

	// Helper functions
	function FindBeagleboneEEPROM()
	{
		console.log( "CPU: Looking for BBB eeprom..." );

		return Promise.any([ fs.openAsync( "/sys/bus/nvmem/devices/at24-0/nvmem", "r" ),
						fs.openAsync( "/sys/class/nvmem/at24-0/nvmem", "r" ),
						fs.openAsync( "/sys/bus/i2c/devices/0-0050/eeprom", "r" ) ] )
						.catch( function( err )
						{
							throw new Error( "Failed to find BBB eeprom" );
						} );
	}

	function ReadEEPROM( fd )
	{
		console.log( "CPU: Opening bbb eeprom..." );

		return readAsync( fd, new Buffer(244), 0, 244, 0 )
				.spread( function (bytesRead, buffer)
				{
					console.log( buffer );
					console.log( "CPU: Got bbb eeprom data" );
					return buffer;
				});
	};

	function ParseInfo( data )
	{
		console.log( "CPU: parsing BBB eeprom.." );

		return Promise.try( function()
		{
			var revision = data.slice( 0, 16 );
			var serial = data.slice( 16, 28 );

			console.log( "CPU: Parsed BBB eeprom." );

			return { "revision": revision, "serial": serial };
		} );
	};
}

CPUInterface.prototype.CheckSupport = function( cpu )
{
	console.log( "CPU: Checking BBB support..." );

	return fs.readFileAsync( path.resolve( __dirname, "cpu/revisionInfo.json" ) )
			.then( JSON.parse )
			.then( function( json )
			{
				console.log( "CPU: Checking details against revision file..." );

				// Lookup cpu details in the json file, based on revision
				var details = json[ cpu.info.revision ];

				if( details !== undefined )
				{
					// Board is supported. Add the retrieved details to the interface object
					for( var prop in details )
					{
						cpu.info[ prop ] = details[ prop ];
					}

					// Add the info to the target CPU Interface
					cpu.targetCPU.info = cpu.info;

					return cpu;
				}
				else
				{
					throw new Error( "Detected CPU was not in list of supported models." );
				}
			} );
};

CPUInterface.prototype.LoadInterfaceImplementation = function( cpu )
{
	console.log( "CPU: Loading CPU interface implementation" );

	// Load and apply the interface implementation to the actual CPU interface
	require( "./cpu/setup.js" )( cpu.targetCPU );

	console.log( "CPU: Loaded CPU interface implementation" );
	return cpu;
};

module.exports = new CPUInterface();
<|endoftext|>


<commit_before>'use strict';

const config = require(process.cwd() + '/config')('testClient');
const include = config.include;

const request = require('supertest');
const assert = require('assert');

const req = request(config.serverUrl);

let Users;

include('test/util/createUsers')((ret) => {
  Users = ret;
});

describe('socket tests', function () {

  let loginStuff1;
  let channelId1;
  let socket1;

  it('login', function (done) {
    include('test/util/login.js')('bob@gmail.com', 'p1', (ls, err) => {
      loginStuff1 = ls;
      done(err);
    });
  });

  it('create a channel', function (done) {
    req.post('/api/channels')
      .set('Authorization', loginStuff1.token)
      .send({
        'users': [Users[0]._id, Users[1]._id],
        'name': 'A channel'
      })
      .expect('Content-Type', /json/)
      .expect(201)
      .end(function (err, res) {
        assert.equal(res.body.message, 'Channel A channel created');
        channelId1 = res.body._id;
        done(err);
      });
  });

  it('create a socket', function (done) {
    let WS = require('ws');
    socket1 = new WS('wss://localhost:3000/api/channels?token=' +
      loginStuff1.token, {}, {});
    done();
  });

  it('add message to a channel', function (done) {
    let validator = function (message) {
      let msg = JSON.parse(message);
      assert.equal(msg.text, 'this is a message');
      assert.equal(msg.postedBy, Users[0]._id);
      assert.notEqual(msg.postedTime, null);
      assert.equal(msg.channelId, channelId1);
      done();
    };
    socket1.on('message', validator);
    req.post('/api/channels/' + channelId1 + '/messages')
      .set('Authorization', loginStuff1.token)
      .send({
        'message': 'this is a message'
      })
      .expect(201)
      .end((err, res) => {
        assert.equal(err, null);
        let msg = res.body;
        assert.equal(msg.text, 'this is a message');
        assert.equal(msg.postedBy, Users[0]._id);
        assert.notEqual(msg.postedTime, null);
        assert.equal(msg.channelId, channelId1);
      });
  });
});

/*

  it('get channels for a user', function (done) {
    req.get('/api/channels/foruser/' + Users[0]._id)
      .expect(200)
      .end(function (err, res) {
        if (err) {
          throw err;
        }
        assert.equal(res.body.length, 0, 'no channels yet');
        done(err);
      });
  });

  it('get channels for user 0', function (done) {
    req.get('/api/channels/foruser/' + Users[0]._id)
      .expect(200)
      .end(function (err, res) {
        channelId = res.body[0]._id;
        done(err);
      });
  });

  it('create the sockets', function (done) {

    let WebSocket = require('ws');
    socket1 = new WebSocket('https://localhost:3000/api/channels', {}, {
      headers: JSON.stringify(user1)
    });
    socket2 = new WebSocket('https://localhost:3000/api/channels', {}, {
      headers: JSON.stringify(user2)
    });

    socket1.on('open', function open() {
      socket1.send(JSON.stringify(user1));
      socket2.on('open', function open() {
        socket2.send(JSON.stringify(user2));
        done();
      });
    });
  });

  it('assert that sockets are set up', function (done) {
    let WebSocket = require('ws');
    assert.equal(socket1.readyState, WebSocket.OPEN);
    assert.equal(socket2.readyState, WebSocket.OPEN);
    done();
  });

  it('set up on message handlers to test broadcasting', function (done) {

    socket1.on('message', function (data, flags) {
      // console.log('on socket2: ' + data);
      assert.equal(data.postedBy, user2);
      assert.equal(data.message,
        'this is a message see if user 1 gets it');
    });

    socket2.on('message', function (data, flags) {
      //console.log('on socket2: ' + data);
      assert.equal(data.postedBy, user1);
      assert.equal(data.message,
        'this is a message see if user 2 gets it');
    });

    done();
  });

  it('add message to a channel', function (done) {
    let call = req.post('/api/channels/' + channelId + '/messages');
    call.cookies = cookie2;
    call.send({
        'message': 'this is a message see if user 1 gets it'
      })
      .expect(200)
      .end(function (err, res) {
        newMessageResult = res.body;
        done(err)
      });
  });
  */
<commit_msg>all clean and all passing<commit_after>'use strict';

const config = require(process.cwd() + '/config')('testClient');
const include = config.include;

const request = require('supertest');
const assert = require('assert');

const req = request(config.serverUrl);

let Users;

include('test/util/createUsers')((ret) => {
  Users = ret;
});

describe('socket tests', function () {

  let loginStuff1;
  let channelId1;
  let socket1;

  it('login', function (done) {
    include('test/util/login.js')('bob@gmail.com', 'p1', (ls, err) => {
      loginStuff1 = ls;
      done(err);
    });
  });

  it('create a channel', function (done) {
    req.post('/api/channels')
      .set('Authorization', loginStuff1.token)
      .send({
        'users': [Users[0]._id, Users[1]._id],
        'name': 'A channel'
      })
      .expect('Content-Type', /json/)
      .expect(201)
      .end(function (err, res) {
        assert.equal(res.body.message, 'Channel A channel created');
        channelId1 = res.body._id;
        done(err);
      });
  });

  it('create a socket', function (done) {
    let WS = require('ws');
    socket1 = new WS('wss://localhost:3000/api/channels?token=' +
      loginStuff1.token, {}, {});
    done();
  });

  it('add message to a channel', function (done) {
    let validator = function (message) {
      let msg = JSON.parse(message);
      assert.equal(msg.text, 'this is a message');
      assert.equal(msg.postedBy, Users[0]._id);
      assert.notEqual(msg.postedTime, null);
      assert.equal(msg.channelId, channelId1);
      socket1.close();
      socket1 = null;
      done();
    };
    socket1.on('message', validator);
    req.post('/api/channels/' + channelId1 + '/messages')
      .set('Authorization', loginStuff1.token)
      .send({
        'message': 'this is a message'
      })
      .expect(201)
      .end((err, res) => {
        assert.equal(err, null);
        let msg = res.body;
        assert.equal(msg.text, 'this is a message');
        assert.equal(msg.postedBy, Users[0]._id);
        assert.notEqual(msg.postedTime, null);
        assert.equal(msg.channelId, channelId1);
      });
  });
});

/*

  it('get channels for a user', function (done) {
    req.get('/api/channels/foruser/' + Users[0]._id)
      .expect(200)
      .end(function (err, res) {
        if (err) {
          throw err;
        }
        assert.equal(res.body.length, 0, 'no channels yet');
        done(err);
      });
  });

  it('get channels for user 0', function (done) {
    req.get('/api/channels/foruser/' + Users[0]._id)
      .expect(200)
      .end(function (err, res) {
        channelId = res.body[0]._id;
        done(err);
      });
  });

  it('create the sockets', function (done) {

    let WebSocket = require('ws');
    socket1 = new WebSocket('https://localhost:3000/api/channels', {}, {
      headers: JSON.stringify(user1)
    });
    socket2 = new WebSocket('https://localhost:3000/api/channels', {}, {
      headers: JSON.stringify(user2)
    });

    socket1.on('open', function open() {
      socket1.send(JSON.stringify(user1));
      socket2.on('open', function open() {
        socket2.send(JSON.stringify(user2));
        done();
      });
    });
  });

  it('assert that sockets are set up', function (done) {
    let WebSocket = require('ws');
    assert.equal(socket1.readyState, WebSocket.OPEN);
    assert.equal(socket2.readyState, WebSocket.OPEN);
    done();
  });

  it('set up on message handlers to test broadcasting', function (done) {

    socket1.on('message', function (data, flags) {
      // console.log('on socket2: ' + data);
      assert.equal(data.postedBy, user2);
      assert.equal(data.message,
        'this is a message see if user 1 gets it');
    });

    socket2.on('message', function (data, flags) {
      //console.log('on socket2: ' + data);
      assert.equal(data.postedBy, user1);
      assert.equal(data.message,
        'this is a message see if user 2 gets it');
    });

    done();
  });

  it('add message to a channel', function (done) {
    let call = req.post('/api/channels/' + channelId + '/messages');
    call.cookies = cookie2;
    call.send({
        'message': 'this is a message see if user 1 gets it'
      })
      .expect(200)
      .end(function (err, res) {
        newMessageResult = res.body;
        done(err)
      });
  });
  */
<|endoftext|>


<commit_before>

//Draws the spectrogram onto the canvas
function drawSpectrogram0(array) {
    "use strict";
    // copy the current canvas onto the temp canvas
    tempCtx0.drawImage(canvas0, 0, 0, 400, 256);

    // iterate over the elements from the array
    for (var i = 0; i < array.length; i += 1) {
        // draw each pixel with the specific color
        var value = array[i];
        ctx0.fillStyle = hot.getColor(value).hex();

        // draw the line at the right side of the canvas
        ctx0.fillRect(400 - 1, 256 - i, 1, 1);
    }

    // set translate on the canvas
    ctx0.translate(-1, 0);
    // draw the copied image
    ctx0.drawImage(tempCanvas0, 0, 0, 400, 256, 0, 0, 400, 256);
    // reset the transformation matrix
    ctx0.setTransform(1, 0, 0, 1, 0, 0);
}

//function called by the javascript node
function audioProcess0() {
    "use strict";
    // get the average for the first channel
    var array = new Uint8Array(32);
    var sendArray = new Uint8Array(256);
    var j0 = 0;

    for(var j = 0; j < 256; j++){
        analyserArray0[j].getByteFrequencyData(array);
        var sum = 0;
        for(var k = 0; k < 32; k++){
            sum += array[k];
        }

        sendArray[j0] = sum/8;
        j0++;
    }

    //var array = new Uint8Array(analyser0.frequencyBinCount);
    //analyser0.getByteFrequencyData(array);

    // draw the spectrogram
    if (!source0.mediaElement.paused) {
        //console.log(document.getElementById("src1").paused);
        drawSpectrogram0(sendArray);
    }
}

//pull the canvas into a variable
canvas0 = document.getElementById("canvas0");

// get the audioCtx from the canvas to draw on
ctx0 = $("#canvas0").get()[0].getContext("2d");

// create a temp canvas we use for copying
tempCanvas0 = document.createElement("canvas");
tempCtx0 = tempCanvas0.getContext("2d");
tempCanvas0.width = 400;
tempCanvas0.height = 256;

// used for color distribution
hot = new chroma.ColorScale({
    colors: ['#000000', '#ff0000', '#ffff00', '#ffffff'],
    positions: [0, 0.25, 0.75, 1],
    mode: 'rgb',
    limits: [0, 300]
});

// setup a javascript node [affects speed]
javascriptNode0 = audioCtx.createScriptProcessor(2048, 1, 1);
// connect to destination, else it isn't called
javascriptNode0.connect(audioCtx.destination);

// Generating a data set for spectrogram from log.
var FilterArray0 = new Array(256);
var logStart0 = Math.log10(20);
var logEnd0 = Math.log10(20000);
//Generate 256 bins from a log range of 20-20000
var stepFunc0 = (logEnd0-logStart0) / 256;
var arrayNum0 = 0;
//Because of non-precise nature of the visualization, the loop will cycle
// through the bin's lower range.
for(var j = logStart0; j < logEnd0 + (stepFunc0/2); j+=stepFunc0){
    //Q = center_frequency / (top_frequency - bottom_frequency)
    var freqTop = Math.pow(10, (stepFunc0/2) + j);
    var freqCenter = Math.pow(10, (stepFunc0/4) + j);
    FilterArray0[arrayNum0] = audioCtx.createBiquadFilter();
    FilterArray0[arrayNum0].type = "bandpass";
    FilterArray0[arrayNum0].frequency.value = freqCenter;
    FilterArray0[arrayNum0].Q.value = freqCenter / (freqTop - Math.pow(10, j));
    gainNode0.connect(FilterArray0[arrayNum0]);
    arrayNum0++;
}
console.log(arrayNum0);

analyserArray0 = new Array(256);

for(var j = 0; j < 256; j++){
    analyserArray0[j] = audioCtx.createAnalyser();
    analyserArray0[j].fftSize = 32;
    FilterArray0[j].connect(analyserArray0[j]);
    //analyserArray0[j].connect(javascriptNode0);
}

// setup a analyzer
/*analyser0 = audioCtx.createAnalyser();
analyser0.smoothingTimeConstant = 0;
analyser0.fftSize = 256;*/
//analyser0.fftSize = 512;

// create a buffer source node
//gainNode0.connect(analyser0);
gainNode0.connect(javascriptNode0);

// when the javascript node is called
// we use information from the analyzer node
// to draw the volume
javascriptNode0.onaudioprocess = audioProcess0;<commit_msg>Fixed bug in fft bin calculation<commit_after>

//Draws the spectrogram onto the canvas
function drawSpectrogram0(array) {
    "use strict";
    // copy the current canvas onto the temp canvas
    tempCtx0.drawImage(canvas0, 0, 0, 400, 256);

    // iterate over the elements from the array
    for (var i = 0; i < array.length; i += 1) {
        // draw each pixel with the specific color
        var value = array[i];
        ctx0.fillStyle = hot.getColor(value).hex();

        // draw the line at the right side of the canvas
        ctx0.fillRect(400 - 1, 256 - i, 1, 1);
    }

    // set translate on the canvas
    ctx0.translate(-1, 0);
    // draw the copied image
    ctx0.drawImage(tempCanvas0, 0, 0, 400, 256, 0, 0, 400, 256);
    // reset the transformation matrix
    ctx0.setTransform(1, 0, 0, 1, 0, 0);
}

//function called by the javascript node
function audioProcess0() {
    "use strict";
    // get the average for the first channel
    var bin = analyserArray0[0].frequencyBinCount;
    console.log(bin);
    var array = new Uint8Array(bin);
    var sendArray = new Uint8Array(256);
    var j0 = 0;

    for(var j = 0; j < 256; j++){
        analyserArray0[j].getByteFrequencyData(array);
        var sum = 0;
        for(var k = 0; k < bin; k++){
            sum += array[k];
        }

        sendArray[j0] = sum/bin;
        j0++;
    }

    //var array = new Uint8Array(analyser0.frequencyBinCount);
    //analyser0.getByteFrequencyData(array);

    // draw the spectrogram
    if (!source0.mediaElement.paused) {
        //console.log(document.getElementById("src1").paused);
        drawSpectrogram0(sendArray);
    }
}

//pull the canvas into a variable
canvas0 = document.getElementById("canvas0");

// get the audioCtx from the canvas to draw on
ctx0 = $("#canvas0").get()[0].getContext("2d");

// create a temp canvas we use for copying
tempCanvas0 = document.createElement("canvas");
tempCtx0 = tempCanvas0.getContext("2d");
tempCanvas0.width = 400;
tempCanvas0.height = 256;

// used for color distribution
hot = new chroma.ColorScale({
    colors: ['#000000', '#ff0000', '#ffff00', '#ffffff'],
    positions: [0, 0.25, 0.75, 1],
    mode: 'rgb',
    limits: [0, 300]
});

// setup a javascript node [affects speed]
javascriptNode0 = audioCtx.createScriptProcessor(2048, 1, 1);
// connect to destination, else it isn't called
javascriptNode0.connect(audioCtx.destination);

// Generating a data set for spectrogram from log.
var FilterArray0 = new Array(256);
var logStart0 = Math.log10(20);
var logEnd0 = Math.log10(20000);
//Generate 256 bins from a log range of 20-20000
var stepFunc0 = (logEnd0-logStart0) / 256;
var arrayNum0 = 0;
//Because of non-precise nature of the visualization, the loop will cycle
// through the bin's lower range.
for(var j = logStart0; j < logEnd0 + (stepFunc0/2); j+=stepFunc0){
    //Q = center_frequency / (top_frequency - bottom_frequency)
    var freqTop = Math.pow(10, (stepFunc0/2) + j);
    var freqCenter = Math.pow(10, (stepFunc0/4) + j);
    FilterArray0[arrayNum0] = audioCtx.createBiquadFilter();
    FilterArray0[arrayNum0].type = "bandpass";
    FilterArray0[arrayNum0].frequency.value = freqCenter;
    FilterArray0[arrayNum0].Q.value = freqCenter / (freqTop - Math.pow(10, j));
    gainNode0.connect(FilterArray0[arrayNum0]);
    arrayNum0++;
}
//console.log(arrayNum0);

analyserArray0 = new Array(256);

for(var j = 0; j < 256; j++){
    analyserArray0[j] = audioCtx.createAnalyser();
    analyserArray0[j].fftSize = 32;
    FilterArray0[j].connect(analyserArray0[j]);
    //analyserArray0[j].connect(javascriptNode0);
}

// setup a analyzer
/*analyser0 = audioCtx.createAnalyser();
analyser0.smoothingTimeConstant = 0;
analyser0.fftSize = 256;*/
//analyser0.fftSize = 512;

// create a buffer source node
//gainNode0.connect(analyser0);
gainNode0.connect(javascriptNode0);

// when the javascript node is called
// we use information from the analyzer node
// to draw the volume
javascriptNode0.onaudioprocess = audioProcess0;<|endoftext|>


<commit_before>/**
  * This file is part of taolin project (http://taolin.fbk.eu)
  * Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
  * Authors: SoNet Group (see AUTHORS.txt)
  *
  * Taolin is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
  * the Free Software Foundation version 3 of the License.
  *
  * Taolin is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Affero General Public License for more details.
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with Taolin. If not, see <http://www.gnu.org/licenses/>.
  *
  */

/**
  * Ext.ux.fbk.sonet.WebcamCantinery Extension Class
  *
  * @author  Maurizio Napolitano <napo@fbk.eu>
  * @version 1.0
  * @class Ext.ux.fbk.sonet.WebcamCantinery
  *
Widget to show the picture snap from the cantinery

  * The snapshots are created with a script managed with a crontab (from monday to friday, from 11:55 to 14:03) and a php script

  *

    this is the json code passed
    {"webcam":{"sec4firstshot":63104,"duration":7680,"interval":30,"servicemessage":"Service available from 12 to 14 on working days","faq","..."}}

    Where:
        sec4firstshot -> the waiting seconds for the first call
        duration -> the duration time (in secs) of the service
        interval -> time (in secs) between the snapshots
        servicemessage -> message to show where the service is not available

*/

WebcamCanteen = Ext.extend(Ext.Panel, {
    border:true
    ,autoScroll:true
    ,iconCls:'webcam'
    ,frame:true
    ,layout: 'fit'
    ,collapsible:false
    ,hideCollapseTool:false
    ,initComponent: function(){
        var config = {
            items: [{
html: '

faq

Why the image is blurred
The image is blurred in order to ensure everybody\'s privacy is respected

There is an archive of the images?
No, the images are overwritten at each snapshot and they are never stored for more than 24 hours (as required by Italian law).

Why the image is sometimes black?
Sometimes the webcam does not have enough memory for handling new images. If you spot a "black image", please tell SoNet with a feedback and we will solve the problem.

',
                display: 'none',
                autoHeight: true,
                border: true
            }]
        };

        Ext.apply(this, Ext.apply(this.initialConfig, config));

        WebcamCanteen.superclass.initComponent.apply(this, arguments);
    }
    ,onRender: function(){
        var webcamid = this.getId();
        Ext.Ajax.request({
            url: 'webcams/gettime',
            scope: this,
            success: function (result, request) {
                var data = Ext.util.JSON.decode(result.responseText);
                Ext.apply(this, data);

                $('#webcam_'+ webcamid +'> p')
                    .text(this.servicemessage);
                $('#webcam_' + webcamid + '_faq').hide();

                var task = {
                    run: function(){
                        var dateNow = new Date().getTime();
                        var img1 = "webcams/getsnapshot?v=" + dateNow;
                        if(task.taskRunCount < (this.duration / this.interval)){
                            $('#webcam_' + webcamid)
                                .find('img')
                                    .attr("src",img1)
                                    .css('display', 'block')
                                .end()
                                .find('p')
                                    .hide();
                        } else {
                            $('#webcam_' + webcamid)
                                .find('img')
                                    .hide()
                                .end()
                                .find('p')
                                    .show();
                            Ext.getCmp(this.portlet_id).updateWidget();
                        }
                    }
                    ,interval: this.interval * 1000
                    ,scope: this
                    ,duration: this.duration * 1000
                };
                this.reloadTask = task;
                this.dTask = new Ext.util.DelayedTask(
                    function(){
                        Ext.TaskMgr.start(this.reloadTask);
                    }
                    ,this
                );

                this.dTask.delay(this.sec4firstshot * 1000);
            }
        });
        WebcamCanteen.superclass.onRender.apply(this, arguments);
    }
});
Ext.reg('webcam', WebcamCanteen);
<commit_msg>another little bug fix in the webcam<commit_after>/**
  * This file is part of taolin project (http://taolin.fbk.eu)
  * Copyright (C) 2008, 2009 FBK Foundation, (http://www.fbk.eu)
  * Authors: SoNet Group (see AUTHORS.txt)
  *
  * Taolin is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
  * the Free Software Foundation version 3 of the License.
  *
  * Taolin is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Affero General Public License for more details.
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with Taolin. If not, see <http://www.gnu.org/licenses/>.
  *
  */

/**
  * Ext.ux.fbk.sonet.WebcamCantinery Extension Class
  *
  * @author  Maurizio Napolitano <napo@fbk.eu>
  * @version 1.0
  * @class Ext.ux.fbk.sonet.WebcamCantinery
  *
Widget to show the picture snap from the cantinery

  * The snapshots are created with a script managed with a crontab (from monday to friday, from 11:55 to 14:03) and a php script

  *

    this is the json code passed
    {"webcam":{"sec4firstshot":63104,"duration":7680,"interval":30,"servicemessage":"Service available from 12 to 14 on working days","faq","..."}}

    Where:
        sec4firstshot -> the waiting seconds for the first call
        duration -> the duration time (in secs) of the service
        interval -> time (in secs) between the snapshots
        servicemessage -> message to show where the service is not available

*/

WebcamCanteen = Ext.extend(Ext.Panel, {
    border:true
    ,autoScroll:true
    ,iconCls:'webcam'
    ,frame:true
    ,layout: 'fit'
    ,collapsible:false
    ,hideCollapseTool:false
    ,initComponent: function(){
        var config = {
            items: [{
html: '

faq

Why the image is blurred
The image is blurred in order to ensure everybody\'s privacy is respected

There is an archive of the images?
No, the images are overwritten at each snapshot and they are never stored for more than 24 hours (as required by Italian law).

Why the image is sometimes black?
Sometimes the webcam does not have enough memory for handling new images. If you spot a "black image", please tell SoNet with a feedback and we will solve the problem.

',
                display: 'none',
                autoHeight: true,
                border: true
            }]
        };

        Ext.apply(this, Ext.apply(this.initialConfig, config));

        WebcamCanteen.superclass.initComponent.apply(this, arguments);
    }
    ,onRender: function(){
        var webcamid = this.getId();
        Ext.Ajax.request({
            url: 'webcams/gettime',
            scope: this,
            success: function (result, request) {
                var data = Ext.util.JSON.decode(result.responseText);
                Ext.apply(this, data);

                $('#webcam_'+ webcamid +'> p')
                    .text(this.servicemessage);
                $('#webcam_' + webcamid + '_faq').hide();

                var task = {
                    run: function(){
                        var dateNow = new Date().getTime();
                        var img1 = "webcams/getsnapshot?v=" + dateNow;
                        if(task.taskRunCount < (this.duration / this.interval)){
                            $('#webcam_' + webcamid)
                                .find('img')
                                    .attr("src",img1)
                                    .css('display', 'block')
                                .end()
                                .find('p')
                                    .hide();
                        } else {
                            $('#webcam_' + webcamid)
                                .find('img')
                                    .hide()
                                .end()
                                .find('p')
                                    .show();
                            Ext.getCmp(this.portlet_id).updateWidget();
                        }
                    }
                    ,interval: this.interval * 1000
                    ,scope: this
                    ,duration: this.duration * 1000
                };
                this.reloadTask = task;
                this.dTask = new Ext.util.DelayedTask(
                    function(){
                        Ext.TaskMgr.start(this.reloadTask);
                    }
                    ,this
                );

                this.dTask.delay(this.sec4firstshot * 1000);
            }
        });
        WebcamCanteen.superclass.onRender.apply(this, arguments);
    }
});
Ext.reg('webcam', WebcamCanteen);
<|endoftext|>


<commit_before>var $productTabs = $('.js-product-tab'),
    $productShowcases = $('.js-product-showcase'),
    urlProduct = w.location.hash;

    // look at the hash to determine what tab to display
if (!!urlProduct) {
  var productTab = '#' + urlProduct.substring(1, urlProduct.length);
  $(productTab + '-tab').addClass('product-tab--active');
  $productShowcases.hide();
  $(productTab + '-showcase').show();
} else {
  //otherwise open the first tab (testing)
  $productShowcases.hide();
  $('#testing-showcase').show();
  $('#testing-tab').addClass('product-tab--active');
}

$productTabs.on('click', function() {
  var $this = $(this);
  var tabTitle = $this.attr('id');

  $productTabs.removeClass('product-tab--active');
  $this.addClass('product-tab--active');
  $productShowcases.hide();
  tabTitle = tabTitle.substring(0, tabTitle.indexOf('-'));
  $('#' +  tabTitle + '-showcase').show();
});
<commit_msg>add js for hash change from top nav<commit_after>var $productTabs = $('.js-product-tab'),
    $productShowcases = $('.js-product-showcase'),
    urlProduct = w.location.hash;

// look at the hash to determine what tab to display
if (!!urlProduct) {
  var productTab = '#' + urlProduct.substring(1, urlProduct.length);
  $(productTab + '-tab').addClass('product-tab--active');
  $productShowcases.hide();
  $(productTab + '-showcase').show();
} else {
  //otherwise open the first tab (testing)
  $productShowcases.hide();
  $('#testing-showcase').show();
  $('#testing-tab').addClass('product-tab--active');
}

$productTabs.on('click', function() {
  var $this = $(this);
  var tabTitle = $this.attr('id');

  $productTabs.removeClass('product-tab--active');
  $this.addClass('product-tab--active');
  $productShowcases.hide();
  tabTitle = tabTitle.substring(0, tabTitle.indexOf('-'));
  $('#' +  tabTitle + '-showcase').show();
});

// If user selects nav dropdown, it changes the hash and needs to change the tabs
$(window).on('hashchange', function() {
  var productTab = '#' + w.location.hash.substring(1, w.location.hash.length);
  $('.js-product-tab').removeClass('product-tab--active');
  $(productTab + '-tab').addClass('product-tab--active');
  $productShowcases.hide();
  $(productTab + '-showcase').show();
});
<|endoftext|>