text: /*
   * jQuery File Upload Processing Plugin
   * https://github.com/blueimp/jQuery-File-Upload
   *
   * Copyright 2012, Sebastian Tschan
   * https://blueimp.net
   *
   * Licensed under the MIT license:
   * https://opensource.org/licenses/MIT
   */
  
  /* jshint nomen:false */
  /* global define, require, window */
  
  ;(function (factory) {
  	'use strict';
  	if (typeof define === 'function' && define.amd) {
  		// Register as an anonymous AMD module:
  		define([
  			'jquery',
  			'./jquery.fileupload'
  		], factory);
  	} else if (typeof exports === 'object') {
  		// Node/CommonJS:
  		factory(
  			require('jquery'),
  			require('./jquery.fileupload')
  		);
  	} else {
  		// Browser globals:
  		factory(
  			window.jQuery
  		);
  	}
  }(function ($) {
  	'use strict';
  
  	var originalAdd = $.blueimp.fileupload.prototype.options.add;
  
  	// The File Upload Processing plugin extends the fileupload widget
  	// with file processing functionality:
  	$.widget('blueimp.fileupload', $.blueimp.fileupload, {
  
  		options: {
  			// The list of processing actions:
  			processQueue: [
  				/*
  				{
  					action: 'log',
  					type: 'debug'
  				}
  				*/
  			],
  			add: function (e, data) {
  				var $this = $(this);
  				data.process(function () {
  					return $this.fileupload('process', data);
  				});
  				originalAdd.call(this, e, data);
  			}
  		},
  
  		processActions: {
  			/*
  			log: function (data, options) {
  				console[options.type](
  					'Processing "' + data.files[data.index].name + '"'
  				);
  			}
  			*/
  		},
  
  		_processFile: function (data, originalData) {
  			var that = this,
  				dfd = $.Deferred().resolveWith(that, [data]),
  				chain = dfd.promise();
  			this._trigger('process', null, data);
  			$.each(data.processQueue, function (i, settings) {
  				var func = function (data) {
  					if (originalData.errorThrown) {
  						return $.Deferred()
  							.rejectWith(that, [originalData]).promise();
  					}
  					return that.processActions[settings.action].call(
  						that,
  						data,
  						settings
  					);
  				};
  				chain = chain.then(func, settings.always && func);
  			});
  			chain
  				.done(function () {
  					that._trigger('processdone', null, data);
  					that._trigger('processalways', null, data);
  				})
  				.fail(function () {
  					that._trigger('processfail', null, data);
  					that._trigger('processalways', null, data);
  				});
  			return chain;
  		},
  
  		// Replaces the settings of each processQueue item that
  		// are strings starting with an "@", using the remaining
  		// substring as key for the option map,
  		// e.g. "@autoUpload" is replaced with options.autoUpload:
  		_transformProcessQueue: function (options) {
  			var processQueue = [];
  			$.each(options.processQueue, function () {
  				var settings = {},
  					action = this.action,
  					prefix = this.prefix === true ? action : this.prefix;
  				$.each(this, function (key, value) {
  					if ($.type(value) === 'string' &&
  						value.charAt(0) === '@') {
  						settings[key] = options[
  						value.slice(1) || (prefix ? prefix +
  							key.charAt(0).toUpperCase() + key.slice(1) : key)
  							];
  					} else {
  						settings[key] = value;
  					}
  
  				});
  				processQueue.push(settings);
  			});
  			options.processQueue = processQueue;
  		},
  
  		// Returns the number of files currently in the processsing queue:
  		processing: function () {
  			return this._processing;
  		},
  
  		// Processes the files given as files property of the data parameter,
  		// returns a Promise object that allows to bind callbacks:
  		process: function (data) {
  			var that = this,
  				options = $.extend({}, this.options, data);
  			if (options.processQueue && options.processQueue.length) {
  				this._transformProcessQueue(options);
  				if (this._processing === 0) {
  					this._trigger('processstart');
  				}
  				$.each(data.files, function (index) {
  					var opts = index ? $.extend({}, options) : options,
  						func = function () {
  							if (data.errorThrown) {
  								return $.Deferred()
  									.rejectWith(that, [data]).promise();
  							}
  							return that._processFile(opts, data);
  						};
  					opts.index = index;
  					that._processing += 1;
  					that._processingQueue = that._processingQueue.then(func, func)
  						.always(function () {
  							that._processing -= 1;
  							if (that._processing === 0) {
  								that._trigger('processstop');
  							}
  						});
  				});
  			}
  			return this._processingQueue;
  		},
  
  		_create: function () {
  			this._super();
  			this._processing = 0;
  			this._processingQueue = $.Deferred().resolveWith(this)
  				.promise();
  		}
  
  	});
  
  }));
  