text: var pluginName = "dropify";
  
  /**
   * Dropify plugin
   *
   * @param {Object} element
   * @param {Array} options
   */
  function Dropify(element, options) {
  	if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
  		return;
  	}
  
  	var defaults = {
  		defaultFile: '',
  		maxFileSize: 0,
  		minWidth: 0,
  		maxWidth: 0,
  		minHeight: 0,
  		maxHeight: 0,
  		showRemove: true,
  		showLoader: true,
  		showErrors: true,
  		errorsPosition: 'overlay',
  		allowedFormats: ['portrait', 'square', 'landscape'],
  		messages: {
  			'default': 'Drag and drop a file here or click',
  			'replace': 'Drag and drop or click to replace',
  			'remove': 'Remove',
  			'error': 'Ooops, something wrong appended.'
  		},
  		error: {
  			'fileSize': 'The file size is too big ({{ value }} max).',
  			'minWidth': 'The image width is too small ({{ value }}}px min).',
  			'maxWidth': 'The image width is too big ({{ value }}}px max).',
  			'minHeight': 'The image height is too small ({{ value }}}px min).',
  			'maxHeight': 'The image height is too big ({{ value }}px max).',
  			'imageFormat': 'The image format is not allowed ({{ value }} only).'
  		},
  		tpl: {
  			wrap: '<div class="dropify-wrapper"></div>',
  			loader: '<div class="dropify-loader"></div>',
  			message: '<div class="dropify-message"><span class="file-icon" /> <p>{{ default }}</p></div>',
  			preview: '<div class="dropify-preview"><span class="dropify-render"></span><div class="dropify-infos"><div class="dropify-infos-inner"><p class="dropify-infos-message">{{ replace }}</p></div></div></div>',
  			filename: '<p class="dropify-filename"><span class="file-icon"></span> <span class="dropify-filename-inner"></span></p>',
  			clearButton: '<button type="button" class="dropify-clear">{{ remove }}</button>',
  			errorLine: '<p class="dropify-error">{{ error }}</p>',
  			errorsContainer: '<div class="dropify-errors-container"><ul></ul></div>'
  		}
  	};
  
  	this.element = element;
  	this.input = $(this.element);
  	this.wrapper = null;
  	this.preview = null;
  	this.filenameWrapper = null;
  	this.settings = $.extend(true, defaults, options, this.input.data());
  	this.imgFileExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp'];
  	this.errorsEvent = $.Event('dropify.errors');
  	this.isDisabled = false;
  	this.isInit = false;
  	this.file = {
  		object: null,
  		name: null,
  		size: null,
  		width: null,
  		height: null,
  		type: null
  	};
  
  	if (!Array.isArray(this.settings.allowedFormats)) {
  		this.settings.allowedFormats = this.settings.allowedFormats.split(' ');
  	}
  
  	this.onChange = this.onChange.bind(this);
  	this.clearElement = this.clearElement.bind(this);
  	this.onFileReady = this.onFileReady.bind(this);
  
  	this.translateMessages();
  	this.createElements();
  	this.setContainerSize();
  
  	this.errorsEvent.errors = [];
  
  	this.input.on('change', this.onChange);
  }
  
  /**
   * On change event
   */
  Dropify.prototype.onChange = function () {
  	this.resetPreview();
  	this.readFile(this.element);
  };
  
  /**
   * Create dom elements
   */
  Dropify.prototype.createElements = function () {
  	this.isInit = true;
  	this.input.wrap($(this.settings.tpl.wrap));
  	this.wrapper = this.input.parent();
  
  	var messageWrapper = $(this.settings.tpl.message).insertBefore(this.input);
  	$(this.settings.tpl.errorLine).appendTo(messageWrapper);
  
  	if (this.isTouchDevice() === true) {
  		this.wrapper.addClass('touch-fallback');
  	}
  
  	if (this.input.attr('disabled')) {
  		this.isDisabled = true;
  		this.wrapper.addClass('disabled');
  	}
  
  	if (this.settings.showLoader === true) {
  		this.loader = $(this.settings.tpl.loader);
  		this.loader.insertBefore(this.input);
  	}
  
  	this.preview = $(this.settings.tpl.preview);
  	this.preview.insertAfter(this.input);
  
  	if (this.isDisabled === false && this.settings.showRemove === true) {
  		this.clearButton = $(this.settings.tpl.clearButton);
  		this.clearButton.insertAfter(this.input);
  		this.clearButton.on('click', this.clearElement);
  	}
  
  	this.filenameWrapper = $(this.settings.tpl.filename);
  	this.filenameWrapper.prependTo(this.preview.find('.dropify-infos-inner'));
  
  	if (this.settings.showErrors === true) {
  		this.errorsContainer = $(this.settings.tpl.errorsContainer);
  
  		if (this.settings.errorsPosition === 'outside') {
  			this.errorsContainer.insertAfter(this.wrapper);
  		} else {
  			this.errorsContainer.insertBefore(this.input);
  		}
  	}
  
  	var defaultFile = this.settings.defaultFile || '';
  
  	if (defaultFile.trim() != '') {
  		this.file.name = this.cleanFilename(defaultFile);
  		this.setPreview(defaultFile);
  	}
  };
  
  /**
   * Read the file using FileReader
   *
   * @param  {Object} input
   */
  Dropify.prototype.readFile = function (input) {
  	if (input.files && input.files[0]) {
  		var reader = new FileReader();
  		var image = new Image();
  		var file = input.files[0];
  		var srcBase64 = null;
  		var _this = this;
  		var eventFileReady = $.Event("dropify.fileReady");
  
  		this.clearErrors();
  		this.showLoader();
  
  		this.setFileInformations(file);
  		reader.readAsDataURL(file);
  
  		this.errorsEvent.errors = [];
  
  		this.checkFileSize();
  
  		reader.onload = function (_file) {
  			srcBase64 = _file.target.result;
  			if (this.isImage()) {
  				image.src = _file.target.result;
  				image.onload = function () {
  					_this.setFileDimensions(this.width, this.height);
  					_this.validateImage();
  					_this.input.trigger(eventFileReady, [srcBase64]);
  				};
  			} else {
  				this.input.trigger(eventFileReady, [srcBase64]);
  			}
  		}.bind(this);
  
  		this.input.on('dropify.fileReady', this.onFileReady);
  	}
  };
  
  /**
   * On file ready to show
   *
   * @param  {Event} event
   * @param  {String} src
   */
  Dropify.prototype.onFileReady = function (event, src) {
  	this.input.off('dropify.fileReady', this.onFileReady);
  
  	if (this.errorsEvent.errors.length === 0) {
  		this.setPreview(src, this.file.name);
  	} else {
  		this.input.trigger(this.errorsEvent, [this]);
  		for (var i = this.errorsEvent.errors.length - 1; i >= 0; i--) {
  			var errorNamespace = this.errorsEvent.errors[i].namespace;
  			var errorKey = errorNamespace.split('.').pop();
  			this.showError(errorKey);
  		}
  
  		if (typeof this.errorsContainer !== "undefined") {
  			this.errorsContainer.addClass('visible');
  
  			var errorsContainer = this.errorsContainer;
  			setTimeout(function () {
  				errorsContainer.removeClass('visible');
  			}, 1000);
  		}
  
  		this.wrapper.addClass('has-error');
  		this.resetPreview();
  		this.clearElement();
  	}
  };
  
  /**
   * Set file informations
   *
   * @param {File} file
   */
  Dropify.prototype.setFileInformations = function (file) {
  	this.file.object = file;
  	this.file.name = file.name;
  	this.file.size = file.size;
  	this.file.type = file.type;
  	this.file.width = null;
  	this.file.height = null;
  };
  
  /**
   * Set file dimensions
   *
   * @param {Int} width
   * @param {Int} height
   */
  Dropify.prototype.setFileDimensions = function (width, height) {
  	this.file.width = width;
  	this.file.height = height;
  };
  
  /**
   * Set the preview and animate it
   *
   * @param {String} src
   */
  Dropify.prototype.setPreview = function (src) {
  	this.wrapper.removeClass('has-error').addClass('has-preview');
  	this.filenameWrapper.children('.dropify-filename-inner').html(this.file.name);
  	var render = this.preview.children('.dropify-render');
  
  	this.hideLoader();
  
  	if (this.isImage() === true) {
  		var imgTag = $('<img />').attr('src', src);
  
  		if (this.settings.height) {
  			imgTag.css("max-height", this.settings.height);
  		}
  
  		imgTag.appendTo(render);
  	} else {
  		$('<i />').attr('class', 'dropify-font-file').appendTo(render);
  		$('<span class="dropify-extension" />').html(this.getFileType()).appendTo(render);
  	}
  	this.preview.fadeIn();
  };
  
  /**
   * Reset the preview
   */
  Dropify.prototype.resetPreview = function () {
  	this.wrapper.removeClass('has-preview');
  	var render = this.preview.children('.dropify-render');
  	render.find('.dropify-extension').remove();
  	render.find('i').remove();
  	render.find('img').remove();
  	this.preview.hide();
  	this.hideLoader();
  };
  
  /**
   * Clean the src and get the filename
   *
   * @param  {String} src
   *
   * @return {String} filename
   */
  Dropify.prototype.cleanFilename = function (src) {
  	var filename = src.split('\\').pop();
  	if (filename == src) {
  		filename = src.split('/').pop();
  	}
  
  	return src != "" ? filename : '';
  };
  
  /**
   * Clear the element, events are available
   */
  Dropify.prototype.clearElement = function () {
  	if (this.errorsEvent.errors.length === 0) {
  		var eventBefore = $.Event("dropify.beforeClear");
  		this.input.trigger(eventBefore, [this]);
  
  		if (eventBefore.result !== false) {
  			this.resetFile();
  			this.input.val('');
  			this.resetPreview();
  
  			this.input.trigger($.Event("dropify.afterClear"), [this]);
  		}
  	} else {
  		this.resetFile();
  		this.input.val('');
  		this.resetPreview();
  	}
  };
  
  /**
   * Reset file informations
   */
  Dropify.prototype.resetFile = function () {
  	this.file.object = null;
  	this.file.name = null;
  	this.file.size = null;
  	this.file.type = null;
  	this.file.width = null;
  	this.file.height = null;
  };
  
  /**
   * Set the container height
   */
  Dropify.prototype.setContainerSize = function () {
  	if (this.settings.height) {
  		this.wrapper.height(this.settings.height);
  	}
  };
  
  /**
   * Test if it's touch screen
   *
   * @return {Boolean}
   */
  Dropify.prototype.isTouchDevice = function () {
  	return (('ontouchstart' in window)
  		|| (navigator.MaxTouchPoints > 0)
  		|| (navigator.msMaxTouchPoints > 0));
  };
  
  /**
   * Get the file type.
   *
   * @return {String}
   */
  Dropify.prototype.getFileType = function () {
  	return this.file.name.split('.').pop().toLowerCase();
  };
  
  /**
   * Test if the file is an image
   *
   * @return {Boolean}
   */
  Dropify.prototype.isImage = function () {
  	if (this.imgFileExtensions.indexOf(this.getFileType()) != "-1") {
  		return true;
  	}
  
  	return false;
  };
  
  /**
   * Translate messages if needed.
   */
  Dropify.prototype.translateMessages = function () {
  	for (var name in this.settings.tpl) {
  		for (var key in this.settings.messages) {
  			this.settings.tpl[name] = this.settings.tpl[name].replace('{{ ' + key + ' }}', this.settings.messages[key]);
  		}
  	}
  };
  
  /**
   * Check the limit filesize.
   */
  Dropify.prototype.checkFileSize = function () {
  	if (this.maxFileSizeToByte() !== 0 && this.file.size > this.maxFileSizeToByte()) {
  		this.pushError("fileSize");
  	}
  };
  
  /**
   * Convert filesize to byte.
   *
   * @return {Int} value
   */
  Dropify.prototype.maxFileSizeToByte = function () {
  	var value = 0;
  
  	if (this.settings.maxFileSize !== 0) {
  		var unit = this.settings.maxFileSize.slice(-1).toUpperCase(),
  			kb = 1024,
  			mb = kb * 1024,
  			gb = mb * 1024;
  
  		if (unit === 'K') {
  			value = parseFloat(this.settings.maxFileSize) * kb;
  		} else if (unit === 'M') {
  			value = parseFloat(this.settings.maxFileSize) * mb;
  		} else if (unit === 'G') {
  			value = parseFloat(this.settings.maxFileSize) * gb;
  		}
  	}
  
  	return value;
  };
  
  /**
   * Validate image dimensions and format
   */
  Dropify.prototype.validateImage = function () {
  	if (this.settings.minWidth !== 0 && this.settings.minWidth >= this.file.width) {
  		this.pushError("minWidth");
  	}
  
  	if (this.settings.maxWidth !== 0 && this.settings.maxWidth <= this.file.width) {
  		this.pushError("maxWidth");
  	}
  
  	if (this.settings.minHeight !== 0 && this.settings.minHeight >= this.file.height) {
  		this.pushError("minHeight");
  	}
  
  	if (this.settings.maxHeight !== 0 && this.settings.maxHeight <= this.file.height) {
  		this.pushError("maxHeight");
  	}
  
  	if (this.settings.allowedFormats.indexOf(this.getImageFormat()) == "-1") {
  		this.pushError("imageFormat");
  	}
  };
  
  /**
   * Get image format.
   *
   * @return {String}
   */
  Dropify.prototype.getImageFormat = function () {
  	if (this.file.width == this.file.height) {
  		return "square";
  	}
  
  	if (this.file.width < this.file.height) {
  		return "portrait";
  	}
  
  	if (this.file.width > this.file.height) {
  		return "landscape";
  	}
  };
  
  /**
   * Push error
   *
   * @param {String} errorKey
   */
  Dropify.prototype.pushError = function (errorKey) {
  	var e = $.Event("dropify.error." + errorKey);
  	this.errorsEvent.errors.push(e);
  	this.input.trigger(e, [this]);
  };
  
  /**
   * Clear errors
   */
  Dropify.prototype.clearErrors = function () {
  	if (typeof this.errorsContainer !== "undefined") {
  		this.errorsContainer.children('ul').html('');
  	}
  };
  
  /**
   * Show error in DOM
   *
   * @param  {String} errorKey
   */
  Dropify.prototype.showError = function (errorKey) {
  	if (typeof this.errorsContainer !== "undefined") {
  		this.errorsContainer.children('ul').append('<li>' + this.getError(errorKey) + '</li>');
  	}
  };
  
  /**
   * Get error message
   *
   * @return  {String} message
   */
  Dropify.prototype.getError = function (errorKey) {
  	var error = this.settings.error[errorKey],
  		value = '';
  
  	if (errorKey === 'fileSize') {
  		value = this.settings.maxFileSize;
  	} else if (errorKey === 'minWidth') {
  		value = this.settings.minWidth;
  	} else if (errorKey === 'maxWidth') {
  		value = this.settings.maxWidth;
  	} else if (errorKey === 'minHeight') {
  		value = this.settings.minHeight;
  	} else if (errorKey === 'maxHeight') {
  		value = this.settings.maxHeight;
  	} else if (errorKey === 'imageFormat') {
  		value = this.settings.allowedFormats.join(' ');
  	}
  
  	if (value !== '') {
  		return error.replace('{{ value }}', value);
  	}
  
  	return error;
  };
  
  /**
   * Show the loader
   */
  Dropify.prototype.showLoader = function () {
  	if (typeof this.loader !== "undefined") {
  		this.loader.show();
  	}
  };
  
  /**
   * Hide the loader
   */
  Dropify.prototype.hideLoader = function () {
  	if (typeof this.loader !== "undefined") {
  		this.loader.hide();
  	}
  };
  
  /**
   * Destroy dropify
   */
  Dropify.prototype.destroy = function () {
  	this.input.siblings().remove();
  	this.input.unwrap();
  	this.isInit = false;
  };
  
  /**
   * Init dropify
   */
  Dropify.prototype.init = function () {
  	this.createElements();
  };
  
  /**
   * Test if element is init
   */
  Dropify.prototype.isDropified = function () {
  	return this.isInit;
  };
  
  $.fn[pluginName] = function (options) {
  	this.each(function () {
  		if (!$.data(this, pluginName)) {
  			$.data(this, pluginName, new Dropify(this, options));
  		}
  	});
  
  	return this;
  };