text: /*!
   * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014 - 2015
   * @version 4.3.1
   *
   * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced features including the FileReader API.
   *
   * The plugin drastically enhances the HTML file input to preview multiple files on the client before upload. In
   * addition it provides the ability to preview content of images, text, videos, audio, html, flash and other objects.
   * It also offers the ability to upload and delete files using AJAX, and add files in batches (i.e. preview, append,
   * or remove before upload).
   *
   * Author: Kartik Visweswaran
   * Copyright: 2015, Kartik Visweswaran, Krajee.com
   * For more JQuery plugins visit http://plugins.krajee.com
   * For more Yii related demos visit http://demos.krajee.com
   */
  ! function(e) {
  	"use strict";
  	"function" == typeof define && define.amd ? define(["jquery"], e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery")) : e(window.jQuery)
  }(function(e) {
  	"use strict";
  	e.fn.fileinputLocales = {};
  	var i, t, a, r, n, l, o, s, d, c, p, u, f, v, g, m, h, w, _, b, C, x, y, T, F, E, I, $, k, P, S, D, U, A, j, L, z, O, R, N, B, M, Z, H, W, q, V, K, X, J, Q, Y, G, ee, ie;
  	i = ".fileinput", t = window.URL || window.webkitURL, a = function(e, i, t) {
  		return void 0 !== e && (t ? e === i : e.match(i))
  	}, r = function(e) {
  		if ("Microsoft Internet Explorer" !== navigator.appName) return !1;
  		if (10 === e) return new RegExp("msie\\s" + e, "i").test(navigator.userAgent);
  		var i, t = document.createElement("div");
  		return t.innerHTML = "<!--[if IE " + e + "]> <i></i> <![endif]-->", i = t.getElementsByTagName("i").length, document.body.appendChild(t), t.parentNode.removeChild(t), i
  	}, n = function() {
  		return new RegExp("Edge/[0-9]+", "i").test(navigator.userAgent)
  	}, l = function(e, t, a, r) {
  		var n = r ? t : t.split(" ").join(i + " ") + i;
  		e.off(n).on(n, a)
  	}, o = {
  		data: {},
  		init: function(e) {
  			var i = e.initialPreview,
  				t = e.id;
  			i.length > 0 && !X(i) && (i = i.split(e.initialPreviewDelimiter)), o.data[t] = {
  				content: i,
  				config: e.initialPreviewConfig,
  				tags: e.initialPreviewThumbTags,
  				delimiter: e.initialPreviewDelimiter,
  				template: e.previewGenericTemplate,
  				msg: function(i) {
  					return e._getMsgSelected(i)
  				},
  				initId: e.previewInitId,
  				footer: e._getLayoutTemplate("footer").replace(/\{progress}/g, e._renderThumbProgress()),
  				isDelete: e.initialPreviewShowDelete,
  				caption: e.initialCaption,
  				actions: function(i, t, a, r, n) {
  					return e._renderFileActions(i, t, a, r, n)
  				}
  			}
  		},
  		fetch: function(e) {
  			return o.data[e].content.filter(function(e) {
  				return null !== e
  			})
  		},
  		count: function(e, i) {
  			return o.data[e] && o.data[e].content ? i ? o.data[e].content.length : o.fetch(e).length : 0
  		},
  		get: function(i, t, a) {
  			var r, n, l = "init_" + t,
  				s = o.data[i],
  				d = s.config[t],
  				c = s.initId + "-" + l,
  				p = " file-preview-initial";
  			return a = void 0 === a ? !0 : a, null === s.content[t] ? "" : (K(d) || K(d.frameClass) || (p += " " + d.frameClass), r = s.template.replace(/\{previewId}/g, c).replace(/\{frameClass}/g, p).replace(/\{fileindex}/g, l).replace(/\{content}/g, s.content[t]).replace(/\{footer}/g, o.footer(i, t, a)), s.tags.length && s.tags[t] && (r = ee(r, s.tags[t])), K(d) || K(d.frameAttr) || (n = e(document.createElement("div")).html(r), n.find(".file-preview-initial").attr(d.frameAttr), r = n.html(), n.remove()), r)
  		},
  		add: function(i, t, a, r, n) {
  			var l, s = e.extend(!0, {}, o.data[i]);
  			return X(t) || (t = t.split(s.delimiter)), n ? (l = s.content.push(t) - 1, s.config[l] = a, s.tags[l] = r) : (l = t.length, s.content = t, s.config = a, s.tags = r), o.data[i] = s, l
  		},
  		set: function(i, t, a, r, n) {
  			var l, s, d = e.extend(!0, {}, o.data[i]);
  			if (t && t.length && (X(t) || (t = t.split(d.delimiter)), s = t.filter(function(e) {
  					return null !== e
  				}), s.length)) {
  				if (void 0 === d.content && (d.content = []), void 0 === d.config && (d.config = []), void 0 === d.tags && (d.tags = []), n) {
  					for (l = 0; l < t.length; l++) t[l] && d.content.push(t[l]);
  					for (l = 0; l < a.length; l++) a[l] && d.config.push(a[l]);
  					for (l = 0; l < r.length; l++) r[l] && d.tags.push(r[l])
  				} else d.content = t, d.config = a, d.tags = r;
  				o.data[i] = d
  			}
  		},
  		unset: function(e, i) {
  			var t = o.count(e);
  			if (t) {
  				if (1 === t) return o.data[e].content = [], void(o.data[e].config = []);
  				o.data[e].content[i] = null, o.data[e].config[i] = null
  			}
  		},
  		out: function(e) {
  			var i, t = "",
  				a = o.data[e],
  				r = o.count(e, !0);
  			if (0 === r) return {
  				content: "",
  				caption: ""
  			};
  			for (var n = 0; r > n; n++) t += o.get(e, n);
  			return i = a.msg(o.count(e)), {
  				content: t,
  				caption: i
  			}
  		},
  		footer: function(e, i, t) {
  			var a = o.data[e];
  			if (t = void 0 === t ? !0 : t, 0 === a.config.length || K(a.config[i])) return "";
  			var r = a.config[i],
  				n = J("caption", r) ? r.caption : "",
  				l = J("width", r) ? r.width : "auto",
  				s = J("url", r) ? r.url : !1,
  				d = J("key", r) ? r.key : null,
  				c = s === !1 && t,
  				p = a.isDelete ? a.actions(!1, !0, c, s, d) : "",
  				u = a.footer.replace(/\{actions}/g, p);
  			return u.replace(/\{caption}/g, n).replace(/\{width}/g, l).replace(/\{indicator}/g, "").replace(/\{indicatorTitle}/g, "")
  		}
  	}, s = function(e, i) {
  		return i = i || 0, "number" == typeof e ? e : ("string" == typeof e && (e = parseFloat(e)), isNaN(e) ? i : e)
  	}, d = function() {
  		return !(!window.File || !window.FileReader)
  	}, c = function() {
  		var e = document.createElement("div");
  		return !r(9) && !n() && (void 0 !== e.draggable || void 0 !== e.ondragstart && void 0 !== e.ondrop)
  	}, p = function() {
  		return d() && window.FormData
  	}, u = function(e, i) {
  		e.removeClass(i).addClass(i)
  	}, f = 'style="width:{width};height:{height};"', v = '      <param name="controller" value="true" />\n      <param name="allowFullScreen" value="true" />\n      <param name="allowScriptAccess" value="always" />\n      <param name="autoPlay" value="false" />\n      <param name="autoStart" value="false" />\n      <param name="quality" value="high" />\n', g = '<div class="file-preview-other">\n   <span class="{previewFileIconClass}">{previewFileIcon}</span>\n</div>', m = {
  		removeIcon: '<i class="glyphicon glyphicon-trash text-danger"></i>',
  		removeClass: "btn btn-xs btn-default",
  		removeTitle: "Remove file",
  		uploadIcon: '<i class="glyphicon glyphicon-upload text-info"></i>',
  		uploadClass: "btn btn-xs btn-default",
  		uploadTitle: "Upload file",
  		indicatorNew: '<i class="glyphicon glyphicon-hand-down text-warning"></i>',
  		indicatorSuccess: '<i class="glyphicon glyphicon-ok-sign text-success"></i>',
  		indicatorError: '<i class="glyphicon glyphicon-exclamation-sign text-danger"></i>',
  		indicatorLoading: '<i class="glyphicon glyphicon-hand-up text-muted"></i>',
  		indicatorNewTitle: "Not uploaded yet",
  		indicatorSuccessTitle: "Uploaded",
  		indicatorErrorTitle: "Upload Error",
  		indicatorLoadingTitle: "Uploading ..."
  	}, h = '{preview}\n<div class="kv-upload-progress hide"></div>\n<div class="input-group {class}">\n   {caption}\n   <div class="input-group-btn">\n       {remove}\n       {cancel}\n       {upload}\n       {browse}\n   </div>\n</div>', w = '{preview}\n<div class="kv-upload-progress hide"></div>\n{remove}\n{cancel}\n{upload}\n{browse}\n', _ = '<div class="file-preview {class}">\n    {close}    <div class="{dropClass}">\n    <div class="file-preview-thumbnails">\n    </div>\n    <div class="clearfix"></div>    <div class="file-preview-status text-center text-success"></div>\n    <div class="kv-fileinput-error"></div>\n    </div>\n</div>', C = '<div class="close fileinput-remove">&times;</div>\n', b = '<span class="glyphicon glyphicon-file kv-caption-icon"></span>', x = '<div tabindex="500" class="form-control file-caption {class}">\n   <div class="file-caption-name"></div>\n</div>\n', y = '<button type="{type}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</button>', T = '<a href="{href}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</a>', F = '<div tabindex="500" class="{css}" {status}>{icon}{label}</div>', E = '<div id="{id}" class="file-preview-detail-modal modal fade" tabindex="-1">\n  <div class="modal-dialog modal-lg">\n    <div class="modal-content">\n      <div class="modal-header">\n        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>\n        <h3 class="modal-title">{heading} <small>{title}</small></h3>\n      </div>\n      <div class="modal-body">\n           <pre>{body}</pre>\n      </div>\n    </div>\n  </div>\n</div>', I = '<div class="progress">\n    <div class="{class}" role="progressbar" aria-valuenow="{percent}" aria-valuemin="0" aria-valuemax="100" style="width:{percent}%;">\n        {percent}%\n     </div>\n</div>', $ = '<div class="file-thumbnail-footer">\n    <div class="file-footer-caption" title="{caption}">{caption}</div>\n    {progress} {actions}\n</div>', k = '<div class="file-actions">\n    <div class="file-footer-buttons">\n        {upload}{delete}{other}    </div>\n    <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n    <div class="clearfix"></div>\n</div>', P = '<button type="button" class="kv-file-remove {removeClass}" title="{removeTitle}" {dataUrl}{dataKey}>{removeIcon}</button>\n', S = '<button type="button" class="kv-file-upload {uploadClass}" title="{uploadTitle}">   {uploadIcon}\n</button>\n', D = '<button type="button" class="btn btn-default btn-xs btn-block" title="{zoomTitle}: {caption}" onclick="{dialog}">\n   {zoomInd}\n</button>\n', U = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n   {content}\n   {footer}\n</div>\n', A = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n    <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n       ' + g + "\n    </object>\n   {footer}\n</div>", j = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n   <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" ' + f + ">\n   {footer}\n</div>\n", L = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n   <pre class="file-preview-text" title="{caption}" ' + f + ">{data}</pre>\n   {zoom}\n   {footer}\n</div>", z = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" ' + f + '>\n   <video width="{width}" height="{height}" controls>\n       <source src="{data}" type="{type}">\n       ' + g + "\n   </video>\n   {footer}\n</div>\n", O = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" ' + f + '>\n   <audio controls>\n       <source src="{data}" type="{type}">\n       ' + g + "\n   </audio>\n   {footer}\n</div>", R = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" ' + f + '>\n   <object class="file-object" type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n' + v + "       " + g + "\n   </object>\n   {footer}\n</div>\n", N = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" ' + f + '>\n   <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n       <param name="movie" value="{caption}" />\n' + v + "         " + g + "\n   </object>\n   {footer}\n</div>", B = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" ' + f + '>\n   <div class="file-preview-other-frame">\n   ' + g + '\n   </div>\n   <div class="file-preview-other-footer">{footer}</div>\n</div>', M = {
  		main1: h,
  		main2: w,
  		preview: _,
  		close: C,
  		zoom: D,
  		icon: b,
  		caption: x,
  		modal: E,
  		progress: I,
  		footer: $,
  		actions: k,
  		actionDelete: P,
  		actionUpload: S,
  		btnDefault: y,
  		btnLink: T,
  		btnBrowse: F
  	}, Z = {
  		generic: U,
  		html: A,
  		image: j,
  		text: L,
  		video: z,
  		audio: O,
  		flash: R,
  		object: N,
  		other: B
  	}, H = ["image", "html", "text", "video", "audio", "flash", "object"], W = {
  		image: {
  			width: "auto",
  			height: "160px"
  		},
  		html: {
  			width: "213px",
  			height: "160px"
  		},
  		text: {
  			width: "160px",
  			height: "136px"
  		},
  		video: {
  			width: "213px",
  			height: "160px"
  		},
  		audio: {
  			width: "213px",
  			height: "80px"
  		},
  		flash: {
  			width: "213px",
  			height: "160px"
  		},
  		object: {
  			width: "160px",
  			height: "160px"
  		},
  		other: {
  			width: "160px",
  			height: "160px"
  		}
  	}, V = {
  		image: function(e, i) {
  			return a(e, "image.*") || a(i, /\.(gif|png|jpe?g)$/i)
  		},
  		html: function(e, i) {
  			return a(e, "text/html") || a(i, /\.(htm|html)$/i)
  		},
  		text: function(e, i) {
  			return a(e, "text.*") || a(e, /\.(xml|javascript)$/i) || a(i, /\.(txt|md|csv|nfo|ini|json|php|js|css)$/i)
  		},
  		video: function(e, i) {
  			return a(e, "video.*") && (a(e, /(ogg|mp4|mp?g|webm|3gp)$/i) || a(i, /\.(og?|mp4|webm|mp?g|3gp)$/i))
  		},
  		audio: function(e, i) {
  			return a(e, "audio.*") && (a(e, /(ogg|mp3|mp?g|wav)$/i) || a(i, /\.(og?|mp3|mp?g|wav)$/i))
  		},
  		flash: function(e, i) {
  			return a(e, "application/x-shockwave-flash", !0) || a(i, /\.(swf)$/i)
  		},
  		object: function(e, i) {
  			return a(e, "application/pdf", !0) || a(i, /\.(pdf)$/i)
  		},
  		other: function() {
  			return !0
  		}
  	}, K = function(i, t) {
  		return void 0 === i || null === i || 0 === i.length || t && "" === e.trim(i)
  	}, X = function(e) {
  		return Array.isArray(e) || "[object Array]" === Object.prototype.toString.call(e)
  	}, J = function(e, i) {
  		return "object" == typeof i && e in i
  	}, Q = function(i, t, a) {
  		return K(i) || K(i[t]) ? a : e(i[t])
  	}, Y = function() {
  		return Math.round((new Date).getTime() + 100 * Math.random())
  	}, G = function(e) {
  		return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;")
  	}, ee = function(i, t) {
  		var a = i;
  		return t ? (e.each(t, function(e, i) {
  			"function" == typeof i && (i = i()), a = a.split(e).join(i)
  		}), a) : a
  	}, ie = function(e) {
  		var i = e.is("img") ? e.attr("src") : e.find("source").attr("src");
  		t.revokeObjectURL(i)
  	}, q = function(i, t) {
  		var a = this;
  		a.$element = e(i), a._validate() && (a.isPreviewable = d(), a.isIE9 = r(9), a.isIE10 = r(10), a.isPreviewable || a.isIE9 ? (a._init(t), a._listen()) : a.$element.removeClass("file-loading"))
  	}, q.prototype = {
  		constructor: q,
  		_init: function(i) {
  			var t, a = this,
  				r = a.$element;
  			e.each(i, function(e, i) {
  				switch (e) {
  					case "minFileCount":
  					case "maxFileCount":
  					case "maxFileSize":
  						a[e] = s(i);
  						break;
  					default:
  						a[e] = i
  				}
  			}), a.fileInputCleared = !1, a.fileBatchCompleted = !0, a.isPreviewable || (a.showPreview = !1), a.uploadFileAttr = K(r.attr("name")) ? "file_data" : r.attr("name"), a.reader = null, a.formdata = {}, a.clearStack(), a.uploadCount = 0, a.uploadStatus = {}, a.uploadLog = [], a.uploadAsyncCount = 0, a.loadedImages = [], a.totalImagesCount = 0, a.ajaxRequests = [], a.isError = !1, a.ajaxAborted = !1, a.cancelling = !1, t = a._getLayoutTemplate("progress"), a.progressTemplate = t.replace("{class}", a.progressClass), a.progressCompleteTemplate = t.replace("{class}", a.progressCompleteClass), a.progressErrorTemplate = t.replace("{class}", a.progressErrorClass), a.dropZoneEnabled = c() && a.dropZoneEnabled, a.isDisabled = a.$element.attr("disabled") || a.$element.attr("readonly"), a.isUploadable = p() && !K(a.uploadUrl), a.slug = "function" == typeof i.slugCallback ? i.slugCallback : a._slugDefault, a.mainTemplate = a.showCaption ? a._getLayoutTemplate("main1") : a._getLayoutTemplate("main2"), a.captionTemplate = a._getLayoutTemplate("caption"), a.previewGenericTemplate = a._getPreviewTemplate("generic"), a.resizeImage && (a.maxImageWidth || a.maxImageHeight) && (a.imageCanvas = document.createElement("canvas"), a.imageCanvasContext = a.imageCanvas.getContext("2d")), K(a.$element.attr("id")) && a.$element.attr("id", Y()), void 0 === a.$container ? a.$container = a._createContainer() : a._refreshContainer(), a.$dropZone = a.$container.find(".file-drop-zone"), a.$progress = a.$container.find(".kv-upload-progress"), a.$btnUpload = a.$container.find(".fileinput-upload"), a.$captionContainer = Q(i, "elCaptionContainer", a.$container.find(".file-caption")), a.$caption = Q(i, "elCaptionText", a.$container.find(".file-caption-name")), a.$previewContainer = Q(i, "elPreviewContainer", a.$container.find(".file-preview")), a.$preview = Q(i, "elPreviewImage", a.$container.find(".file-preview-thumbnails")), a.$previewStatus = Q(i, "elPreviewStatus", a.$container.find(".file-preview-status")), a.$errorContainer = Q(i, "elErrorContainer", a.$previewContainer.find(".kv-fileinput-error")), K(a.msgErrorClass) || u(a.$errorContainer, a.msgErrorClass), a.$errorContainer.hide(), a.fileActionSettings = e.extend(!0, m, i.fileActionSettings), a.previewInitId = "preview-" + Y(), a.id = a.$element.attr("id"), o.init(a), a._initPreview(!0), a._initPreviewDeletes(), a.options = i, a._setFileDropZoneTitle(), a.$element.removeClass("file-loading"), a.$element.attr("disabled") && a.disable()
  		},
  		_validate: function() {
  			var e, i = this;
  			return "file" === i.$element.attr("type") ? !0 : (e = '<div class="help-block alert alert-warning"><h4>Invalid Input Type</h4>You must set an input <code>type = file</code> for <b>bootstrap-fileinput</b> plugin to initialize.</div>', i.$element.after(e), !1)
  		},
  		_errorsExist: function() {
  			var i, t = this;
  			return t.$errorContainer.find("li").length ? !0 : (i = e(document.createElement("div")).html(t.$errorContainer.html()), i.find("span.kv-error-close").remove(), i.find("ul").remove(), e.trim(i.text()).length ? !0 : !1)
  		},
  		_errorHandler: function(e, i) {
  			var t = this,
  				a = e.target.error;
  			a.code === a.NOT_FOUND_ERR ? t._showError(t.msgFileNotFound.replace("{name}", i)) : a.code === a.SECURITY_ERR ? t._showError(t.msgFileSecured.replace("{name}", i)) : a.code === a.NOT_READABLE_ERR ? t._showError(t.msgFileNotReadable.replace("{name}", i)) : a.code === a.ABORT_ERR ? t._showError(t.msgFilePreviewAborted.replace("{name}", i)) : t._showError(t.msgFilePreviewError.replace("{name}", i))
  		},
  		_addError: function(e) {
  			var i = this,
  				t = i.$errorContainer;
  			e && t.length && (t.html(i.errorCloseButton + e), l(t.find(".kv-error-close"), "click", function() {
  				t.fadeOut("slow")
  			}))
  		},
  		_resetErrors: function(e) {
  			var i = this,
  				t = i.$errorContainer;
  			i.isError = !1, i.$container.removeClass("has-error"), t.html(""), e ? t.fadeOut("slow") : t.hide()
  		},
  		_showFolderError: function(e) {
  			var i, t = this,
  				a = t.$errorContainer;
  			e && (i = t.msgFoldersNotAllowed.replace(/\{n}/g, e), t._addError(i), u(t.$container, "has-error"), a.fadeIn(800), t._raise("filefoldererror", [e, i]))
  		},
  		_showUploadError: function(e, i, t) {
  			var a = this,
  				r = a.$errorContainer,
  				n = t || "fileuploaderror",
  				l = i && i.id ? '<li data-file-id="' + i.id + '">' + e + "</li>" : "<li>" + e + "</li>";
  			return 0 === r.find("ul").length ? a._addError("<ul>" + l + "</ul>") : r.find("ul").append(l), r.fadeIn(800), a._raise(n, [i, e]), a.$container.removeClass("file-input-new"), u(a.$container, "has-error"), !0
  		},
  		_showError: function(e, i, t) {
  			var a = this,
  				r = a.$errorContainer,
  				n = t || "fileerror";
  			return i = i || {}, i.reader = a.reader, a._addError(e), r.fadeIn(800), a._raise(n, [i, e]), a.isUploadable || a._clearFileInput(), a.$container.removeClass("file-input-new"), u(a.$container, "has-error"), a.$btnUpload.attr("disabled", !0), !0
  		},
  		_noFilesError: function(e) {
  			var i = this,
  				t = i.minFileCount > 1 ? i.filePlural : i.fileSingle,
  				a = i.msgFilesTooLess.replace("{n}", i.minFileCount).replace("{files}", t),
  				r = i.$errorContainer;
  			i._addError(a), i.isError = !0, i._updateFileDetails(0), r.fadeIn(800), i._raise("fileerror", [e, a]), i._clearFileInput(), u(i.$container, "has-error")
  		},
  		_parseError: function(i, t, a) {
  			var r = this,
  				n = e.trim(t + ""),
  				l = "." === n.slice(-1) ? "" : ".",
  				o = void 0 !== i.responseJSON && void 0 !== i.responseJSON.error ? i.responseJSON.error : i.responseText;
  			return r.cancelling && r.msgUploadAborted && (n = r.msgUploadAborted), r.showAjaxErrorDetails && o ? (o = e.trim(o.replace(/\n\s*\n/g, "\n")), o = o.length > 0 ? "<pre>" + o + "</pre>" : "", n += l + o) : n += l, r.cancelling = !1, a ? "<b>" + a + ": </b>" + n : n
  		},
  		_parseFileType: function(e) {
  			var i, t, a, r, n = this;
  			for (r = 0; r < H.length; r += 1)
  				if (a = H[r], i = J(a, n.fileTypeSettings) ? n.fileTypeSettings[a] : V[a], t = i(e.type, e.name) ? a : "", !K(t)) return t;
  			return "other"
  		},
  		_parseFilePreviewIcon: function(i, t) {
  			var a, r = this,
  				n = r.previewFileIcon;
  			return t && t.indexOf(".") > -1 && (a = t.split(".").pop(), r.previewFileIconSettings && r.previewFileIconSettings[a] && (n = r.previewFileIconSettings[a]), r.previewFileExtSettings && e.each(r.previewFileExtSettings, function(e, i) {
  				r.previewFileIconSettings[e] && i(a) && (n = r.previewFileIconSettings[e])
  			})), i.indexOf("{previewFileIcon}") > -1 ? i.replace(/\{previewFileIconClass}/g, r.previewFileIconClass).replace(/\{previewFileIcon}/g, n) : i
  		},
  		_raise: function(i, t) {
  			var a = this,
  				r = e.Event(i);
  			if (void 0 !== t ? a.$element.trigger(r, t) : a.$element.trigger(r), r.isDefaultPrevented()) return !1;
  			if (!r.result) return r.result;
  			switch (i) {
  				case "filebatchuploadcomplete":
  				case "filebatchuploadsuccess":
  				case "fileuploaded":
  				case "fileclear":
  				case "filecleared":
  				case "filereset":
  				case "fileerror":
  				case "filefoldererror":
  				case "fileuploaderror":
  				case "filebatchuploaderror":
  				case "filedeleteerror":
  				case "filecustomerror":
  				case "filesuccessremove":
  					break;
  				default:
  					a.ajaxAborted = r.result
  			}
  			return !0
  		},
  		_listen: function() {
  			var i = this,
  				t = i.$element,
  				a = t.closest("form"),
  				r = i.$container;
  			l(t, "change", e.proxy(i._change, i)), l(i.$btnFile, "click", e.proxy(i._browse, i)), l(a, "reset", e.proxy(i.reset, i)), l(r.find(".fileinput-remove:not([disabled])"), "click", e.proxy(i.clear, i)), l(r.find(".fileinput-cancel"), "click", e.proxy(i.cancel, i)), i._initDragDrop(), i.isUploadable || l(a, "submit", e.proxy(i._submitForm, i)), l(i.$container.find(".fileinput-upload"), "click", e.proxy(i._uploadClick, i))
  		},
  		_initDragDrop: function() {
  			var i = this,
  				t = i.$dropZone;
  			i.isUploadable && i.dropZoneEnabled && i.showPreview && (l(t, "dragenter dragover", e.proxy(i._zoneDragEnter, i)), l(t, "dragleave", e.proxy(i._zoneDragLeave, i)), l(t, "drop", e.proxy(i._zoneDrop, i)), l(e(document), "dragenter dragover drop", i._zoneDragDropInit))
  		},
  		_zoneDragDropInit: function(e) {
  			e.stopPropagation(), e.preventDefault()
  		},
  		_zoneDragEnter: function(i) {
  			var t = this,
  				a = e.inArray("Files", i.originalEvent.dataTransfer.types) > -1;
  			return t._zoneDragDropInit(i), t.isDisabled || !a ? (i.originalEvent.dataTransfer.effectAllowed = "none", void(i.originalEvent.dataTransfer.dropEffect = "none")) : void u(t.$dropZone, "file-highlighted")
  		},
  		_zoneDragLeave: function(e) {
  			var i = this;
  			i._zoneDragDropInit(e), i.isDisabled || i.$dropZone.removeClass("file-highlighted")
  		},
  		_zoneDrop: function(e) {
  			var i = this;
  			e.preventDefault(), i.isDisabled || K(e.originalEvent.dataTransfer.files) || (i._change(e, "dragdrop"), i.$dropZone.removeClass("file-highlighted"))
  		},
  		_uploadClick: function(e) {
  			var i, t = this,
  				a = t.$container.find(".fileinput-upload"),
  				r = !a.hasClass("disabled") && K(a.attr("disabled"));
  			if (!e || !e.isDefaultPrevented()) {
  				if (!t.isUploadable) return void(r && "submit" !== a.attr("type") && (i = a.closest("form"), i.length && i.trigger("submit"), e.preventDefault()));
  				e.preventDefault(), r && t.upload()
  			}
  		},
  		_submitForm: function() {
  			var e = this,
  				i = e.$element,
  				t = i.get(0).files;
  			return t && e.minFileCount > 0 && e._getFileCount(t.length) < e.minFileCount ? (e._noFilesError({}), !1) : !e._abort({})
  		},
  		_clearPreview: function() {
  			var e = this,
  				i = e.showUploadedThumbs ? e.$preview.find(".file-preview-frame:not(.file-preview-success)") : e.$preview.find(".file-preview-frame");
  			i.remove(), e.$preview.find(".file-preview-frame").length && e.showPreview || e._resetUpload(), e._validateDefaultPreview()
  		},
  		_initPreview: function(e) {
  			var i, t = this,
  				a = t.initialCaption || "";
  			return o.count(t.id) ? (i = o.out(t.id), a = e && t.initialCaption ? t.initialCaption : i.caption, t.$preview.html(i.content), t._setCaption(a), void(K(i.content) || t.$container.removeClass("file-input-new"))) : (t._clearPreview(), void(e ? t._setCaption(a) : t._initCaption()))
  		},
  		_initPreviewDeletes: function() {
  			var i = this,
  				t = i.deleteExtraData || {},
  				a = function() {
  					var e = i.isUploadable ? o.count(i.id) : i.$element.get(0).files.length;
  					0 !== i.$preview.find(".kv-file-remove").length || e || (i.reset(), i.initialCaption = "")
  				};
  			i.$preview.find(".kv-file-remove").each(function() {
  				var r = e(this),
  					n = r.data("url") || i.deleteUrl,
  					s = r.data("key");
  				if (!K(n) && void 0 !== s) {
  					var d, c, p, f, v = r.closest(".file-preview-frame"),
  						g = o.data[i.id],
  						m = v.data("fileindex");
  					m = parseInt(m.replace("init_", "")), p = K(g.config) && K(g.config[m]) ? null : g.config[m], f = K(p) || K(p.extra) ? t : p.extra, "function" == typeof f && (f = f()), c = {
  						id: r.attr("id"),
  						key: s,
  						extra: f
  					}, d = e.extend(!0, {}, {
  						url: n,
  						type: "POST",
  						dataType: "json",
  						data: e.extend(!0, {}, {
  							key: s
  						}, f),
  						beforeSend: function(e) {
  							i.ajaxAborted = !1, i._raise("filepredelete", [s, e, f]), i.ajaxAborted ? e.abort() : (u(v, "file-uploading"), u(r, "disabled"))
  						},
  						success: function(e, t, n) {
  							var l, d;
  							return K(e) || K(e.error) ? (o.unset(i.id, m), l = o.count(i.id), d = l > 0 ? i._getMsgSelected(l) : "", i._raise("filedeleted", [s, n, f]), i._setCaption(d), v.removeClass("file-uploading").addClass("file-deleted"), void v.fadeOut("slow", function() {
  								i._clearObjects(v), v.remove(), a(), l || 0 !== i.getFileStack().length || (i._setCaption(""), i.reset())
  							})) : (c.jqXHR = n, c.response = e, i._showError(e.error, c, "filedeleteerror"), v.removeClass("file-uploading"), r.removeClass("disabled"), void a())
  						},
  						error: function(e, t, r) {
  							var n = i._parseError(e, r);
  							c.jqXHR = e, c.response = {}, i._showError(n, c, "filedeleteerror"), v.removeClass("file-uploading"), a()
  						}
  					}, i.ajaxDeleteSettings), l(r, "click", function() {
  						return i._validateMinCount() ? void e.ajax(d) : !1
  					})
  				}
  			})
  		},
  		_clearObjects: function(i) {
  			i.find("video audio").each(function() {
  				this.pause(), e(this).remove()
  			}), i.find("img object div").each(function() {
  				e(this).remove()
  			})
  		},
  		_clearFileInput: function() {
  			var i, t, a, r = this,
  				n = r.$element;
  			K(n.val()) || (r.isIE9 || r.isIE10 ? (i = n.closest("form"), t = e(document.createElement("form")), a = e(document.createElement("div")), n.before(a), i.length ? i.after(t) : a.after(t), t.append(n).trigger("reset"), a.before(n).remove(), t.remove()) : n.val(""), r.fileInputCleared = !0)
  		},
  		_resetUpload: function() {
  			var e = this;
  			e.uploadCache = {
  				content: [],
  				config: [],
  				tags: [],
  				append: !0
  			}, e.uploadCount = 0, e.uploadStatus = {}, e.uploadLog = [], e.uploadAsyncCount = 0, e.loadedImages = [], e.totalImagesCount = 0, e.$btnUpload.removeAttr("disabled"), e._setProgress(0), u(e.$progress, "hide"), e._resetErrors(!1), e.ajaxAborted = !1, e.ajaxRequests = [], e._resetCanvas()
  		},
  		_resetCanvas: function() {
  			var e = this;
  			e.canvas && e.imageCanvasContext && e.imageCanvasContext.clearRect(0, 0, e.canvas.width, e.canvas.height)
  		},
  		_hasInitialPreview: function() {
  			var e = this;
  			return !e.overwriteInitial && o.count(e.id)
  		},
  		_resetPreview: function() {
  			var e, i, t = this;
  			o.count(t.id) ? (e = o.out(t.id), t.$preview.html(e.content), i = t.initialCaption ? t.initialCaption : e.caption, t._setCaption(i)) : (t._clearPreview(), t._initCaption())
  		},
  		_clearDefaultPreview: function() {
  			var e = this;
  			e.$preview.find(".file-default-preview").remove()
  		},
  		_validateDefaultPreview: function() {
  			var e = this;
  			e.showPreview && !K(e.defaultPreviewContent) && (e.$preview.html('<div class="file-default-preview">' + e.defaultPreviewContent + "</div>"), e.$container.removeClass("file-input-new"))
  		},
  		_resetPreviewThumbs: function(e) {
  			var i, t = this;
  			return e ? (t._clearPreview(), void t.clearStack()) : void(t._hasInitialPreview() ? (i = o.out(t.id), t.$preview.html(i.content), t._setCaption(i.caption), t._initPreviewDeletes()) : t._clearPreview())
  		},
  		_getLayoutTemplate: function(e) {
  			var i = this,
  				t = J(e, i.layoutTemplates) ? i.layoutTemplates[e] : M[e];
  			return K(i.customLayoutTags) ? t : ee(t, i.customLayoutTags)
  		},
  		_getPreviewTemplate: function(e) {
  			var i = this,
  				t = J(e, i.previewTemplates) ? i.previewTemplates[e] : Z[e];
  			return K(i.customPreviewTags) ? t : ee(t, i.customPreviewTags)
  		},
  		_getOutData: function(e, i, t) {
  			var a = this;
  			return e = e || {}, i = i || {}, t = t || a.filestack.slice(0) || {}, {
  				form: a.formdata,
  				files: t,
  				filenames: a.filenames,
  				extra: a._getExtraData(),
  				response: i,
  				reader: a.reader,
  				jqXHR: e
  			}
  		},
  		_getMsgSelected: function(e) {
  			var i = this,
  				t = 1 === e ? i.fileSingle : i.filePlural;
  			return i.msgSelected.replace("{n}", e).replace("{files}", t)
  		},
  		_getThumbs: function(e) {
  			return e = e || "", this.$preview.find(".file-preview-frame:not(.file-preview-initial)" + e)
  		},
  		_getExtraData: function(e, i) {
  			var t = this,
  				a = t.uploadExtraData;
  			return "function" == typeof t.uploadExtraData && (a = t.uploadExtraData(e, i)), a
  		},
  		_initXhr: function(e, i, t) {
  			var a = this;
  			return e.upload && e.upload.addEventListener("progress", function(e) {
  				var r = 0,
  					n = e.loaded || e.position,
  					l = e.total;
  				e.lengthComputable && (r = Math.ceil(n / l * 100)), i ? a._setAsyncUploadStatus(i, r, t) : a._setProgress(Math.ceil(r))
  			}, !1), e
  		},
  		_ajaxSubmit: function(i, t, a, r, n, l) {
  			var o, s = this;
  			s._raise("filepreajax", [n, l]), s._uploadExtra(n, l), o = e.extend(!0, {}, {
  				xhr: function() {
  					var i = e.ajaxSettings.xhr();
  					return s._initXhr(i, n, s.getFileStack().length)
  				},
  				url: s.uploadUrl,
  				type: "POST",
  				dataType: "json",
  				data: s.formdata,
  				cache: !1,
  				processData: !1,
  				contentType: !1,
  				beforeSend: i,
  				success: t,
  				complete: a,
  				error: r
  			}, s.ajaxSettings), s.ajaxRequests.push(e.ajax(o))
  		},
  		_initUploadSuccess: function(i, t, a) {
  			var r, n, l, s, d, c, p, u, f = this;
  			f.showPreview && "object" == typeof i && !e.isEmptyObject(i) && void 0 !== i.initialPreview && i.initialPreview.length > 0 && (f.hasInitData = !0, d = i.initialPreview || [], c = i.initialPreviewConfig || [], p = i.initialPreviewThumbTags || [], r = void 0 === i.append || i.append ? !0 : !1, f.overwriteInitial = !1, void 0 !== t ? a ? (u = t.attr("data-fileindex"), f.uploadCache.content[u] = d[0], f.uploadCache.config[u] = c[0], f.uploadCache.tags[u] = p[0], f.uploadCache.append = r) : (l = o.add(f.id, d, c[0], p[0], r), n = o.get(f.id, l, !1), s = e(n).hide(), t.after(s).fadeOut("slow", function() {
  				s.fadeIn("slow").css("display:inline-block"), f._initPreviewDeletes(), f._clearFileInput(), t.remove()
  			})) : (o.set(f.id, d, c, p, r), f._initPreview(), f._initPreviewDeletes()))
  		},
  		_initSuccessThumbs: function() {
  			var i = this;
  			i.showPreview && i._getThumbs(".file-preview-success").each(function() {
  				var t = e(this),
  					a = t.find(".kv-file-remove");
  				a.removeAttr("disabled"), l(a, "click", function() {
  					var e = i._raise("filesuccessremove", [t.attr("id"), t.data("fileindex")]);
  					ie(t), e !== !1 && t.fadeOut("slow", function() {
  						t.remove(), i.$preview.find(".file-preview-frame").length || i.reset()
  					})
  				})
  			})
  		},
  		_checkAsyncComplete: function() {
  			var i, t, a = this;
  			for (t = 0; t < a.filestack.length; t++)
  				if (a.filestack[t] && (i = a.previewInitId + "-" + t, -1 === e.inArray(i, a.uploadLog))) return !1;
  			return a.uploadAsyncCount === a.uploadLog.length
  		},
  		_uploadExtra: function(i, t) {
  			var a = this,
  				r = a._getExtraData(i, t);
  			0 !== r.length && e.each(r, function(e, i) {
  				a.formdata.append(e, i)
  			})
  		},
  		_uploadSingle: function(i, t, a) {
  			var r, n, l, s, d, c, p, f, v, g, m = this,
  				h = m.getFileStack().length,
  				w = new FormData,
  				_ = m.previewInitId + "-" + i,
  				b = m.filestack.length > 0 || !e.isEmptyObject(m.uploadExtraData),
  				C = {
  					id: _,
  					index: i
  				};
  			m.formdata = w, m.showPreview && (n = e("#" + _ + ":not(.file-preview-initial)"), s = n.find(".kv-file-upload"), d = n.find(".kv-file-remove"), e("#" + _).find(".file-thumb-progress").removeClass("hide")), 0 === h || !b || s && s.hasClass("disabled") || m._abort(C) || (g = function(e, i) {
  				m.updateStack(e, void 0), m.uploadLog.push(i), m._checkAsyncComplete() && (m.fileBatchCompleted = !0)
  			}, l = function() {
  				m.fileBatchCompleted && setTimeout(function() {
  					m.showPreview && (o.set(m.id, m.uploadCache.content, m.uploadCache.config, m.uploadCache.tags, m.uploadCache.append), m.hasInitData && (m._initPreview(), m._initPreviewDeletes())), m.unlock(), m._clearFileInput(), m._raise("filebatchuploadcomplete", [m.filestack, m._getExtraData()]), m.uploadCount = 0, m.uploadStatus = {}, m.uploadLog = [], m._setProgress(100)
  				}, 100)
  			}, c = function(t) {
  				r = m._getOutData(t), m.fileBatchCompleted = !1, m.showPreview && (n.hasClass("file-preview-success") || (m._setThumbStatus(n, "Loading"), u(n, "file-uploading")), s.attr("disabled", !0), d.attr("disabled", !0)), a || m.lock(), m._raise("filepreupload", [r, _, i]), e.extend(!0, C, r), m._abort(C) && (t.abort(), m._setProgressCancelled())
  			}, p = function(t, l, o) {
  				r = m._getOutData(o, t), e.extend(!0, C, r), setTimeout(function() {
  					K(t) || K(t.error) ? (m.showPreview && (m._setThumbStatus(n, "Success"), s.hide(), m._initUploadSuccess(t, n, a)), m._raise("fileuploaded", [r, _, i]), a ? g(i, _) : m.updateStack(i, void 0)) : (m._showUploadError(t.error, C), m._setPreviewError(n, i), a && g(i, _))
  				}, 100)
  			}, f = function() {
  				setTimeout(function() {
  					m.showPreview && (s.removeAttr("disabled"), d.removeAttr("disabled"), n.removeClass("file-uploading")), a ? l() : (m.unlock(!1), m._clearFileInput()), m._initSuccessThumbs()
  				}, 100)
  			}, v = function(r, l, o) {
  				var s = m._parseError(r, o, a ? t[i].name : null);
  				setTimeout(function() {
  					a && g(i, _), m.uploadStatus[_] = 100, m._setPreviewError(n, i), e.extend(!0, C, m._getOutData(r)), m._showUploadError(s, C)
  				}, 100)
  			}, w.append(m.uploadFileAttr, t[i], m.filenames[i]), w.append("file_id", i), m._ajaxSubmit(c, p, f, v, _, i))
  		},
  		_uploadBatch: function() {
  			var i, t, a, r, n, l = this,
  				o = l.filestack,
  				s = o.length,
  				d = {},
  				c = l.filestack.length > 0 || !e.isEmptyObject(l.uploadExtraData);
  			l.formdata = new FormData, 0 !== s && c && !l._abort(d) && (n = function() {
  				e.each(o, function(e) {
  					l.updateStack(e, void 0)
  				}), l._clearFileInput()
  			}, i = function(i) {
  				l.lock();
  				var t = l._getOutData(i);
  				l.showPreview && l._getThumbs().each(function() {
  					var i = e(this),
  						t = i.find(".kv-file-upload"),
  						a = i.find(".kv-file-remove");
  					i.hasClass("file-preview-success") || (l._setThumbStatus(i, "Loading"), u(i, "file-uploading")), t.attr("disabled", !0), a.attr("disabled", !0)
  				}), l._raise("filebatchpreupload", [t]), l._abort(t) && (i.abort(), l._setProgressCancelled())
  			}, t = function(i, t, a) {
  				var r = l._getOutData(a, i),
  					o = l._getThumbs(),
  					s = 0,
  					d = K(i) || K(i.errorkeys) ? [] : i.errorkeys;
  				K(i) || K(i.error) ? (l._raise("filebatchuploadsuccess", [r]), n(), l.showPreview ? (o.each(function() {
  					var i = e(this),
  						t = i.find(".kv-file-upload");
  					i.find(".kv-file-upload").hide(), l._setThumbStatus(i, "Success"), i.removeClass("file-uploading"), t.removeAttr("disabled")
  				}), l._initUploadSuccess(i)) : l.reset()) : (l.showPreview && (o.each(function() {
  					var i = e(this),
  						t = i.find(".kv-file-remove"),
  						a = i.find(".kv-file-upload");
  					return i.removeClass("file-uploading"), a.removeAttr("disabled"), t.removeAttr("disabled"), 0 === d.length ? void l._setPreviewError(i) : (-1 !== e.inArray(s, d) ? l._setPreviewError(i) : (i.find(".kv-file-upload").hide(), l._setThumbStatus(i, "Success"), l.updateStack(s, void 0)), void s++)
  				}), l._initUploadSuccess(i)), l._showUploadError(i.error, r, "filebatchuploaderror"))
  			}, r = function() {
  				l._setProgress(100), l.unlock(), l._initSuccessThumbs(), l._clearFileInput(), l._raise("filebatchuploadcomplete", [l.filestack, l._getExtraData()])
  			}, a = function(i, t, a) {
  				var r = l._getOutData(i),
  					n = l._parseError(i, a);
  				l._showUploadError(n, r, "filebatchuploaderror"), l.uploadFileCount = s - 1, l.showPreview && (l._getThumbs().each(function() {
  					var i = e(this),
  						t = i.attr("data-fileindex");
  					i.removeClass("file-uploading"), void 0 !== l.filestack[t] && l._setPreviewError(i)
  				}), l._getThumbs().removeClass("file-uploading"), l._getThumbs(" .kv-file-upload").removeAttr("disabled"), l._getThumbs(" .kv-file-delete").removeAttr("disabled"))
  			}, e.each(o, function(e, i) {
  				K(o[e]) || l.formdata.append(l.uploadFileAttr, i, l.filenames[e])
  			}), l._ajaxSubmit(i, t, r, a))
  		},
  		_uploadExtraOnly: function() {
  			var e, i, t, a, r = this,
  				n = {};
  			r.formdata = new FormData, r._abort(n) || (e = function(e) {
  				r.lock();
  				var i = r._getOutData(e);
  				r._raise("filebatchpreupload", [i]),
  					r._setProgress(50), n.data = i, n.xhr = e, r._abort(n) && (e.abort(), r._setProgressCancelled())
  			}, i = function(e, i, t) {
  				var a = r._getOutData(t, e);
  				K(e) || K(e.error) ? (r._raise("filebatchuploadsuccess", [a]), r._clearFileInput(), r._initUploadSuccess(e)) : r._showUploadError(e.error, a, "filebatchuploaderror")
  			}, t = function() {
  				r._setProgress(100), r.unlock(), r._clearFileInput(), r._raise("filebatchuploadcomplete", [r.filestack, r._getExtraData()])
  			}, a = function(e, i, t) {
  				var a = r._getOutData(e),
  					l = r._parseError(e, t);
  				n.data = a, r._showUploadError(l, a, "filebatchuploaderror")
  			}, r._ajaxSubmit(e, i, t, a))
  		},
  		_initFileActions: function() {
  			var i = this;
  			i.showPreview && (i.$preview.find(".kv-file-remove").each(function() {
  				var t, a, r, n, s = e(this),
  					d = s.closest(".file-preview-frame"),
  					c = d.attr("id"),
  					p = d.attr("data-fileindex");
  				l(s, "click", function() {
  					return n = i._raise("filepreremove", [c, p]), n !== !1 && i._validateMinCount() ? (t = d.hasClass("file-preview-error"), ie(d), void d.fadeOut("slow", function() {
  						i.updateStack(p, void 0), i._clearObjects(d), d.remove(), c && t && i.$errorContainer.find('li[data-file-id="' + c + '"]').fadeOut("fast", function() {
  							e(this).remove(), i._errorsExist() || i._resetErrors()
  						});
  						var n = i.getFileStack(!0),
  							l = n.length,
  							s = o.count(i.id),
  							u = i.showPreview && i.$preview.find(".file-preview-frame").length;
  						i._clearFileInput(), 0 !== l || 0 !== s || u ? (a = s + l, r = a > 1 ? i._getMsgSelected(a) : n[0] ? i._getFileNames()[0] : "", i._setCaption(r)) : i.reset(), i._raise("fileremoved", [c, p])
  					})) : !1
  				})
  			}), i.$preview.find(".kv-file-upload").each(function() {
  				var t = e(this);
  				l(t, "click", function() {
  					var e = t.closest(".file-preview-frame"),
  						a = e.attr("data-fileindex");
  					e.hasClass("file-preview-error") || i._uploadSingle(a, i.filestack, !1)
  				})
  			}))
  		},
  		_hideFileIcon: function() {
  			this.overwriteInitial && this.$captionContainer.find(".kv-caption-icon").hide()
  		},
  		_showFileIcon: function() {
  			this.$captionContainer.find(".kv-caption-icon").show()
  		},
  		_previewDefault: function(i, a, r) {
  			if (this.showPreview) {
  				var n = this,
  					l = "",
  					o = i ? i.name : "",
  					s = t.createObjectURL(i),
  					d = a.slice(a.lastIndexOf("-") + 1),
  					c = n.previewSettings.other || W.other,
  					p = n._renderFileFooter(i.name, c.width),
  					u = n._parseFilePreviewIcon(n._getPreviewTemplate("other"), o);
  				r === !0 && (n.isUploadable || (p += '<div class="file-other-error" title="' + n.fileActionSettings.indicatorErrorTitle + '">' + n.fileActionSettings.indicatorError + "</div>")), n._clearDefaultPreview(), n.$preview.append("\n" + u.replace(/\{previewId}/g, a).replace(/\{frameClass}/g, l).replace(/\{fileindex}/g, d).replace(/\{caption}/g, n.slug(i.name)).replace(/\{width}/g, c.width).replace(/\{height}/g, c.height).replace(/\{type}/g, i.type).replace(/\{data}/g, s).replace(/\{footer}/g, p)), r === !0 && n.isUploadable && n._setThumbStatus(e("#" + a), "Error")
  			}
  		},
  		_previewFile: function(e, i, t, a, r) {
  			if (this.showPreview) {
  				var n, l, o, s = this,
  					d = s._parseFileType(i),
  					c = i ? i.name : "",
  					p = s.slug(c),
  					u = s.allowedPreviewTypes,
  					f = s.allowedPreviewMimeTypes,
  					v = s._getPreviewTemplate(d),
  					g = u && u.indexOf(d) >= 0,
  					m = J(d, s.previewSettings) ? s.previewSettings[d] : W[d],
  					h = f && -1 !== f.indexOf(i.type),
  					w = s._renderFileFooter(p, m.width),
  					_ = "",
  					b = a.slice(a.lastIndexOf("-") + 1);
  				g || h ? (v = s._parseFilePreviewIcon(v, c.split(".").pop()), "text" === d ? (l = G(t.target.result), o = "text-" + Y(), n = v.replace(/\{zoom}/g, s._getLayoutTemplate("zoom")), _ = s._getLayoutTemplate("modal").replace("{id}", o).replace(/\{title}/g, p).replace(/\{body}/g, l).replace(/\{heading}/g, s.msgZoomModalHeading), n = n.replace(/\{previewId}/g, a).replace(/\{caption}/g, p).replace(/\{width}/g, m.width).replace(/\{height}/g, m.height).replace(/\{frameClass}/g, "").replace(/\{zoomInd}/g, s.zoomIndicator).replace(/\{footer}/g, w).replace(/\{fileindex}/g, b).replace(/\{type}/g, i.type).replace(/\{zoomTitle}/g, s.msgZoomTitle).replace(/\{dialog}/g, "$('#" + o + "').modal('show')").replace(/\{data}/g, l) + _) : n = v.replace(/\{previewId}/g, a).replace(/\{caption}/g, p).replace(/\{frameClass}/g, "").replace(/\{type}/g, i.type).replace(/\{fileindex}/g, b).replace(/\{width}/g, m.width).replace(/\{height}/g, m.height).replace(/\{footer}/g, w).replace(/\{data}/g, r), s._clearDefaultPreview(), s.$preview.append("\n" + n), s._validateImage(e, a, p, i.type)) : s._previewDefault(i, a)
  			}
  		},
  		_slugDefault: function(e) {
  			return K(e) ? "" : String(e).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, "_")
  		},
  		_readFiles: function(i) {
  			this.reader = new FileReader;
  			var r, n = this,
  				l = n.$element,
  				o = n.$preview,
  				s = n.reader,
  				d = n.$previewContainer,
  				c = n.$previewStatus,
  				p = n.msgLoading,
  				u = n.msgProgress,
  				f = n.previewInitId,
  				v = i.length,
  				g = n.fileTypeSettings,
  				m = n.filestack.length,
  				h = function(t, a, l, o) {
  					var s = e.extend(!0, {}, n._getOutData({}, {}, i), {
  							id: l,
  							index: o
  						}),
  						d = {
  							id: l,
  							index: o,
  							file: a,
  							files: i
  						};
  					return n._previewDefault(a, l, !0), n.isUploadable && n.addToStack(void 0), setTimeout(r(o + 1), 100), n._initFileActions(), n.removeFromPreviewOnError && e("#" + l).remove(), n.isUploadable ? n._showUploadError(t, s) : n._showError(t, d)
  				};
  			n.loadedImages = [], n.totalImagesCount = 0, e.each(i, function(e, i) {
  				var t = n.fileTypeSettings.image || V.image;
  				t && t(i.type) && n.totalImagesCount++
  			}), r = function(e) {
  				if (K(l.attr("multiple")) && (v = 1), e >= v) return n.isUploadable && n.filestack.length > 0 ? n._raise("filebatchselected", [n.getFileStack()]) : n._raise("filebatchselected", [i]), d.removeClass("file-thumb-loading"), void c.html("");
  				var w, _, b, C, x, y, T = m + e,
  					F = f + "-" + T,
  					E = i[e],
  					I = n.slug(E.name),
  					$ = (E.size || 0) / 1e3,
  					k = "",
  					P = t.createObjectURL(E),
  					S = 0,
  					D = n.allowedFileTypes,
  					U = K(D) ? "" : D.join(", "),
  					A = n.allowedFileExtensions,
  					j = K(A) ? "" : A.join(", ");
  				if (K(A) || (k = new RegExp("\\.(" + A.join("|") + ")$", "i")), $ = $.toFixed(2), n.maxFileSize > 0 && $ > n.maxFileSize) return C = n.msgSizeTooLarge.replace("{name}", I).replace("{size}", $).replace("{maxSize}", n.maxFileSize), void(n.isError = h(C, E, F, e));
  				if (!K(D) && X(D)) {
  					for (b = 0; b < D.length; b += 1) x = D[b], _ = g[x], y = void 0 !== _ && _(E.type, I), S += K(y) ? 0 : y.length;
  					if (0 === S) return C = n.msgInvalidFileType.replace("{name}", I).replace("{types}", U), void(n.isError = h(C, E, F, e))
  				}
  				return 0 !== S || K(A) || !X(A) || K(k) || (y = a(I, k), S += K(y) ? 0 : y.length, 0 !== S) ? n.showPreview ? (o.length > 0 && void 0 !== FileReader ? (c.html(p.replace("{index}", e + 1).replace("{files}", v)), d.addClass("file-thumb-loading"), s.onerror = function(e) {
  					n._errorHandler(e, I)
  				}, s.onload = function(i) {
  					n._previewFile(e, E, i, F, P), n._initFileActions()
  				}, s.onloadend = function() {
  					C = u.replace("{index}", e + 1).replace("{files}", v).replace("{percent}", 50).replace("{name}", I), setTimeout(function() {
  						c.html(C), n._updateFileDetails(v), r(e + 1)
  					}, 100), n._raise("fileloaded", [E, F, e, s])
  				}, s.onprogress = function(i) {
  					if (i.lengthComputable) {
  						var t = i.loaded / i.total * 100,
  							a = Math.ceil(t);
  						C = u.replace("{index}", e + 1).replace("{files}", v).replace("{percent}", a).replace("{name}", I), setTimeout(function() {
  							c.html(C)
  						}, 100)
  					}
  				}, w = J("text", g) ? g.text : V.text, w(E.type, I) ? s.readAsText(E, n.textEncoding) : s.readAsArrayBuffer(E)) : (n._previewDefault(E, F), setTimeout(function() {
  					r(e + 1), n._updateFileDetails(v)
  				}, 100), n._raise("fileloaded", [E, F, e, s])), void n.addToStack(E)) : (n.addToStack(E), setTimeout(r(e + 1), 100), void n._raise("fileloaded", [E, F, e, s])) : (C = n.msgInvalidFileExtension.replace("{name}", I).replace("{extensions}", j), void(n.isError = h(C, E, F, e)))
  			}, r(0), n._updateFileDetails(v, !1)
  		},
  		_updateFileDetails: function(e) {
  			var i = this,
  				t = i.$element,
  				a = i.getFileStack(),
  				r = t[0].files[0] && t[0].files[0].name || a.length && a[0].name || "",
  				n = i.slug(r),
  				l = i.isUploadable ? a.length : e,
  				s = o.count(i.id) + l,
  				d = l > 1 ? i._getMsgSelected(s) : n;
  			i.isError ? (i.$previewContainer.removeClass("file-thumb-loading"), i.$previewStatus.html(""), i.$captionContainer.find(".kv-caption-icon").hide()) : i._showFileIcon(), i._setCaption(d, i.isError), i.$container.removeClass("file-input-new file-input-ajax-new"), 1 === arguments.length && i._raise("fileselect", [e, n]), o.count(i.id) && i._initPreviewDeletes()
  		},
  		_setThumbStatus: function(e, i) {
  			var t = this;
  			if (t.showPreview) {
  				var a = "indicator" + i,
  					r = a + "Title",
  					n = "file-preview-" + i.toLowerCase(),
  					l = e.find(".file-upload-indicator"),
  					o = t.fileActionSettings;
  				e.removeClass("file-preview-success file-preview-error file-preview-loading"), "Error" === i && e.find(".kv-file-upload").attr("disabled", !0), l.html(o[a]), l.attr("title", o[r]), e.addClass(n)
  			}
  		},
  		_setProgressCancelled: function() {
  			var e = this;
  			e._setProgress(100, e.$progress, e.msgCancelled)
  		},
  		_setProgress: function(e, i, t) {
  			var a = this,
  				r = Math.min(e, 100),
  				n = 100 > r ? a.progressTemplate : t ? a.progressErrorTemplate : a.progressCompleteTemplate;
  			i = i || a.$progress, K(n) || (i.html(n.replace(/\{percent}/g, r)), t && i.find('[role="progressbar"]').html(t))
  		},
  		_setFileDropZoneTitle: function() {
  			var e = this,
  				i = e.$container.find(".file-drop-zone");
  			i.find("." + e.dropZoneTitleClass).remove(), e.isUploadable && e.showPreview && 0 !== i.length && !(e.getFileStack().length > 0) && e.dropZoneEnabled && (0 === i.find(".file-preview-frame").length && K(e.defaultPreviewContent) && i.prepend('<div class="' + e.dropZoneTitleClass + '">' + e.dropZoneTitle + "</div>"), e.$container.removeClass("file-input-new"), u(e.$container, "file-input-ajax-new"))
  		},
  		_setAsyncUploadStatus: function(i, t, a) {
  			var r = this,
  				n = 0;
  			r._setProgress(t, e("#" + i).find(".file-thumb-progress")), r.uploadStatus[i] = t, e.each(r.uploadStatus, function(e, i) {
  				n += i
  			}), r._setProgress(Math.ceil(n / a))
  		},
  		_validateMinCount: function() {
  			var e = this,
  				i = e.isUploadable ? e.getFileStack().length : e.$element.get(0).files.length;
  			return e.validateInitialCount && e.minFileCount > 0 && e._getFileCount(i - 1) < e.minFileCount ? (e._noFilesError({}), !1) : !0
  		},
  		_getFileCount: function(e) {
  			var i = this,
  				t = 0;
  			return i.validateInitialCount && !i.overwriteInitial && (t = o.count(i.id), e += t), e
  		},
  		_getFileName: function(e) {
  			return e && e.name ? this.slug(e.name) : void 0
  		},
  		_getFileNames: function(e) {
  			var i = this;
  			return i.filenames.filter(function(i) {
  				return e ? void 0 !== i : void 0 !== i && null !== i
  			})
  		},
  		_setPreviewError: function(e, i, t) {
  			var a = this;
  			i && a.updateStack(i, t), a.removeFromPreviewOnError ? e.remove() : a._setThumbStatus(e, "Error")
  		},
  		_checkDimensions: function(e, i, t, a, r, n, l) {
  			var o, s, d, c, p = this,
  				u = "Small" === i ? "min" : "max",
  				f = p[u + "Image" + n];
  			!K(f) && t.length && (d = t[0], s = "Width" === n ? d.naturalWidth || d.width : d.naturalHeight || d.height, c = "Small" === i ? s >= f : f >= s, c || (o = p["msgImage" + n + i].replace("{name}", r).replace("{size}", f), p._showUploadError(o, l), p._setPreviewError(a, e, null)))
  		},
  		_validateImage: function(e, i, a, r) {
  			var n, o, s, d = this,
  				c = d.$preview,
  				p = c.find("#" + i),
  				u = p.find("img");
  			a = a || "Untitled", u.length && l(u, "load", function() {
  				o = p.width(), s = c.width(), o > s && (u.css("width", "100%"), p.css("width", "97%")), n = {
  					ind: e,
  					id: i
  				}, d._checkDimensions(e, "Small", u, p, a, "Width", n), d._checkDimensions(e, "Small", u, p, a, "Height", n), d.resizeImage || (d._checkDimensions(e, "Large", u, p, a, "Width", n), d._checkDimensions(e, "Large", u, p, a, "Height", n)), d._raise("fileimageloaded", [i]), d.loadedImages.push({
  					ind: e,
  					img: u,
  					thumb: p,
  					pid: i,
  					typ: r
  				}), d._validateAllImages(), t.revokeObjectURL(u.attr("src"))
  			})
  		},
  		_validateAllImages: function() {
  			var e, i, t, a, r, n, l, o = this,
  				s = {};
  			if (o.loadedImages.length === o.totalImagesCount && (o._raise("fileimagesloaded"), o.resizeImage)) {
  				for (l = o.isUploadable ? o._showUploadError : o._showError, e = 0; e < o.loadedImages.length; e++) i = o.loadedImages[e], t = i.img, a = i.thumb, r = i.pid, n = i.ind, s = {
  					id: r,
  					index: n
  				}, o._getResizedImage(t[0], i.typ, r, n) || (l(o.msgImageResizeError, s, "fileimageresizeerror"), o._setPreviewError(a, n));
  				o._raise("fileimagesresized")
  			}
  		},
  		_getResizedImage: function(e, i, t, a) {
  			var r, n, l = this,
  				o = e.naturalWidth,
  				s = e.naturalHeight,
  				d = 1,
  				c = l.maxImageWidth || o,
  				p = l.maxImageHeight || s,
  				u = o && s,
  				f = l.imageCanvas,
  				v = l.imageCanvasContext;
  			if (!u) return !1;
  			if (o === c && s === p) return !0;
  			i = i || l.resizeDefaultImageType, r = o > c, n = s > p, d = "width" === l.resizePreference ? r ? c / o : n ? p / s : 1 : n ? p / s : r ? c / o : 1, l._resetCanvas(), o *= d, s *= d, f.width = o, f.height = s;
  			try {
  				return v.drawImage(e, 0, 0, o, s), f.toBlob(function(e) {
  					l._raise("fileimageresized", [t, a]), l.filestack[a] = e
  				}, i, l.resizeQuality), !0
  			} catch (g) {
  				return !1
  			}
  		},
  		_initBrowse: function(e) {
  			var i = this;
  			i.$btnFile = e.find(".btn-file"), i.$btnFile.append(i.$element)
  		},
  		_initCaption: function() {
  			var e = this,
  				i = e.initialCaption || "";
  			return e.overwriteInitial || K(i) ? (e.$caption.html(""), !1) : (e._setCaption(i), !0)
  		},
  		_setCaption: function(i, t) {
  			var a, r, n, l, o = this,
  				s = o.getFileStack();
  			if (o.$caption.length) {
  				if (t) a = e("<div>" + o.msgValidationError + "</div>").text(), n = s.length, l = n ? 1 === n && s[0] ? o._getFileNames()[0] : o._getMsgSelected(n) : o._getMsgSelected(o.msgNo), r = '<span class="' + o.msgValidationErrorClass + '">' + o.msgValidationErrorIcon + (K(i) ? l : i) + "</span>";
  				else {
  					if (K(i)) return;
  					a = e("<div>" + i + "</div>").text(), r = o._getLayoutTemplate("icon") + a
  				}
  				o.$caption.html(r), o.$caption.attr("title", a), o.$captionContainer.find(".file-caption-ellipsis").attr("title", a)
  			}
  		},
  		_createContainer: function() {
  			var i = this,
  				t = e(document.createElement("div")).attr({
  					"class": "file-input file-input-new"
  				}).html(i._renderMain());
  			return i.$element.before(t), i._initBrowse(t), t
  		},
  		_refreshContainer: function() {
  			var e = this,
  				i = e.$container;
  			i.before(e.$element), i.html(e._renderMain()), e._initBrowse(i)
  		},
  		_renderMain: function() {
  			var e = this,
  				i = e.isUploadable && e.dropZoneEnabled ? " file-drop-zone" : "file-drop-disabled",
  				t = e.showClose ? e._getLayoutTemplate("close") : "",
  				a = e.showPreview ? e._getLayoutTemplate("preview").replace(/\{class}/g, e.previewClass).replace(/\{dropClass}/g, i) : "",
  				r = e.isDisabled ? e.captionClass + " file-caption-disabled" : e.captionClass,
  				n = e.captionTemplate.replace(/\{class}/g, r + " kv-fileinput-caption");
  			return e.mainTemplate.replace(/\{class}/g, e.mainClass).replace(/\{preview}/g, a).replace(/\{close}/g, t).replace(/\{caption}/g, n).replace(/\{upload}/g, e._renderButton("upload")).replace(/\{remove}/g, e._renderButton("remove")).replace(/\{cancel}/g, e._renderButton("cancel")).replace(/\{browse}/g, e._renderButton("browse"))
  		},
  		_renderButton: function(e) {
  			var i = this,
  				t = i._getLayoutTemplate("btnDefault"),
  				a = i[e + "Class"],
  				r = i[e + "Title"],
  				n = i[e + "Icon"],
  				l = i[e + "Label"],
  				o = i.isDisabled ? " disabled" : "",
  				s = "button";
  			switch (e) {
  				case "remove":
  					if (!i.showRemove) return "";
  					break;
  				case "cancel":
  					if (!i.showCancel) return "";
  					a += " hide";
  					break;
  				case "upload":
  					if (!i.showUpload) return "";
  					i.isUploadable && !i.isDisabled ? t = i._getLayoutTemplate("btnLink").replace("{href}", i.uploadUrl) : s = "submit";
  					break;
  				case "browse":
  					t = i._getLayoutTemplate("btnBrowse");
  					break;
  				default:
  					return ""
  			}
  			return a += "browse" === e ? " btn-file" : " fileinput-" + e + " fileinput-" + e + "-button", K(l) || (l = ' <span class="' + i.buttonLabelClass + '">' + l + "</span>"), t.replace("{type}", s).replace("{css}", a).replace("{title}", r).replace("{status}", o).replace("{icon}", n).replace("{label}", l)
  		},
  		_renderThumbProgress: function() {
  			return '<div class="file-thumb-progress hide">' + this.progressTemplate.replace(/\{percent}/g, "0") + "</div>"
  		},
  		_renderFileFooter: function(e, i) {
  			var t, a, r = this,
  				n = r.fileActionSettings,
  				l = r._getLayoutTemplate("footer");
  			return r.isUploadable ? (t = l.replace(/\{actions}/g, r._renderFileActions(!0, !0, !1, !1, !1)), a = t.replace(/\{caption}/g, e).replace(/\{width}/g, i).replace(/\{progress}/g, r._renderThumbProgress()).replace(/\{indicator}/g, n.indicatorNew).replace(/\{indicatorTitle}/g, n.indicatorNewTitle)) : a = l.replace(/\{actions}/g, "").replace(/\{caption}/g, e).replace(/\{progress}/g, "").replace(/\{width}/g, i).replace(/\{indicator}/g, "").replace(/\{indicatorTitle}/g, ""), a = ee(a, r.previewThumbTags)
  		},
  		_renderFileActions: function(e, i, t, a, r) {
  			if (!e && !i) return "";
  			var n = this,
  				l = a === !1 ? "" : ' data-url="' + a + '"',
  				o = r === !1 ? "" : ' data-key="' + r + '"',
  				s = n._getLayoutTemplate("actionDelete"),
  				d = "",
  				c = n._getLayoutTemplate("actions"),
  				p = n.otherActionButtons.replace(/\{dataKey}/g, o),
  				u = n.fileActionSettings,
  				f = t ? u.removeClass + " disabled" : u.removeClass;
  			return s = s.replace(/\{removeClass}/g, f).replace(/\{removeIcon}/g, u.removeIcon).replace(/\{removeTitle}/g, u.removeTitle).replace(/\{dataUrl}/g, l).replace(/\{dataKey}/g, o), e && (d = n._getLayoutTemplate("actionUpload").replace(/\{uploadClass}/g, u.uploadClass).replace(/\{uploadIcon}/g, u.uploadIcon).replace(/\{uploadTitle}/g, u.uploadTitle)), c.replace(/\{delete}/g, s).replace(/\{upload}/g, d).replace(/\{other}/g, p)
  		},
  		_browse: function(e) {
  			var i = this;
  			i._raise("filebrowse"), e && e.isDefaultPrevented() || (i.isError && !i.isUploadable && i.clear(), i.$captionContainer.focus())
  		},
  		_change: function(i) {
  			var t = this,
  				a = t.$element;
  			if (!t.isUploadable && K(a.val()) && t.fileInputCleared) return void(t.fileInputCleared = !1);
  			t.fileInputCleared = !1;
  			var r, n, l, s, d, c, p = arguments.length > 1,
  				u = t.isUploadable,
  				f = 0,
  				v = p ? i.originalEvent.dataTransfer.files : a.get(0).files,
  				g = t.filestack.length,
  				m = K(a.attr("multiple")),
  				h = m && g > 0,
  				w = 0,
  				_ = function(i, a, r, n) {
  					var l = e.extend(!0, {}, t._getOutData({}, {}, v), {
  							id: r,
  							index: n
  						}),
  						o = {
  							id: r,
  							index: n,
  							file: a,
  							files: v
  						};
  					return t.isUploadable ? t._showUploadError(i, l) : t._showError(i, o)
  				};
  			if (t.reader = null, t._resetUpload(), t._hideFileIcon(), t.isUploadable && t.$container.find(".file-drop-zone ." + t.dropZoneTitleClass).remove(), p)
  				for (r = []; v[f];) s = v[f], s.type || s.size % 4096 !== 0 ? r.push(s) : w++, f++;
  			else r = void 0 === i.target.files ? i.target && i.target.value ? [{
  				name: i.target.value.replace(/^.+\\/, "")
  			}] : [] : i.target.files;
  			if (K(r) || 0 === r.length) return u || t.clear(), t._showFolderError(w), void t._raise("fileselectnone");
  			if (t._resetErrors(), c = r.length, l = t._getFileCount(t.isUploadable ? t.getFileStack().length + c : c), t.maxFileCount > 0 && l > t.maxFileCount) {
  				if (!t.autoReplace || c > t.maxFileCount) return d = t.autoReplace && c > t.maxFileCount ? c : l, n = t.msgFilesTooMany.replace("{m}", t.maxFileCount).replace("{n}", d), t.isError = _(n, null, null, null), t.$captionContainer.find(".kv-caption-icon").hide(), t._setCaption("", !0), void t.$container.removeClass("file-input-new file-input-ajax-new");
  				l > t.maxFileCount && t._resetPreviewThumbs(u)
  			} else !u || h ? (t._resetPreviewThumbs(!1), h && t.clearStack()) : !u || 0 !== g || o.count(t.id) && !t.overwriteInitial || t._resetPreviewThumbs(!0);
  			t.isPreviewable ? t._readFiles(r) : t._updateFileDetails(1), t._showFolderError(w)
  		},
  		_abort: function(i) {
  			var t, a = this;
  			return a.ajaxAborted && "object" == typeof a.ajaxAborted && void 0 !== a.ajaxAborted.message ? (t = e.extend(!0, {}, a._getOutData(), i), t.abortData = a.ajaxAborted.data || {}, t.abortMessage = a.ajaxAborted.message, a.cancel(), a._setProgress(100, a.$progress, a.msgCancelled), a._showUploadError(a.ajaxAborted.message, t, "filecustomerror"), !0) : !1
  		},
  		_resetFileStack: function() {
  			var i = this,
  				t = 0,
  				a = [],
  				r = [];
  			i._getThumbs().each(function() {
  				var n = e(this),
  					l = n.attr("data-fileindex"),
  					o = i.filestack[l]; - 1 !== l && (void 0 !== o ? (a[t] = o, r[t] = i._getFileName(o), n.attr({
  					id: i.previewInitId + "-" + t,
  					"data-fileindex": t
  				}), t++) : n.attr({
  					id: "uploaded-" + Y(),
  					"data-fileindex": "-1"
  				}))
  			}), i.filestack = a, i.filenames = r
  		},
  		clearStack: function() {
  			var e = this;
  			return e.filestack = [], e.filenames = [], e.$element
  		},
  		updateStack: function(e, i) {
  			var t = this;
  			return t.filestack[e] = i, t.filenames[e] = t._getFileName(i), t.$element
  		},
  		addToStack: function(e) {
  			var i = this;
  			return i.filestack.push(e), i.filenames.push(i._getFileName(e)), i.$element
  		},
  		getFileStack: function(e) {
  			var i = this;
  			return i.filestack.filter(function(i) {
  				return e ? void 0 !== i : void 0 !== i && null !== i
  			})
  		},
  		lock: function() {
  			var e = this;
  			return e._resetErrors(), e.disable(), e.showRemove && u(e.$container.find(".fileinput-remove"), "hide"), e.showCancel && e.$container.find(".fileinput-cancel").removeClass("hide"), e._raise("filelock", [e.filestack, e._getExtraData()]), e.$element
  		},
  		unlock: function(e) {
  			var i = this;
  			return void 0 === e && (e = !0), i.enable(), i.showCancel && u(i.$container.find(".fileinput-cancel"), "hide"), i.showRemove && i.$container.find(".fileinput-remove").removeClass("hide"), e && i._resetFileStack(), i._raise("fileunlock", [i.filestack, i._getExtraData()]), i.$element
  		},
  		cancel: function() {
  			var i, t = this,
  				a = t.ajaxRequests,
  				r = a.length;
  			if (r > 0)
  				for (i = 0; r > i; i += 1) t.cancelling = !0, a[i].abort();
  			return t._setProgressCancelled(), t._getThumbs().each(function() {
  				var i = e(this),
  					a = i.attr("data-fileindex");
  				i.removeClass("file-uploading"), void 0 !== t.filestack[a] && (i.find(".kv-file-upload").removeClass("disabled").removeAttr("disabled"), i.find(".kv-file-remove").removeClass("disabled").removeAttr("disabled")), t.unlock()
  			}), t.$element
  		},
  		clear: function() {
  			var i, t = this;
  			return t.$btnUpload.removeAttr("disabled"), t._getThumbs().find("video,audio,img").each(function() {
  				ie(e(this))
  			}), t._resetUpload(), t.clearStack(), t._clearFileInput(), t._resetErrors(!0), t._raise("fileclear"), t._hasInitialPreview() ? (t._showFileIcon(), t._resetPreview(), t._initPreviewDeletes(), t.$container.removeClass("file-input-new")) : (t._getThumbs().each(function() {
  				t._clearObjects(e(this))
  			}), t.isUploadable && (o.data[t.id] = {}), t.$preview.html(""), i = !t.overwriteInitial && t.initialCaption.length > 0 ? t.initialCaption : "", t._setCaption(i), t.$caption.attr("title", ""), u(t.$container, "file-input-new"), t._validateDefaultPreview()), 0 === t.$container.find(".file-preview-frame").length && (t._initCaption() || t.$captionContainer.find(".kv-caption-icon").hide()), t._hideFileIcon(), t._raise("filecleared"), t.$captionContainer.focus(), t._setFileDropZoneTitle(), t.$element
  		},
  		reset: function() {
  			var e = this;
  			return e._resetPreview(), e.$container.find(".fileinput-filename").text(""), e._raise("filereset"), u(e.$container, "file-input-new"), (e.$preview.find(".file-preview-frame").length || e.isUploadable && e.dropZoneEnabled) && e.$container.removeClass("file-input-new"), e._setFileDropZoneTitle(), e.clearStack(), e.formdata = {}, e.$element
  		},
  		disable: function() {
  			var e = this;
  			return e.isDisabled = !0, e._raise("filedisabled"), e.$element.attr("disabled", "disabled"), e.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled"), e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr("disabled", !0), e._initDragDrop(), e.$element
  		},
  		enable: function() {
  			var e = this;
  			return e.isDisabled = !1, e._raise("fileenabled"), e.$element.removeAttr("disabled"), e.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled"), e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled"), e._initDragDrop(), e.$element
  		},
  		upload: function() {
  			var i, t, a, r = this,
  				n = r.getFileStack().length,
  				l = {},
  				o = !e.isEmptyObject(r._getExtraData());
  			if (r.minFileCount > 0 && r._getFileCount(n) < r.minFileCount) return void r._noFilesError(l);
  			if (r.isUploadable && !r.isDisabled && (0 !== n || o)) {
  				if (r._resetUpload(), r.$progress.removeClass("hide"), r.uploadCount = 0, r.uploadStatus = {}, r.uploadLog = [], r.lock(), r._setProgress(2), 0 === n && o) return void r._uploadExtraOnly();
  				if (a = r.filestack.length, r.hasInitData = !1, !r.uploadAsync) return r._uploadBatch(), r.$element;
  				for (t = r._getOutData(), r._raise("filebatchpreupload", [t]), r.fileBatchCompleted = !1, r.uploadCache = {
  						content: [],
  						config: [],
  						tags: [],
  						append: !0
  					}, r.uploadAsyncCount = r.getFileStack().length, i = 0; a > i; i++) r.uploadCache.content[i] = null, r.uploadCache.config[i] = null, r.uploadCache.tags[i] = null;
  				for (i = 0; a > i; i++) void 0 !== r.filestack[i] && r._uploadSingle(i, r.filestack, !0)
  			}
  		},
  		destroy: function() {
  			var e = this,
  				t = e.$container;
  			return t.find(".file-drop-zone").off(), e.$element.insertBefore(t).off(i).removeData(), t.off().remove(), e.$element
  		},
  		refresh: function(i) {
  			var t = this,
  				a = t.$element;
  			return i = i ? e.extend(!0, {}, t.options, i) : t.options, t.destroy(), a.fileinput(i), a.val() && a.trigger("change.fileinput"), a
  		}
  	}, e.fn.fileinput = function(i) {
  		if (d() || r(9)) {
  			var t = Array.apply(null, arguments),
  				a = [];
  			switch (t.shift(), this.each(function() {
  				var r, n = e(this),
  					l = n.data("fileinput"),
  					o = "object" == typeof i && i,
  					s = o.language || n.data("language") || "en",
  					d = {};
  				l || ("en" === s || K(e.fn.fileinputLocales[s]) || (d = e.fn.fileinputLocales[s]), r = e.extend(!0, {}, e.fn.fileinput.defaults, e.fn.fileinputLocales.en, d, o, n.data()), l = new q(this, r), n.data("fileinput", l)), "string" == typeof i && a.push(l[i].apply(l, t))
  			}), a.length) {
  				case 0:
  					return this;
  				case 1:
  					return a[0];
  				default:
  					return a
  			}
  		}
  	}, e.fn.fileinput.defaults = {
  		language: "en",
  		showCaption: !0,
  		showPreview: !0,
  		showRemove: !0,
  		showUpload: !0,
  		showCancel: !0,
  		showClose: !0,
  		showUploadedThumbs: !0,
  		autoReplace: !1,
  		mainClass: "",
  		previewClass: "",
  		captionClass: "",
  		mainTemplate: null,
  		initialCaption: "",
  		initialPreview: [],
  		initialPreviewDelimiter: "*$$*",
  		initialPreviewConfig: [],
  		initialPreviewThumbTags: [],
  		previewThumbTags: {},
  		initialPreviewShowDelete: !0,
  		removeFromPreviewOnError: !1,
  		deleteUrl: "",
  		deleteExtraData: {},
  		overwriteInitial: !0,
  		layoutTemplates: M,
  		previewTemplates: Z,
  		allowedPreviewTypes: H,
  		allowedPreviewMimeTypes: null,
  		allowedFileTypes: null,
  		allowedFileExtensions: null,
  		defaultPreviewContent: null,
  		customLayoutTags: {},
  		customPreviewTags: {},
  		previewSettings: W,
  		fileTypeSettings: V,
  		previewFileIcon: '<i class="glyphicon glyphicon-file"></i>',
  		previewFileIconClass: "file-icon-4x",
  		previewFileIconSettings: {},
  		previewFileExtSettings: {},
  		buttonLabelClass: "hidden-xs",
  		browseIcon: '<i class="glyphicon glyphicon-folder-open"></i>&nbsp;',
  		browseClass: "btn btn-primary",
  		removeIcon: '<i class="glyphicon glyphicon-trash"></i>',
  		removeClass: "btn btn-default",
  		cancelIcon: '<i class="glyphicon glyphicon-ban-circle"></i>',
  		cancelClass: "btn btn-default",
  		uploadIcon: '<i class="glyphicon glyphicon-upload"></i>',
  		uploadClass: "btn btn-default",
  		uploadUrl: null,
  		uploadAsync: !0,
  		uploadExtraData: {},
  		minImageWidth: null,
  		minImageHeight: null,
  		maxImageWidth: null,
  		maxImageHeight: null,
  		resizeImage: !1,
  		resizePreference: "width",
  		resizeQuality: .92,
  		resizeDefaultImageType: "image/jpeg",
  		maxFileSize: 0,
  		minFileCount: 0,
  		maxFileCount: 0,
  		validateInitialCount: !1,
  		msgValidationErrorClass: "text-danger",
  		msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ',
  		msgErrorClass: "file-error-message",
  		progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active",
  		progressClass: "progress-bar progress-bar-success progress-bar-striped active",
  		progressCompleteClass: "progress-bar progress-bar-success",
  		progressErrorClass: "progress-bar progress-bar-danger",
  		previewFileType: "image",
  		zoomIndicator: '<i class="glyphicon glyphicon-zoom-in"></i>',
  		elCaptionContainer: null,
  		elCaptionText: null,
  		elPreviewContainer: null,
  		elPreviewImage: null,
  		elPreviewStatus: null,
  		elErrorContainer: null,
  		errorCloseButton: '<span class="close kv-error-close">&times;</span>',
  		slugCallback: null,
  		dropZoneEnabled: !0,
  		dropZoneTitleClass: "file-drop-zone-title",
  		fileActionSettings: {},
  		otherActionButtons: "",
  		textEncoding: "UTF-8",
  		ajaxSettings: {},
  		ajaxDeleteSettings: {},
  		showAjaxErrorDetails: !0
  	}, e.fn.fileinputLocales.en = {
  		fileSingle: "file",
  		filePlural: "files",
  		browseLabel: "Browse &hellip;",
  		removeLabel: "Remove",
  		removeTitle: "Clear selected files",
  		cancelLabel: "Cancel",
  		cancelTitle: "Abort ongoing upload",
  		uploadLabel: "Upload",
  		uploadTitle: "Upload selected files",
  		msgNo: "No",
  		msgCancelled: "Cancelled",
  		msgZoomTitle: "View details",
  		msgZoomModalHeading: "Detailed Preview",
  		msgSizeTooLarge: 'File "{name}" (<b>{size} KB</b>) exceeds maximum allowed upload size of <b>{maxSize} KB</b>.',
  		msgFilesTooLess: "You must select at least <b>{n}</b> {files} to upload.",
  		msgFilesTooMany: "Number of files selected for upload <b>({n})</b> exceeds maximum allowed limit of <b>{m}</b>.",
  		msgFileNotFound: 'File "{name}" not found!',
  		msgFileSecured: 'Security restrictions prevent reading the file "{name}".',
  		msgFileNotReadable: 'File "{name}" is not readable.',
  		msgFilePreviewAborted: 'File preview aborted for "{name}".',
  		msgFilePreviewError: 'An error occurred while reading the file "{name}".',
  		msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.',
  		msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.',
  		msgUploadAborted: "The file upload was aborted",
  		msgValidationError: "Validation Error",
  		msgLoading: "Loading file {index} of {files} &hellip;",
  		msgProgress: "Loading file {index} of {files} - {name} - {percent}% completed.",
  		msgSelected: "{n} {files} selected",
  		msgFoldersNotAllowed: "Drag & drop files only! {n} folder(s) dropped were skipped.",
  		msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
  		msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
  		msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
  		msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
  		msgImageResizeError: "Could not get the image dimensions to resize.",
  		msgImageResizeException: "Error while resizing the image.<pre>{errors}</pre>",
  		dropZoneTitle: "Drag & drop files here &hellip;"
  	}, e.fn.fileinput.Constructor = q, e(document).ready(function() {
  		var i = e("input.file[type=file]");
  		i.length && i.fileinput()
  	})
  });