', 'igm');
+ reg_match.lastIndex = this.pos;
+ var reg_array = reg_match.exec(this.input);
+ var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script
+ if(this.pos < end_script) { //get everything in between the script tags
+ content = this.input.substring(this.pos, end_script);
+ this.pos = end_script;
+ }
+ return content;
+ };
+
+ this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object
+ if (this.tags[tag + 'count']) { //check for the existence of this tag type
+ this.tags[tag + 'count']++;
+ this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
+ }
+ else { //otherwise initialize this tag type
+ this.tags[tag + 'count'] = 1;
+ this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
+ }
+ this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
+ this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
+ };
+
+ this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer
+ if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
+ var temp_parent = this.tags.parent; //check to see if it's a closable tag.
+ while (temp_parent) { //till we reach '' (the initial value);
+ if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
+ break;
+ }
+ temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
+ }
+ if (temp_parent) { //if we caught something
+ this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
+ this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
+ }
+ delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
+ delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
+ if (this.tags[tag + 'count'] === 1) {
+ delete this.tags[tag + 'count'];
+ }
+ else {
+ this.tags[tag + 'count']--;
+ }
+ }
+ };
+
+ this.get_tag = function (peek) { //function to get a full tag and parse its type
+ var input_char = '',
+ content = [],
+ comment = '',
+ space = false,
+ tag_start, tag_end,
+ orig_pos = this.pos,
+ orig_line_char_count = this.line_char_count;
+
+ peek = peek !== undefined ? peek : false;
+
+ do {
+ if (this.pos >= this.input.length) {
+ if (peek) {
+ this.pos = orig_pos;
+ this.line_char_count = orig_line_char_count;
+ }
+ return content.length?content.join(''):['', 'TK_EOF'];
+ }
+
+ input_char = this.input.charAt(this.pos);
+ this.pos++;
+ this.line_char_count++;
+
+ if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
+ space = true;
+ this.line_char_count--;
+ continue;
+ }
+
+ if (input_char === "'" || input_char === '"') {
+ if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially
+ input_char += this.get_unformatted(input_char);
+ space = true;
+ }
+ }
+
+ if (input_char === '=') { //no space before =
+ space = false;
+ }
+
+ if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) {
+ //no space after = or before >
+ if (this.line_char_count >= this.max_char) {
+ this.print_newline(false, content);
+ this.line_char_count = 0;
+ }
+ else {
+ content.push(' ');
+ this.line_char_count++;
+ }
+ space = false;
+ }
+ if (input_char === '<') {
+ tag_start = this.pos - 1;
+ }
+ content.push(input_char); //inserts character at-a-time (or string)
+ } while (input_char !== '>');
+
+ var tag_complete = content.join('');
+ var tag_index;
+ if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
+ tag_index = tag_complete.indexOf(' ');
+ }
+ else { //otherwise go with the tag ending
+ tag_index = tag_complete.indexOf('>');
+ }
+ var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
+ if (tag_complete.charAt(tag_complete.length-2) === '/' ||
+ this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
+ if ( ! peek) {
+ this.tag_type = 'SINGLE';
+ }
+ }
+ else if (tag_check === 'script') { //for later script handling
+ if ( ! peek) {
+ this.record_tag(tag_check);
+ this.tag_type = 'SCRIPT';
+ }
+ }
+ else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
+ if ( ! peek) {
+ this.record_tag(tag_check);
+ this.tag_type = 'STYLE';
+ }
+ }
+ else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
+ comment = this.get_unformatted(''+tag_check+'>', tag_complete); //...delegate to get_unformatted function
+ content.push(comment);
+ // Preserve collapsed whitespace either before or after this tag.
+ if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){
+ content.splice(0, 0, this.input.charAt(tag_start - 1));
+ }
+ tag_end = this.pos - 1;
+ if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){
+ content.push(this.input.charAt(tag_end + 1));
+ }
+ this.tag_type = 'SINGLE';
+ }
+ else if (tag_check.charAt(0) === '!') { //peek for so...
+ comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
+ content.push(comment);
+ }
+ if ( ! peek) {
+ this.tag_type = 'START';
+ }
+ }
+ else if (tag_check.indexOf('[endif') !== -1) {//peek for ', tag_complete);
+ content.push(comment);
+ this.tag_type = 'SINGLE';
+ }
+ }
+ else if ( ! peek) {
+ if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
+ this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
+ this.tag_type = 'END';
+ }
+ else { //otherwise it's a start-tag
+ this.record_tag(tag_check); //push it on the tag stack
+ this.tag_type = 'START';
+ }
+ if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
+ this.print_newline(true, this.output);
+ }
+ }
+
+ if (peek) {
+ this.pos = orig_pos;
+ this.line_char_count = orig_line_char_count;
+ }
+
+ return content.join(''); //returns fully formatted tag
+ };
+
+ this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety
+
+ if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
+ return '';
+ }
+ var input_char = '';
+ var content = '';
+ var space = true;
+ do {
+
+ if (this.pos >= this.input.length) {
+ return content;
+ }
+
+ input_char = this.input.charAt(this.pos);
+ this.pos++;
+
+ if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
+ if (!space) {
+ this.line_char_count--;
+ continue;
+ }
+ if (input_char === '\n' || input_char === '\r') {
+ content += '\n';
+ /* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect tags if they are specified in the 'unformatted array'
+ for (var i=0; i]*>\s*$/);
+
+ // if next_tag comes back but is not an isolated tag, then
+ // let's treat the 'a' tag as having content
+ // and respect the unformatted option
+ if (!tag || this.Utils.in_array(tag, unformatted)){
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
+
+ this.input = js_source || ''; //gets the input for the Parser
+ this.output = [];
+ this.indent_character = indent_character;
+ this.indent_string = '';
+ this.indent_size = indent_size;
+ this.brace_style = brace_style;
+ this.indent_level = 0;
+ this.max_char = max_char;
+ this.line_char_count = 0; //count to see if max_char was exceeded
+
+ for (var i=0; i 0) {
+ this.indent_level--;
+ }
+ };
+ };
+ return this;
+ }
+
+ /*_____________________--------------------_____________________*/
+
+ multi_parser = new Parser(); //wrapping functions Parser
+ multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
+
+ while (true) {
+ var t = multi_parser.get_token();
+ multi_parser.token_text = t[0];
+ multi_parser.token_type = t[1];
+
+ if (multi_parser.token_type === 'TK_EOF') {
+ break;
+ }
+
+ switch (multi_parser.token_type) {
+ case 'TK_TAG_START':
+ multi_parser.print_newline(false, multi_parser.output);
+ multi_parser.print_token(multi_parser.token_text);
+ multi_parser.indent();
+ multi_parser.current_mode = 'CONTENT';
+ break;
+ case 'TK_TAG_STYLE':
+ case 'TK_TAG_SCRIPT':
+ multi_parser.print_newline(false, multi_parser.output);
+ multi_parser.print_token(multi_parser.token_text);
+ multi_parser.current_mode = 'CONTENT';
+ break;
+ case 'TK_TAG_END':
+ //Print new line only if the tag has no content and has child
+ if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
+ var tag_name = multi_parser.token_text.match(/\w+/)[0];
+ var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
+ if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
+ multi_parser.print_newline(true, multi_parser.output);
+ }
+ }
+ multi_parser.print_token(multi_parser.token_text);
+ multi_parser.current_mode = 'CONTENT';
+ break;
+ case 'TK_TAG_SINGLE':
+ // Don't add a newline before elements that should remain unformatted.
+ var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
+ if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
+ multi_parser.print_newline(false, multi_parser.output);
+ }
+ multi_parser.print_token(multi_parser.token_text);
+ multi_parser.current_mode = 'CONTENT';
+ break;
+ case 'TK_CONTENT':
+ if (multi_parser.token_text !== '') {
+ multi_parser.print_token(multi_parser.token_text);
+ }
+ multi_parser.current_mode = 'TAG';
+ break;
+ case 'TK_STYLE':
+ case 'TK_SCRIPT':
+ if (multi_parser.token_text !== '') {
+ multi_parser.output.push('\n');
+ var text = multi_parser.token_text,
+ _beautifier,
+ script_indent_level = 1;
+ if (multi_parser.token_type === 'TK_SCRIPT') {
+ _beautifier = typeof js_beautify === 'function' && js_beautify;
+ } else if (multi_parser.token_type === 'TK_STYLE') {
+ _beautifier = typeof css_beautify === 'function' && css_beautify;
+ }
+
+ if (options.indent_scripts === "keep") {
+ script_indent_level = 0;
+ } else if (options.indent_scripts === "separate") {
+ script_indent_level = -multi_parser.indent_level;
+ }
+
+ var indentation = multi_parser.get_full_indent(script_indent_level);
+ if (_beautifier) {
+ // call the Beautifier if avaliable
+ text = _beautifier(text.replace(/^\s*/, indentation), options);
+ } else {
+ // simply indent the string otherwise
+ var white = text.match(/^\s*/)[0];
+ var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
+ var reindent = multi_parser.get_full_indent(script_indent_level -_level);
+ text = text.replace(/^\s*/, indentation)
+ .replace(/\r\n|\r|\n/g, '\n' + reindent)
+ .replace(/\s*$/, '');
+ }
+ if (text) {
+ multi_parser.print_token(text);
+ multi_parser.print_newline(true, multi_parser.output);
+ }
+ }
+ multi_parser.current_mode = 'TAG';
+ break;
+ }
+ multi_parser.last_token = multi_parser.token_type;
+ multi_parser.last_text = multi_parser.token_text;
+ }
+ return multi_parser.output.join('');
+ }
+
+ // If we're running a web page and don't have either of the above, add our one global
+ window.html_beautify = function(html_source, options) {
+ return style_html(html_source, options, window.js_beautify, window.css_beautify);
+ };
+
+}());
diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js b/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
new file mode 100644
index 000000000..552613d96
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
@@ -0,0 +1,620 @@
+锘/*!
+ * jQuery blockUI plugin
+ * Version 2.70.0-2014.11.23
+ * Requires jQuery v1.7 or later
+ *
+ * Examples at: http://malsup.com/jquery/block/
+ * Copyright (c) 2007-2013 M. Alsup
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Thanks to Amir-Hossein Sobhi for some excellent contributions!
+ */
+
+;(function() {
+/*jshint eqeqeq:false curly:false latedef:false */
+"use strict";
+
+ function setup($) {
+ $.fn._fadeIn = $.fn.fadeIn;
+
+ var noOp = $.noop || function() {};
+
+ // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
+ // confusing userAgent strings on Vista)
+ var msie = /MSIE/.test(navigator.userAgent);
+ var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
+ var mode = document.documentMode || 0;
+ var setExpr = $.isFunction( document.createElement('div').style.setExpression );
+
+ // global $ methods for blocking/unblocking the entire page
+ $.blockUI = function(opts) { install(window, opts); };
+ $.unblockUI = function(opts) { remove(window, opts); };
+
+ // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
+ $.growlUI = function(title, message, timeout, onClose) {
+ var $m = $('');
+ if (title) $m.append(''+title+'
');
+ if (message) $m.append(''+message+'
');
+ if (timeout === undefined) timeout = 3000;
+
+ // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
+ var callBlock = function(opts) {
+ opts = opts || {};
+
+ $.blockUI({
+ message: $m,
+ fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
+ fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
+ timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
+ centerY: false,
+ showOverlay: false,
+ onUnblock: onClose,
+ css: $.blockUI.defaults.growlCSS
+ });
+ };
+
+ callBlock();
+ var nonmousedOpacity = $m.css('opacity');
+ $m.mouseover(function() {
+ callBlock({
+ fadeIn: 0,
+ timeout: 30000
+ });
+
+ var displayBlock = $('.blockMsg');
+ displayBlock.stop(); // cancel fadeout if it has started
+ displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
+ }).mouseout(function() {
+ $('.blockMsg').fadeOut(1000);
+ });
+ // End konapun additions
+ };
+
+ // plugin method for blocking element content
+ $.fn.block = function(opts) {
+ if ( this[0] === window ) {
+ $.blockUI( opts );
+ return this;
+ }
+ var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
+ this.each(function() {
+ var $el = $(this);
+ if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
+ return;
+ $el.unblock({ fadeOut: 0 });
+ });
+
+ return this.each(function() {
+ if ($.css(this,'position') == 'static') {
+ this.style.position = 'relative';
+ $(this).data('blockUI.static', true);
+ }
+ this.style.zoom = 1; // force 'hasLayout' in ie
+ install(this, opts);
+ });
+ };
+
+ // plugin method for unblocking element content
+ $.fn.unblock = function(opts) {
+ if ( this[0] === window ) {
+ $.unblockUI( opts );
+ return this;
+ }
+ return this.each(function() {
+ remove(this, opts);
+ });
+ };
+
+ $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
+
+ // override these in your code to change the default behavior and style
+ $.blockUI.defaults = {
+ // message displayed when blocking (use null for no message)
+ message: '',
+
+ title: null, // title string; only used when theme == true
+ draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
+
+ theme: false, // set to true to use with jQuery UI themes
+
+ // styles for the message when blocking; if you wish to disable
+ // these and use an external stylesheet then do this in your code:
+ // $.blockUI.defaults.css = {};
+ css: {
+ padding: 0,
+ margin: 0,
+ width: '30%',
+ top: '40%',
+ left: '35%',
+ textAlign: 'center',
+ color: '#000',
+ border: '0px',
+ backgroundColor:'transparent',
+ cursor: 'wait'
+ },
+
+ // minimal style set used when themes are used
+ themedCSS: {
+ width: '30%',
+ top: '40%',
+ left: '35%'
+ },
+
+ // styles for the overlay
+ overlayCSS: {
+ backgroundColor: '#000',
+ opacity: 0.6,
+ cursor: 'wait'
+ },
+
+ // style to replace wait cursor before unblocking to correct issue
+ // of lingering wait cursor
+ cursorReset: 'default',
+
+ // styles applied when using $.growlUI
+ growlCSS: {
+ width: '350px',
+ top: '10px',
+ left: '',
+ right: '10px',
+ border: 'none',
+ padding: '5px',
+ opacity: 0.6,
+ cursor: 'default',
+ color: '#fff',
+ backgroundColor: '#000',
+ '-webkit-border-radius':'10px',
+ '-moz-border-radius': '10px',
+ 'border-radius': '10px'
+ },
+
+ // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
+ // (hat tip to Jorge H. N. de Vasconcelos)
+ /*jshint scripturl:true */
+ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
+
+ // force usage of iframe in non-IE browsers (handy for blocking applets)
+ forceIframe: false,
+
+ // z-index for the blocking overlay
+ baseZ: 1000,
+
+ // set these to true to have the message automatically centered
+ centerX: true, // <-- only effects element blocking (page block controlled via css above)
+ centerY: true,
+
+ // allow body element to be stetched in ie6; this makes blocking look better
+ // on "short" pages. disable if you wish to prevent changes to the body height
+ allowBodyStretch: true,
+
+ // enable if you want key and mouse events to be disabled for content that is blocked
+ bindEvents: true,
+
+ // be default blockUI will supress tab navigation from leaving blocking content
+ // (if bindEvents is true)
+ constrainTabKey: true,
+
+ // fadeIn time in millis; set to 0 to disable fadeIn on block
+ fadeIn: 200,
+
+ // fadeOut time in millis; set to 0 to disable fadeOut on unblock
+ fadeOut: 400,
+
+ // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
+ timeout: 0,
+
+ // disable if you don't want to show the overlay
+ showOverlay: true,
+
+ // if true, focus will be placed in the first available input field when
+ // page blocking
+ focusInput: true,
+
+ // elements that can receive focus
+ focusableElements: ':input:enabled:visible',
+
+ // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
+ // no longer needed in 2012
+ // applyPlatformOpacityRules: true,
+
+ // callback method invoked when fadeIn has completed and blocking message is visible
+ onBlock: null,
+
+ // callback method invoked when unblocking has completed; the callback is
+ // passed the element that has been unblocked (which is the window object for page
+ // blocks) and the options that were passed to the unblock call:
+ // onUnblock(element, options)
+ onUnblock: null,
+
+ // callback method invoked when the overlay area is clicked.
+ // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
+ onOverlayClick: null,
+
+ // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
+ quirksmodeOffsetHack: 4,
+
+ // class name of the message block
+ blockMsgClass: 'blockMsg',
+
+ // if it is already blocked, then ignore it (don't unblock and reblock)
+ ignoreIfBlocked: false
+ };
+
+ // private data and functions follow...
+
+ var pageBlock = null;
+ var pageBlockEls = [];
+
+ function install(el, opts) {
+ var css, themedCSS;
+ var full = (el == window);
+ var msg = (opts && opts.message !== undefined ? opts.message : undefined);
+ opts = $.extend({}, $.blockUI.defaults, opts || {});
+
+ if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
+ return;
+
+ opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
+ css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
+ if (opts.onOverlayClick)
+ opts.overlayCSS.cursor = 'pointer';
+
+ themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
+ msg = msg === undefined ? opts.message : msg;
+
+ // remove the current block (if there is one)
+ if (full && pageBlock)
+ remove(window, {fadeOut:0});
+
+ // if an existing element is being used as the blocking content then we capture
+ // its current place in the DOM (and current display style) so we can restore
+ // it when we unblock
+ if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
+ var node = msg.jquery ? msg[0] : msg;
+ var data = {};
+ $(el).data('blockUI.history', data);
+ data.el = node;
+ data.parent = node.parentNode;
+ data.display = node.style.display;
+ data.position = node.style.position;
+ if (data.parent)
+ data.parent.removeChild(node);
+ }
+
+ $(el).data('blockUI.onUnblock', opts.onUnblock);
+ var z = opts.baseZ;
+
+ // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
+ // layer1 is the iframe layer which is used to supress bleed through of underlying content
+ // layer2 is the overlay layer which has opacity and a wait cursor (by default)
+ // layer3 is the message content that is displayed while blocking
+ var lyr1, lyr2, lyr3, s;
+ if (msie || opts.forceIframe)
+ lyr1 = $('');
+ else
+ lyr1 = $('');
+
+ if (opts.theme)
+ lyr2 = $('');
+ else
+ lyr2 = $('');
+
+ if (opts.theme && full) {
+ s = '';
+ if ( opts.title ) {
+ s += '';
+ }
+ s += '
';
+ s += '
';
+ }
+ else if (opts.theme) {
+ s = '';
+ }
+ else if (full) {
+ s = '';
+ }
+ else {
+ s = '';
+ }
+ lyr3 = $(s);
+
+ // if we have a message, style it
+ if (msg) {
+ if (opts.theme) {
+ lyr3.css(themedCSS);
+ lyr3.addClass('ui-widget-content');
+ }
+ else
+ lyr3.css(css);
+ }
+
+ // style the overlay
+ if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
+ lyr2.css(opts.overlayCSS);
+ lyr2.css('position', full ? 'fixed' : 'absolute');
+
+ // make iframe layer transparent in IE
+ if (msie || opts.forceIframe)
+ lyr1.css('opacity',0.0);
+
+ //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
+ var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
+ $.each(layers, function() {
+ this.appendTo($par);
+ });
+
+ if (opts.theme && opts.draggable && $.fn.draggable) {
+ lyr3.draggable({
+ handle: '.ui-dialog-titlebar',
+ cancel: 'li'
+ });
+ }
+
+ // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
+ var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
+ if (ie6 || expr) {
+ // give body 100% height
+ if (full && opts.allowBodyStretch && $.support.boxModel)
+ $('html,body').css('height','100%');
+
+ // fix ie6 issue when blocked element has a border width
+ if ((ie6 || !$.support.boxModel) && !full) {
+ var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
+ var fixT = t ? '(0 - '+t+')' : 0;
+ var fixL = l ? '(0 - '+l+')' : 0;
+ }
+
+ // simulate fixed position
+ $.each(layers, function(i,o) {
+ var s = o[0].style;
+ s.position = 'absolute';
+ if (i < 2) {
+ if (full)
+ s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
+ else
+ s.setExpression('height','this.parentNode.offsetHeight + "px"');
+ if (full)
+ s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
+ else
+ s.setExpression('width','this.parentNode.offsetWidth + "px"');
+ if (fixL) s.setExpression('left', fixL);
+ if (fixT) s.setExpression('top', fixT);
+ }
+ else if (opts.centerY) {
+ if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
+ s.marginTop = 0;
+ }
+ else if (!opts.centerY && full) {
+ var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
+ var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
+ s.setExpression('top',expression);
+ }
+ });
+ }
+
+ // show the message
+ if (msg) {
+ if (opts.theme)
+ lyr3.find('.ui-widget-content').append(msg);
+ else
+ lyr3.append(msg);
+ if (msg.jquery || msg.nodeType)
+ $(msg).show();
+ }
+
+ if ((msie || opts.forceIframe) && opts.showOverlay)
+ lyr1.show(); // opacity is zero
+ if (opts.fadeIn) {
+ var cb = opts.onBlock ? opts.onBlock : noOp;
+ var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
+ var cb2 = msg ? cb : noOp;
+ if (opts.showOverlay)
+ lyr2._fadeIn(opts.fadeIn, cb1);
+ if (msg)
+ lyr3._fadeIn(opts.fadeIn, cb2);
+ }
+ else {
+ if (opts.showOverlay)
+ lyr2.show();
+ if (msg)
+ lyr3.show();
+ if (opts.onBlock)
+ opts.onBlock.bind(lyr3)();
+ }
+
+ // bind key and mouse events
+ bind(1, el, opts);
+
+ if (full) {
+ pageBlock = lyr3[0];
+ pageBlockEls = $(opts.focusableElements,pageBlock);
+ if (opts.focusInput)
+ setTimeout(focus, 20);
+ }
+ else
+ center(lyr3[0], opts.centerX, opts.centerY);
+
+ if (opts.timeout) {
+ // auto-unblock
+ var to = setTimeout(function() {
+ if (full)
+ $.unblockUI(opts);
+ else
+ $(el).unblock(opts);
+ }, opts.timeout);
+ $(el).data('blockUI.timeout', to);
+ }
+ }
+
+ // remove the block
+ function remove(el, opts) {
+ var count;
+ var full = (el == window);
+ var $el = $(el);
+ var data = $el.data('blockUI.history');
+ var to = $el.data('blockUI.timeout');
+ if (to) {
+ clearTimeout(to);
+ $el.removeData('blockUI.timeout');
+ }
+ opts = $.extend({}, $.blockUI.defaults, opts || {});
+ bind(0, el, opts); // unbind events
+
+ if (opts.onUnblock === null) {
+ opts.onUnblock = $el.data('blockUI.onUnblock');
+ $el.removeData('blockUI.onUnblock');
+ }
+
+ var els;
+ if (full) // crazy selector to handle odd field errors in ie6/7
+ els = $('body').children().filter('.blockUI').add('body > .blockUI');
+ else
+ els = $el.find('>.blockUI');
+
+ // fix cursor issue
+ if ( opts.cursorReset ) {
+ if ( els.length > 1 )
+ els[1].style.cursor = opts.cursorReset;
+ if ( els.length > 2 )
+ els[2].style.cursor = opts.cursorReset;
+ }
+
+ if (full)
+ pageBlock = pageBlockEls = null;
+
+ if (opts.fadeOut) {
+ count = els.length;
+ els.stop().fadeOut(opts.fadeOut, function() {
+ if ( --count === 0)
+ reset(els,data,opts,el);
+ });
+ }
+ else
+ reset(els, data, opts, el);
+ }
+
+ // move blocking element back into the DOM where it started
+ function reset(els,data,opts,el) {
+ var $el = $(el);
+ if ( $el.data('blockUI.isBlocked') )
+ return;
+
+ els.each(function(i,o) {
+ // remove via DOM calls so we don't lose event handlers
+ if (this.parentNode)
+ this.parentNode.removeChild(this);
+ });
+
+ if (data && data.el) {
+ data.el.style.display = data.display;
+ data.el.style.position = data.position;
+ data.el.style.cursor = 'default'; // #59
+ if (data.parent)
+ data.parent.appendChild(data.el);
+ $el.removeData('blockUI.history');
+ }
+
+ if ($el.data('blockUI.static')) {
+ $el.css('position', 'static'); // #22
+ }
+
+ if (typeof opts.onUnblock == 'function')
+ opts.onUnblock(el,opts);
+
+ // fix issue in Safari 6 where block artifacts remain until reflow
+ var body = $(document.body), w = body.width(), cssW = body[0].style.width;
+ body.width(w-1).width(w);
+ body[0].style.width = cssW;
+ }
+
+ // bind/unbind the handler
+ function bind(b, el, opts) {
+ var full = el == window, $el = $(el);
+
+ // don't bother unbinding if there is nothing to unbind
+ if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
+ return;
+
+ $el.data('blockUI.isBlocked', b);
+
+ // don't bind events when overlay is not in use or if bindEvents is false
+ if (!full || !opts.bindEvents || (b && !opts.showOverlay))
+ return;
+
+ // bind anchors and inputs for mouse and key events
+ var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
+ if (b)
+ $(document).bind(events, opts, handler);
+ else
+ $(document).unbind(events, handler);
+
+ // former impl...
+ // var $e = $('a,:input');
+ // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
+ }
+
+ // event handler to suppress keyboard/mouse events when blocking
+ function handler(e) {
+ // allow tab navigation (conditionally)
+ if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
+ if (pageBlock && e.data.constrainTabKey) {
+ var els = pageBlockEls;
+ var fwd = !e.shiftKey && e.target === els[els.length-1];
+ var back = e.shiftKey && e.target === els[0];
+ if (fwd || back) {
+ setTimeout(function(){focus(back);},10);
+ return false;
+ }
+ }
+ }
+ var opts = e.data;
+ var target = $(e.target);
+ if (target.hasClass('blockOverlay') && opts.onOverlayClick)
+ opts.onOverlayClick(e);
+
+ // allow events within the message content
+ if (target.parents('div.' + opts.blockMsgClass).length > 0)
+ return true;
+
+ // allow events for content that is not being blocked
+ return target.parents().children().filter('div.blockUI').length === 0;
+ }
+
+ function focus(back) {
+ if (!pageBlockEls)
+ return;
+ var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
+ if (e)
+ e.focus();
+ }
+
+ function center(el, x, y) {
+ var p = el.parentNode, s = el.style;
+ var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
+ var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
+ if (x) s.left = l > 0 ? (l+'px') : '0';
+ if (y) s.top = t > 0 ? (t+'px') : '0';
+ }
+
+ function sz(el, p) {
+ return parseInt($.css(el,p),10)||0;
+ }
+
+ }
+
+
+ /*global define:true */
+ if (typeof define === 'function' && define.amd && define.amd.jQuery) {
+ define(['jquery'], setup);
+ } else {
+ setup(jQuery);
+ }
+
+})();
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css
new file mode 100644
index 000000000..0f27a5f5b
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css
@@ -0,0 +1,671 @@
+/*!
+ * bootstrap-fileinput v5.2.4
+ * http://plugins.krajee.com/file-input
+ *
+ * Krajee default styling for bootstrap-fileinput.
+ *
+ * Author: Kartik Visweswaran
+ * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com
+ *
+ * Licensed under the BSD-3-Clause
+ * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
+ */
+
+.file-loading input[type=file],
+input[type=file].file-loading {
+ width: 0;
+ height: 0;
+}
+
+.file-no-browse {
+ position: absolute;
+ left: 50%;
+ bottom: 20%;
+ width: 1px;
+ height: 1px;
+ font-size: 0;
+ opacity: 0;
+ border: none;
+ background: none;
+ outline: none;
+ box-shadow: none;
+}
+
+.kv-hidden,
+.file-caption-icon,
+.file-zoom-dialog .modal-header:before,
+.file-zoom-dialog .modal-header:after,
+.file-input-new .file-preview,
+.file-input-new .close,
+.file-input-new .glyphicon-file,
+.file-input-new .fileinput-remove-button,
+.file-input-new .fileinput-upload-button,
+.file-input-new .no-browse .input-group-btn,
+.file-input-ajax-new .fileinput-remove-button,
+.file-input-ajax-new .fileinput-upload-button,
+.file-input-ajax-new .no-browse .input-group-btn,
+.hide-content .kv-file-content,
+.is-locked .fileinput-upload-button,
+.is-locked .fileinput-remove-button {
+ display: none;
+}
+
+.btn-file input[type=file],
+.file-caption-icon,
+.file-preview .fileinput-remove,
+.krajee-default .file-thumb-progress,
+.file-zoom-dialog .btn-navigate,
+.file-zoom-dialog .floating-buttons {
+ position: absolute;
+}
+
+.file-caption-icon .kv-caption-icon {
+ line-height: inherit;
+}
+
+.file-input,
+.file-loading:before,
+.btn-file,
+.file-caption,
+.file-preview,
+.krajee-default.file-preview-frame,
+.krajee-default .file-thumbnail-footer,
+.file-zoom-dialog .modal-dialog {
+ position: relative;
+}
+
+.file-error-message pre,
+.file-error-message ul,
+.krajee-default .file-actions,
+.krajee-default .file-other-error {
+ text-align: left;
+}
+
+.file-error-message pre,
+.file-error-message ul {
+ margin: 0;
+}
+
+.krajee-default .file-drag-handle,
+.krajee-default .file-upload-indicator {
+ float: left;
+ margin-top: 10px;
+ width: 16px;
+ height: 16px;
+}
+
+.file-thumb-progress .progress,
+.file-thumb-progress .progress-bar {
+ font-family: Verdana, Helvetica, sans-serif;
+ font-size: 0.7rem;
+}
+
+.krajee-default .file-thumb-progress .progress,
+.kv-upload-progress .progress {
+ background-color: #ccc;
+}
+
+.krajee-default .file-caption-info,
+.krajee-default .file-size-info {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 160px;
+ height: 15px;
+ margin: auto;
+}
+
+.file-zoom-content > .file-object.type-video,
+.file-zoom-content > .file-object.type-flash,
+.file-zoom-content > .file-object.type-image {
+ max-width: 100%;
+ max-height: 100%;
+ width: auto;
+}
+
+.file-zoom-content > .file-object.type-video,
+.file-zoom-content > .file-object.type-flash {
+ height: 100%;
+}
+
+.file-zoom-content > .file-object.type-pdf,
+.file-zoom-content > .file-object.type-html,
+.file-zoom-content > .file-object.type-text,
+.file-zoom-content > .file-object.type-default {
+ width: 100%;
+}
+
+.file-loading:before {
+ content: " Loading...";
+ display: inline-block;
+ padding-left: 20px;
+ line-height: 16px;
+ font-size: 13px;
+ font-variant: small-caps;
+ color: #999;
+ background: transparent url(loading.gif) top left no-repeat;
+}
+
+.file-object {
+ margin: 0 0 -5px 0;
+ padding: 0;
+}
+
+.btn-file {
+ overflow: hidden;
+}
+
+.btn-file input[type=file] {
+ top: 0;
+ left: 0;
+ min-width: 100%;
+ min-height: 100%;
+ text-align: right;
+ opacity: 0;
+ background: none repeat scroll 0 0 transparent;
+ cursor: inherit;
+ display: block;
+}
+
+.btn-file ::-ms-browse {
+ font-size: 10000px;
+ width: 100%;
+ height: 100%;
+}
+
+.file-caption.icon-visible .file-caption-icon {
+ display: inline-block;
+}
+
+.file-caption.icon-visible .file-caption-name {
+ padding-left: 25px;
+}
+
+.file-caption.icon-visible > .input-group-lg .file-caption-name {
+ padding-left: 30px;
+}
+
+.file-caption.icon-visible > .input-group-sm .file-caption-name {
+ padding-left: 22px;
+}
+
+.file-caption-name:not(.file-caption-disabled) {
+ background-color: transparent;
+}
+
+.file-caption-name.file-processing {
+ font-style: italic;
+ border-color: #bbb;
+ opacity: 0.5;
+}
+
+.file-caption-icon {
+ padding: 7px 5px;
+ left: 4px;
+}
+
+.input-group-lg .file-caption-icon {
+ font-size: 1.25rem;
+}
+
+.input-group-sm .file-caption-icon {
+ font-size: 0.875rem;
+ padding: 0.25rem;
+}
+
+.file-error-message {
+ color: #a94442;
+ background-color: #f2dede;
+ margin: 5px;
+ border: 1px solid #ebccd1;
+ border-radius: 4px;
+ padding: 15px;
+}
+
+.file-error-message pre {
+ margin: 5px 0;
+}
+
+.file-caption-disabled {
+ background-color: #eee;
+ cursor: not-allowed;
+ opacity: 1;
+}
+
+.file-preview {
+ border-radius: 5px;
+ border: 1px solid #ddd;
+ padding: 8px;
+ width: 100%;
+ margin-bottom: 5px;
+}
+
+.file-preview .btn-xs {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.file-preview .fileinput-remove {
+ top: 1px;
+ right: 1px;
+ line-height: 10px;
+}
+
+.file-preview .clickable {
+ cursor: pointer;
+}
+
+.file-preview-image {
+ font: 40px Impact, Charcoal, sans-serif;
+ color: #008000;
+ width: auto;
+ height: auto;
+ max-width: 100%;
+ max-height: 100%;
+}
+
+.krajee-default.file-preview-frame {
+ margin: 8px;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
+ padding: 6px;
+ float: left;
+ text-align: center;
+}
+
+.krajee-default.file-preview-frame .kv-file-content {
+ width: 213px;
+ height: 160px;
+}
+
+.krajee-default .file-preview-other-frame {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
+ width: 400px;
+}
+
+.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content {
+ width: 240px;
+ height: 55px;
+}
+
+.krajee-default.file-preview-frame .file-thumbnail-footer {
+ height: 70px;
+}
+
+.krajee-default.file-preview-frame:not(.file-preview-error):hover {
+ border: 1px solid rgba(0, 0, 0, 0.3);
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
+}
+
+.krajee-default .file-preview-text {
+ color: #428bca;
+ border: 1px solid #ddd;
+ outline: none;
+ resize: none;
+}
+
+.krajee-default .file-preview-html {
+ border: 1px solid #ddd;
+}
+
+.krajee-default .file-other-icon {
+ font-size: 6em;
+ line-height: 1;
+}
+
+.krajee-default .file-footer-buttons {
+ float: right;
+}
+
+.krajee-default .file-footer-caption {
+ display: block;
+ text-align: center;
+ padding-top: 4px;
+ font-size: 11px;
+ color: #777;
+ margin-bottom: 30px;
+}
+
+.file-upload-stats {
+ font-size: 10px;
+ text-align: center;
+ width: 100%;
+}
+
+.kv-upload-progress .file-upload-stats {
+ font-size: 12px;
+ margin: -10px 0 5px;
+}
+
+.krajee-default .file-preview-error {
+ opacity: 0.65;
+ box-shadow: none;
+}
+
+.krajee-default .file-thumb-progress {
+ top: 37px;
+ left: 0;
+ right: 0;
+}
+
+.krajee-default.kvsortable-ghost {
+ background: #e1edf7;
+ border: 2px solid #a1abff;
+}
+
+.krajee-default .file-preview-other:hover {
+ opacity: 0.8;
+}
+
+.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover {
+ color: #000;
+}
+
+.kv-upload-progress .progress {
+ height: 20px;
+ margin: 10px 0;
+ overflow: hidden;
+}
+
+.kv-upload-progress .progress-bar {
+ height: 20px;
+ font-family: Verdana, Helvetica, sans-serif;
+}
+
+
+/*noinspection CssOverwrittenProperties*/
+
+.file-zoom-dialog .file-other-icon {
+ font-size: 22em;
+ font-size: 50vmin;
+}
+
+.file-zoom-dialog .modal-dialog {
+ width: auto;
+}
+
+.file-zoom-dialog .modal-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.file-zoom-dialog .btn-navigate {
+ margin: 0 0.1rem;
+ padding: 0;
+ font-size: 1.2rem;
+ width: 2.4rem;
+ height: 2.4rem;
+ top: 50%;
+ border-radius: 50%;
+ text-align:center;
+}
+
+.btn-navigate * {
+ width: auto;
+}
+
+.file-zoom-dialog .floating-buttons {
+ top: 5px;
+ right: 10px;
+}
+
+.file-zoom-dialog .btn-kv-prev {
+ left: 0;
+}
+
+.file-zoom-dialog .btn-kv-next {
+ right: 0;
+}
+
+.file-zoom-dialog .kv-zoom-caption {
+ max-width: 50%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.file-zoom-dialog .kv-zoom-header {
+ padding: 0.5rem;
+}
+
+.file-zoom-dialog .kv-zoom-body {
+ padding: 0.25rem 0.5rem 0.25rem 0;
+}
+
+.file-zoom-dialog .kv-zoom-description {
+ position: absolute;
+ opacity: 0.8;
+ font-size: 0.8rem;
+ background-color: #1a1a1a;
+ padding: 1rem;
+ text-align: center;
+ border-radius: 0.5rem;
+ color: #fff;
+ left: 15%;
+ right: 15%;
+ bottom: 15%;
+}
+
+.file-zoom-dialog .kv-desc-hide {
+ float: right;
+ color: #fff;
+ padding: 0 0.1rem;
+ background: none;
+ border: none;
+}
+
+.file-zoom-dialog .kv-desc-hide:hover {
+ opacity: 0.7;
+}
+
+.file-zoom-dialog .kv-desc-hide:focus {
+ opacity: 0.9;
+}
+
+.file-input-new .no-browse .form-control {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.file-input-ajax-new .no-browse .form-control {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.file-caption {
+ width: 100%;
+ position: relative;
+}
+
+.file-thumb-loading {
+ background: transparent url(loading.gif) no-repeat scroll center center content-box !important;
+}
+
+.file-drop-zone {
+ border: 1px dashed #aaa;
+ min-height: 260px;
+ border-radius: 4px;
+ text-align: center;
+ vertical-align: middle;
+ margin: 12px 15px 12px 12px;
+ padding: 5px;
+}
+
+.file-drop-zone.clickable:hover {
+ border: 2px dashed #999;
+}
+
+.file-drop-zone.clickable:focus {
+ border: 2px solid #5acde2;
+}
+
+.file-drop-zone .file-preview-thumbnails {
+ cursor: default;
+}
+
+.file-drop-zone-title {
+ color: #aaa;
+ font-size: 1.6em;
+ text-align: center;
+ padding: 85px 10px;
+ cursor: default;
+}
+
+.file-highlighted {
+ border: 2px dashed #999 !important;
+ background-color: #eee;
+}
+
+.file-uploading {
+ background: url(loading-sm.gif) no-repeat center bottom 10px;
+ opacity: 0.65;
+}
+
+.file-zoom-fullscreen .modal-dialog {
+ min-width: 100%;
+ margin: 0;
+}
+
+.file-zoom-fullscreen .modal-content {
+ border-radius: 0;
+ box-shadow: none;
+ min-height: 100vh;
+}
+
+.file-zoom-fullscreen .kv-zoom-body {
+ overflow-y: auto;
+}
+
+.floating-buttons {
+ z-index: 3000;
+}
+
+.floating-buttons .btn-kv {
+ margin-left: 3px;
+ z-index: 3000;
+}
+
+.kv-zoom-actions .btn-kv {
+ margin-left: 3px;
+}
+
+.file-zoom-content {
+ text-align: center;
+ white-space: nowrap;
+ min-height: 300px;
+}
+
+.file-zoom-content:hover {
+ background: transparent;
+}
+
+.file-zoom-content > * {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.file-zoom-content .kv-spacer {
+ height: 100%;
+}
+
+.file-zoom-content .file-preview-image {
+ max-height: 100%;
+}
+
+.file-zoom-content .file-preview-video {
+ max-height: 100%;
+}
+
+.file-zoom-content > .file-object.type-image {
+ height: auto;
+ min-height: inherit;
+}
+
+.file-zoom-content > .file-object.type-audio {
+ width: auto;
+ height: 30px;
+}
+
+@media (min-width: 576px) {
+ .file-zoom-dialog .modal-dialog {
+ max-width: 500px;
+ }
+}
+
+@media (min-width: 992px) {
+ .file-zoom-dialog .modal-lg {
+ max-width: 800px;
+ }
+}
+
+@media (max-width: 767px) {
+ .file-preview-thumbnails {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ }
+
+ .file-zoom-dialog .modal-header {
+ flex-direction: column;
+ }
+}
+
+@media (max-width: 350px) {
+ .krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content {
+ width: 160px;
+ }
+}
+
+@media (max-width: 420px) {
+ .krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
+ width: 100%;
+ }
+}
+
+.file-loading[dir=rtl]:before {
+ background: transparent url(loading.gif) top right no-repeat;
+ padding-left: 0;
+ padding-right: 20px;
+}
+
+.clickable .file-drop-zone-title {
+ cursor: pointer;
+}
+
+.file-sortable .file-drag-handle:hover {
+ opacity: 0.7;
+}
+
+.file-sortable .file-drag-handle {
+ cursor: grab;
+ opacity: 1;
+}
+
+.file-grabbing,
+.file-grabbing * {
+ cursor: not-allowed !important;
+}
+
+.file-grabbing .file-preview-thumbnails * {
+ cursor: grabbing !important;
+}
+
+.file-preview-frame.sortable-chosen {
+ background-color: #d9edf7;
+ border-color: #17a2b8;
+ box-shadow: none !important;
+}
+
+.file-preview .kv-zoom-cache {
+ display: none;
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js
new file mode 100644
index 000000000..f52cf3d79
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js
@@ -0,0 +1,6404 @@
+/*!
+ * bootstrap-fileinput v5.2.4
+ * http://plugins.krajee.com/file-input
+ *
+ * Author: Kartik Visweswaran
+ * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com
+ *
+ * Licensed under the BSD-3-Clause
+ * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
+ */
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else {
+ if (typeof module === 'object' && module.exports) {
+ //noinspection NpmUsedModulesInstalled
+ module.exports = factory(require('jquery'));
+ } else {
+ factory(window.jQuery);
+ }
+ }
+}(function ($) {
+ 'use strict';
+ $.fn.fileinputLocales = {};
+ $.fn.fileinputThemes = {};
+ if (!$.fn.fileinputBsVersion) {
+ $.fn.fileinputBsVersion = (window.Alert && window.Alert.VERSION) ||
+ (window.bootstrap && window.bootstrap.Alert && bootstrap.Alert.VERSION) || '3.x.x';
+ }
+ String.prototype.setTokens = function (replacePairs) {
+ var str = this.toString(), key, re;
+ for (key in replacePairs) {
+ if (replacePairs.hasOwnProperty(key)) {
+ re = new RegExp('\{' + key + '\}', 'g');
+ str = str.replace(re, replacePairs[key]);
+ }
+ }
+ return str;
+ };
+
+ if (!Array.prototype.flatMap) { // polyfill flatMap
+ Array.prototype.flatMap = function (lambda) {
+ return [].concat(this.map(lambda));
+ };
+ }
+
+ if (!document.currentScript) {
+ document.currentScript = function() {
+ var scripts = document.getElementsByTagName('script');
+ return scripts[scripts.length - 1];
+ }();
+ }
+
+ var $h, FileInput, getLoadingUrl = function () {
+ var src = document.currentScript.src, srcPath = src.substring(0, src.lastIndexOf("/"));
+ return srcPath + '/loading.gif'
+ };
+
+ // fileinput helper object for all global variables and internal helper methods
+ $h = {
+ FRAMES: '.kv-preview-thumb',
+ SORT_CSS: 'file-sortable',
+ INIT_FLAG: 'init-',
+ ZOOM_VAR: getLoadingUrl() + '?kvTemp__2873389129__=', // used to prevent 404 errors in URL parsing
+ OBJECT_PARAMS: '\n' +
+ '\n' +
+ '\n' +
+ '\n' +
+ '\n' +
+ '\n',
+ DEFAULT_PREVIEW: '\n' +
+ '{previewFileIcon}\n' +
+ '
',
+ MODAL_ID: 'kvFileinputModal',
+ MODAL_EVENTS: ['show', 'shown', 'hide', 'hidden', 'loaded'],
+ logMessages: {
+ ajaxError: '{status}: {error}. Error Details: {text}.',
+ badDroppedFiles: 'Error scanning dropped files!',
+ badExifParser: 'Error loading the piexif.js library. {details}',
+ badInputType: 'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.',
+ exifWarning: 'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded ' +
+ 'the "piexif.js" library correctly on your page before the "fileinput.js" script.',
+ invalidChunkSize: 'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.',
+ invalidThumb: 'Invalid thumb frame with id: "{id}".',
+ noResumableSupport: 'The browser does not support resumable or chunk uploads.',
+ noUploadUrl: 'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.',
+ retryStatus: 'Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.',
+ chunkQueueError: 'Could not push task to ajax pool for chunk index # {index}.',
+ resumableMaxRetriesReached: 'Maximum resumable ajax retries ({n}) reached.',
+ resumableRetryError: 'Could not retry the resumable request (try # {n})... aborting.',
+ resumableAborting: 'Aborting / cancelling the resumable request.',
+ resumableRequestError: 'Error processing resumable request. {msg}'
+
+ },
+ objUrl: window.URL || window.webkitURL,
+ isBs: function (ver) {
+ var chk = $.trim(($.fn.fileinputBsVersion || '') + '');
+ ver = parseInt(ver, 10);
+ if (!chk) {
+ return ver === 4;
+ }
+ return ver === parseInt(chk.charAt(0), 10);
+
+ },
+ defaultButtonCss: function (fill) {
+ return 'btn-default btn-' + (fill ? '' : 'outline-') + 'secondary';
+ },
+ now: function () {
+ return new Date().getTime();
+ },
+ round: function (num) {
+ num = parseFloat(num);
+ return isNaN(num) ? 0 : Math.floor(Math.round(num));
+ },
+ getArray: function (obj) {
+ var i, arr = [], len = obj && obj.length || 0;
+ for (i = 0; i < len; i++) {
+ arr.push(obj[i]);
+ }
+ return arr;
+ },
+ getFileRelativePath: function (file) {
+ /** @namespace file.relativePath */
+ /** @namespace file.webkitRelativePath */
+ return String(file.newPath || file.relativePath || file.webkitRelativePath || $h.getFileName(file) || null);
+
+ },
+ getFileId: function (file, generateFileId) {
+ var relativePath = $h.getFileRelativePath(file);
+ if (typeof generateFileId === 'function') {
+ return generateFileId(file);
+ }
+ if (!file) {
+ return null;
+ }
+ if (!relativePath) {
+ return null;
+ }
+ return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_'));
+ },
+ getFrameSelector: function (id, selector) {
+ selector = selector || '';
+ return '[id="' + id + '"]' + selector;
+ },
+ getZoomSelector: function (id, selector) {
+ return $h.getFrameSelector('zoom-' + id, selector);
+ },
+ getFrameElement: function ($element, id, selector) {
+ return $element.find($h.getFrameSelector(id, selector));
+ },
+ getZoomElement: function ($element, id, selector) {
+ return $element.find($h.getZoomSelector(id, selector));
+ },
+ getElapsed: function (seconds) {
+ var delta = seconds, out = '', result = {}, structure = {
+ year: 31536000,
+ month: 2592000,
+ week: 604800, // uncomment row to ignore
+ day: 86400, // feel free to add your own row
+ hour: 3600,
+ minute: 60,
+ second: 1
+ };
+ $h.getObjectKeys(structure).forEach(function (key) {
+ result[key] = Math.floor(delta / structure[key]);
+ delta -= result[key] * structure[key];
+ });
+ $.each(result, function (key, value) {
+ if (value > 0) {
+ out += (out ? ' ' : '') + value + key.substring(0, 1);
+ }
+ });
+ return out;
+ },
+ debounce: function (func, delay) {
+ var inDebounce;
+ return function () {
+ var args = arguments, context = this;
+ clearTimeout(inDebounce);
+ inDebounce = setTimeout(function () {
+ func.apply(context, args);
+ }, delay);
+ };
+ },
+ stopEvent: function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ },
+ getFileName: function (file) {
+ /** @namespace file.fileName */
+ return file ? (file.fileName || file.name || '') : ''; // some confusion in different versions of Firefox
+ },
+ createObjectURL: function (data) {
+ if ($h.objUrl && $h.objUrl.createObjectURL && data) {
+ return $h.objUrl.createObjectURL(data);
+ }
+ return '';
+ },
+ revokeObjectURL: function (data) {
+ if ($h.objUrl && $h.objUrl.revokeObjectURL && data) {
+ $h.objUrl.revokeObjectURL(data);
+ }
+ },
+ compare: function (input, str, exact) {
+ return input !== undefined && (exact ? input === str : input.match(str));
+ },
+ isIE: function (ver) {
+ var div, status;
+ // check for IE versions < 11
+ if (navigator.appName !== 'Microsoft Internet Explorer') {
+ return false;
+ }
+ if (ver === 10) {
+ return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent);
+ }
+ div = document.createElement('div');
+ div.innerHTML = '';
+ status = div.getElementsByTagName('i').length;
+ document.body.appendChild(div);
+ div.parentNode.removeChild(div);
+ return status;
+ },
+ canOrientImage: function ($el) {
+ var $img = $(document.createElement('img')).css({width: '1px', height: '1px'}).insertAfter($el),
+ flag = $img.css('image-orientation');
+ $img.remove();
+ return !!flag;
+ },
+ canAssignFilesToInput: function () {
+ var input = document.createElement('input');
+ try {
+ input.type = 'file';
+ input.files = null;
+ return true;
+ } catch (err) {
+ return false;
+ }
+ },
+ getDragDropFolders: function (items) {
+ var i, item, len = items ? items.length : 0, folders = 0;
+ if (len > 0 && items[0].webkitGetAsEntry()) {
+ for (i = 0; i < len; i++) {
+ item = items[i].webkitGetAsEntry();
+ if (item && item.isDirectory) {
+ folders++;
+ }
+ }
+ }
+ return folders;
+ },
+ initModal: function ($modal) {
+ var $body = $('body');
+ if ($body.length) {
+ $modal.appendTo($body);
+ }
+ },
+ isFunction: function (v) {
+ return typeof v === 'function';
+ },
+ isEmpty: function (value, trim) {
+ if (value === undefined || value === null || value === '') {
+ return true;
+ }
+ if ($h.isString(value) && trim) {
+ return $.trim(value) === '';
+ }
+ if ($h.isArray(value)) {
+ return value.length === 0;
+ }
+ if ($.isPlainObject(value) && $.isEmptyObject(value)) {
+ return true
+ }
+ return false;
+ },
+ isArray: function (a) {
+ return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
+ },
+ isString: function (a) {
+ return Object.prototype.toString.call(a) === '[object String]';
+ },
+ ifSet: function (needle, haystack, def) {
+ def = def || '';
+ return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : def;
+ },
+ cleanArray: function (arr) {
+ if (!(arr instanceof Array)) {
+ arr = [];
+ }
+ return arr.filter(function (e) {
+ return (e !== undefined && e !== null);
+ });
+ },
+ spliceArray: function (arr, index, reverseOrder) {
+ var i, j = 0, out = [], newArr;
+ if (!(arr instanceof Array)) {
+ return [];
+ }
+ newArr = $.extend(true, [], arr);
+ if (reverseOrder) {
+ newArr.reverse();
+ }
+ for (i = 0; i < newArr.length; i++) {
+ if (i !== index) {
+ out[j] = newArr[i];
+ j++;
+ }
+ }
+ if (reverseOrder) {
+ out.reverse();
+ }
+ return out;
+ },
+ getNum: function (num, def) {
+ def = def || 0;
+ if (typeof num === 'number') {
+ return num;
+ }
+ if (typeof num === 'string') {
+ num = parseFloat(num);
+ }
+ return isNaN(num) ? def : num;
+ },
+ hasFileAPISupport: function () {
+ return !!(window.File && window.FileReader);
+ },
+ hasDragDropSupport: function () {
+ var div = document.createElement('div');
+ /** @namespace div.draggable */
+ /** @namespace div.ondragstart */
+ /** @namespace div.ondrop */
+ return !$h.isIE(9) &&
+ (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined));
+ },
+ hasFileUploadSupport: function () {
+ return $h.hasFileAPISupport() && window.FormData;
+ },
+ hasBlobSupport: function () {
+ try {
+ return !!window.Blob && Boolean(new Blob());
+ } catch (e) {
+ return false;
+ }
+ },
+ hasArrayBufferViewSupport: function () {
+ try {
+ return new Blob([new Uint8Array(100)]).size === 100;
+ } catch (e) {
+ return false;
+ }
+ },
+ hasResumableUploadSupport: function () {
+ /** @namespace Blob.prototype.webkitSlice */
+ /** @namespace Blob.prototype.mozSlice */
+ return $h.hasFileUploadSupport() && $h.hasBlobSupport() && $h.hasArrayBufferViewSupport() &&
+ (!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || !!Blob.prototype.slice || false);
+ },
+ dataURI2Blob: function (dataURI) {
+ var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder ||
+ window.MSBlobBuilder, canBlob = $h.hasBlobSupport(), byteStr, arrayBuffer, intArray, i, mimeStr, bb,
+ canProceed = (canBlob || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array;
+ if (!canProceed) {
+ return null;
+ }
+ if (dataURI.split(',')[0].indexOf('base64') >= 0) {
+ byteStr = atob(dataURI.split(',')[1]);
+ } else {
+ byteStr = decodeURIComponent(dataURI.split(',')[1]);
+ }
+ arrayBuffer = new ArrayBuffer(byteStr.length);
+ intArray = new Uint8Array(arrayBuffer);
+ for (i = 0; i < byteStr.length; i += 1) {
+ intArray[i] = byteStr.charCodeAt(i);
+ }
+ mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0];
+ if (canBlob) {
+ return new Blob([$h.hasArrayBufferViewSupport() ? intArray : arrayBuffer], {type: mimeStr});
+ }
+ bb = new BlobBuilder();
+ bb.append(arrayBuffer);
+ return bb.getBlob(mimeStr);
+ },
+ arrayBuffer2String: function (buffer) {
+ if (window.TextDecoder) {
+ return new TextDecoder('utf-8').decode(buffer);
+ }
+ var array = Array.prototype.slice.apply(new Uint8Array(buffer)), out = '', i = 0, len, c, char2, char3;
+ len = array.length;
+ while (i < len) {
+ c = array[i++];
+ switch (c >> 4) { // jshint ignore:line
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 0xxxxxxx
+ out += String.fromCharCode(c);
+ break;
+ case 12:
+ case 13:
+ // 110x xxxx 10xx xxxx
+ char2 = array[i++];
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); // jshint ignore:line
+ break;
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ char2 = array[i++];
+ char3 = array[i++];
+ out += String.fromCharCode(((c & 0x0F) << 12) | // jshint ignore:line
+ ((char2 & 0x3F) << 6) | // jshint ignore:line
+ ((char3 & 0x3F) << 0)); // jshint ignore:line
+ break;
+ }
+ }
+ return out;
+ },
+ isHtml: function (str) {
+ var a = document.createElement('div');
+ a.innerHTML = str;
+ for (var c = a.childNodes, i = c.length; i--;) {
+ if (c[i].nodeType === 1) {
+ return true;
+ }
+ }
+ return false;
+ },
+ isSvg: function (str) {
+ return str.match(/^\s*<\?xml/i) && (str.match(/' + str + '' + tag + '>'));
+ },
+ uniqId: function () {
+ return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36);
+ },
+ cspBuffer: {
+ CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id
+ domElementsStyles: {},
+ stash: function (htmlString) {
+ var self = this, outerDom = $.parseHTML('' + htmlString + '
'), $el = $(outerDom);
+ $el.find('[style]').each(function (key, elem) {
+ var $elem = $(elem), styleDeclaration = $elem[0].style, id = $h.uniqId(), styles = {};
+ if (styleDeclaration && styleDeclaration.length) {
+ $(styleDeclaration).each(function () {
+ styles[this] = styleDeclaration[this];
+ });
+ self.domElementsStyles[id] = styles;
+ $elem.removeAttr('style').attr(self.CSP_ATTRIB, id);
+ }
+ });
+ $el.filter('*').removeAttr('style'); // make sure all style attr are removed
+ var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) {
+ return outerDom[itm];
+ });
+ return values.flatMap(function (elem) {
+ return elem.innerHTML;
+ }).join('');
+ },
+ apply: function (domElement) {
+ var self = this, $el = $(domElement);
+ $el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) {
+ var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id];
+ if (styles) {
+ $elem.css(styles);
+ }
+ $elem.removeAttr(self.CSP_ATTRIB);
+ });
+ self.domElementsStyles = {};
+ }
+ },
+ setHtml: function ($elem, htmlString) {
+ var buf = $h.cspBuffer;
+ $elem.html(buf.stash(htmlString));
+ buf.apply($elem);
+ return $elem;
+ },
+ htmlEncode: function (str, undefVal) {
+ if (str === undefined) {
+ return undefVal || null;
+ }
+ return str.replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ },
+ replaceTags: function (str, tags) {
+ var out = str;
+ if (!tags) {
+ return out;
+ }
+ $.each(tags, function (key, value) {
+ if (typeof value === 'function') {
+ value = value();
+ }
+ out = out.split(key).join(value);
+ });
+ return out;
+ },
+ cleanMemory: function ($thumb) {
+ var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src');
+ $h.revokeObjectURL(data);
+ },
+ findFileName: function (filePath) {
+ var sepIndex = filePath.lastIndexOf('/');
+ if (sepIndex === -1) {
+ sepIndex = filePath.lastIndexOf('\\');
+ }
+ return filePath.split(filePath.substring(sepIndex, sepIndex + 1)).pop();
+ },
+ checkFullScreen: function () {
+ return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement ||
+ document.msFullscreenElement;
+ },
+ toggleFullScreen: function (maximize) {
+ var doc = document, de = doc.documentElement, isFullScreen = $h.checkFullScreen();
+ if (de && maximize && !isFullScreen) {
+ if (de.requestFullscreen) {
+ de.requestFullscreen();
+ } else {
+ if (de.msRequestFullscreen) {
+ de.msRequestFullscreen();
+ } else {
+ if (de.mozRequestFullScreen) {
+ de.mozRequestFullScreen();
+ } else {
+ if (de.webkitRequestFullscreen) {
+ de.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ }
+ }
+ }
+ }
+ } else {
+ if (isFullScreen) {
+ if (doc.exitFullscreen) {
+ doc.exitFullscreen();
+ } else {
+ if (doc.msExitFullscreen) {
+ doc.msExitFullscreen();
+ } else {
+ if (doc.mozCancelFullScreen) {
+ doc.mozCancelFullScreen();
+ } else {
+ if (doc.webkitExitFullscreen) {
+ doc.webkitExitFullscreen();
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ moveArray: function (arr, oldIndex, newIndex, reverseOrder) {
+ var newArr = $.extend(true, [], arr);
+ if (reverseOrder) {
+ newArr.reverse();
+ }
+ if (newIndex >= newArr.length) {
+ var k = newIndex - newArr.length;
+ while ((k--) + 1) {
+ newArr.push(undefined);
+ }
+ }
+ newArr.splice(newIndex, 0, newArr.splice(oldIndex, 1)[0]);
+ if (reverseOrder) {
+ newArr.reverse();
+ }
+ return newArr;
+ },
+ closeButton: function (css) {
+ css = ($h.isBs(5) ? 'btn-close' : 'close') + (css ? ' ' + css : '');
+ return '';
+ },
+ getRotation: function (value) {
+ switch (value) {
+ case 2:
+ return 'rotateY(180deg)';
+ case 3:
+ return 'rotate(180deg)';
+ case 4:
+ return 'rotate(180deg) rotateY(180deg)';
+ case 5:
+ return 'rotate(270deg) rotateY(180deg)';
+ case 6:
+ return 'rotate(90deg)';
+ case 7:
+ return 'rotate(90deg) rotateY(180deg)';
+ case 8:
+ return 'rotate(270deg)';
+ default:
+ return '';
+ }
+ },
+ setTransform: function (el, val) {
+ if (!el) {
+ return;
+ }
+ el.style.transform = val;
+ el.style.webkitTransform = val;
+ el.style['-moz-transform'] = val;
+ el.style['-ms-transform'] = val;
+ el.style['-o-transform'] = val;
+ },
+ getObjectKeys: function (obj) {
+ var keys = [];
+ if (obj) {
+ $.each(obj, function (key) {
+ keys.push(key);
+ });
+ }
+ return keys;
+ },
+ getObjectSize: function (obj) {
+ return $h.getObjectKeys(obj).length;
+ },
+ /**
+ * Small dependency injection for the task manager
+ * https://gist.github.com/fearphage/4341799
+ */
+ whenAll: function (array) {
+ var s = [].slice, resolveValues = arguments.length === 1 && $h.isArray(array) ? array : s.call(arguments),
+ deferred = $.Deferred(), i, failed = 0, value, length = resolveValues.length,
+ remaining = length, rejectContexts, rejectValues, resolveContexts, updateFunc;
+ rejectContexts = rejectValues = resolveContexts = Array(length);
+ updateFunc = function (index, contexts, values) {
+ return function () {
+ if (values !== resolveValues) {
+ failed++;
+ }
+ deferred.notifyWith(contexts[index] = this, values[index] = s.call(arguments));
+ if (!(--remaining)) {
+ deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values);
+ }
+ };
+ };
+ for (i = 0; i < length; i++) {
+ if ((value = resolveValues[i]) && $.isFunction(value.promise)) {
+ value.promise()
+ .done(updateFunc(i, resolveContexts, resolveValues))
+ .fail(updateFunc(i, rejectContexts, rejectValues));
+ } else {
+ deferred.notifyWith(this, value);
+ --remaining;
+ }
+ }
+ if (!remaining) {
+ deferred.resolveWith(resolveContexts, resolveValues);
+ }
+ return deferred.promise();
+ }
+ };
+ FileInput = function (element, options) {
+ var self = this;
+ self.$element = $(element);
+ self.$parent = self.$element.parent();
+ if (!self._validate()) {
+ return;
+ }
+ self.isPreviewable = $h.hasFileAPISupport();
+ self.isIE9 = $h.isIE(9);
+ self.isIE10 = $h.isIE(10);
+ if (self.isPreviewable || self.isIE9) {
+ self._init(options);
+ self._listen();
+ }
+ self.$element.removeClass('file-loading');
+ };
+
+ FileInput.prototype = {
+ constructor: FileInput,
+ _cleanup: function () {
+ var self = this;
+ self.reader = null;
+ self.clearFileStack();
+ self.fileBatchCompleted = true;
+ self.isError = false;
+ self.isDuplicateError = false;
+ self.isPersistentError = false;
+ self.cancelling = false;
+ self.paused = false;
+ self.lastProgress = 0;
+ self._initAjax();
+ },
+ _isAborted: function () {
+ var self = this;
+ return self.cancelling || self.paused;
+ },
+ _initAjax: function () {
+ var self = this, tm = self.taskManager = {
+ pool: {},
+ addPool: function (id) {
+ return (tm.pool[id] = new tm.TasksPool(id));
+ },
+ getPool: function (id) {
+ return tm.pool[id];
+ },
+ addTask: function (id, logic) { // add standalone task directly from task manager
+ return new tm.Task(id, logic);
+ },
+ TasksPool: function (id) {
+ var tp = this;
+ tp.id = id;
+ tp.cancelled = false;
+ tp.cancelledDeferrer = $.Deferred();
+ tp.tasks = {};
+ tp.addTask = function (id, logic) {
+ return (tp.tasks[id] = new tm.Task(id, logic));
+ };
+ tp.size = function () {
+ return $h.getObjectSize(tp.tasks);
+ };
+ tp.run = function (maxThreads) {
+ var i = 0, failed = false, task, tasksList = $h.getObjectKeys(tp.tasks).map(function (key) {
+ return tp.tasks[key];
+ }), tasksDone = [], deferred = $.Deferred(), enqueue, callback;
+
+ if (tp.cancelled) {
+ tp.cancelledDeferrer.resolve();
+ return deferred.reject();
+ }
+ // if run all at once
+ if (!maxThreads) {
+ var tasksDeferredList = $h.getObjectKeys(tp.tasks).map(function (key) {
+ return tp.tasks[key].deferred;
+ });
+ // when all are done
+ $h.whenAll(tasksDeferredList).done(function () {
+ var argv = $h.getArray(arguments);
+ if (!tp.cancelled) {
+ deferred.resolve.apply(null, argv);
+ tp.cancelledDeferrer.reject();
+ } else {
+ deferred.reject.apply(null, argv);
+ tp.cancelledDeferrer.resolve();
+ }
+ }).fail(function () {
+ var argv = $h.getArray(arguments);
+ deferred.reject.apply(null, argv);
+ if (!tp.cancelled) {
+ tp.cancelledDeferrer.reject();
+ } else {
+ tp.cancelledDeferrer.resolve();
+ }
+ });
+ // run all tasks
+ $.each(tp.tasks, function (id) {
+ task = tp.tasks[id];
+ task.run();
+ });
+ return deferred;
+ }
+ enqueue = function (task) {
+ $.when(task.deferred)
+ .fail(function () {
+ failed = true;
+ callback.apply(null, arguments);
+ })
+ .always(callback);
+ };
+ callback = function () {
+ var argv = $h.getArray(arguments);
+ // notify a task just ended
+ deferred.notify(argv);
+ tasksDone.push(argv);
+ if (tp.cancelled) {
+ deferred.reject.apply(null, tasksDone);
+ tp.cancelledDeferrer.resolve();
+ return;
+ }
+ if (tasksDone.length === tp.size()) {
+ if (failed) {
+ deferred.reject.apply(null, tasksDone);
+ } else {
+ deferred.resolve.apply(null, tasksDone);
+ }
+ }
+ // if there are any tasks remaining
+ if (tasksList.length) {
+ task = tasksList.shift();
+ enqueue(task);
+ task.run();
+ }
+ };
+ // run the first "maxThreads" tasks
+ while (tasksList.length && i++ < maxThreads) {
+ task = tasksList.shift();
+ enqueue(task);
+ task.run();
+ }
+ return deferred;
+ };
+ tp.cancel = function () {
+ tp.cancelled = true;
+ return tp.cancelledDeferrer;
+ };
+ },
+ Task: function (id, logic) {
+ var tk = this;
+ tk.id = id;
+ tk.deferred = $.Deferred();
+ tk.logic = logic;
+ tk.context = null;
+ tk.run = function () {
+ var argv = $h.getArray(arguments);
+ argv.unshift(tk.deferred); // add deferrer as first argument
+ logic.apply(tk.context, argv); // run task
+ return tk.deferred; // return deferrer
+ };
+ tk.runWithContext = function (context) {
+ tk.context = context;
+ return tk.run();
+ };
+ }
+ };
+ self.ajaxQueue = [];
+ self.ajaxRequests = [];
+ self.ajaxAborted = false;
+ },
+ _init: function (options, refreshMode) {
+ var self = this, f, $el = self.$element, $cont, t, tmp;
+ self.options = options;
+ self.canOrientImage = $h.canOrientImage($el);
+ $.each(options, function (key, value) {
+ switch (key) {
+ case 'minFileCount':
+ case 'maxFileCount':
+ case 'maxTotalFileCount':
+ case 'minFileSize':
+ case 'maxFileSize':
+ case 'maxFilePreviewSize':
+ case 'resizeQuality':
+ case 'resizeIfSizeMoreThan':
+ case 'progressUploadThreshold':
+ case 'initialPreviewCount':
+ case 'zoomModalHeight':
+ case 'minImageHeight':
+ case 'maxImageHeight':
+ case 'minImageWidth':
+ case 'maxImageWidth':
+ case 'bytesToKB':
+ self[key] = $h.getNum(value);
+ break;
+ default:
+ self[key] = value;
+ break;
+ }
+ });
+ if (!self.bytesToKB || self.bytesToKB <= 0) {
+ self.bytesToKB = 1024;
+ }
+ if (self.errorCloseButton === undefined) {
+ self.errorCloseButton = $h.closeButton('kv-error-close' + ($h.isBs(5) ? ' float-end' : ''));
+ }
+ if (self.maxTotalFileCount > 0 && self.maxTotalFileCount < self.maxFileCount) {
+ self.maxTotalFileCount = self.maxFileCount;
+ }
+ if (self.rtl) { // swap buttons for rtl
+ tmp = self.previewZoomButtonIcons.prev;
+ self.previewZoomButtonIcons.prev = self.previewZoomButtonIcons.next;
+ self.previewZoomButtonIcons.next = tmp;
+ }
+ // validate chunk threads to not exceed maxAjaxThreads
+ if (!isNaN(self.maxAjaxThreads) && self.maxAjaxThreads < self.resumableUploadOptions.maxThreads) {
+ self.resumableUploadOptions.maxThreads = self.maxAjaxThreads;
+ }
+ self._initFileManager();
+ if (typeof self.autoOrientImage === 'function') {
+ self.autoOrientImage = self.autoOrientImage();
+ }
+ if (typeof self.autoOrientImageInitial === 'function') {
+ self.autoOrientImageInitial = self.autoOrientImageInitial();
+ }
+ if (!refreshMode) {
+ self._cleanup();
+ }
+ self.duplicateErrors = [];
+ self.$form = $el.closest('form');
+ self._initTemplateDefaults();
+ self.uploadFileAttr = !$h.isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data';
+ t = self._getLayoutTemplate('progress');
+ self.progressTemplate = t.replace('{class}', self.progressClass);
+ self.progressInfoTemplate = t.replace('{class}', self.progressInfoClass);
+ self.progressPauseTemplate = t.replace('{class}', self.progressPauseClass);
+ self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
+ self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass);
+ self.isDisabled = $el.attr('disabled') || $el.attr('readonly');
+ if (self.isDisabled) {
+ $el.attr('disabled', true);
+ }
+ self.isClickable = self.browseOnZoneClick && self.showPreview &&
+ (self.dropZoneEnabled || !$h.isEmpty(self.defaultPreviewContent));
+ self.isAjaxUpload = $h.hasFileUploadSupport() && !$h.isEmpty(self.uploadUrl);
+ self.dropZoneEnabled = $h.hasDragDropSupport() && self.dropZoneEnabled;
+ if (!self.isAjaxUpload) {
+ self.dropZoneEnabled = self.dropZoneEnabled && $h.canAssignFilesToInput();
+ }
+ self.slug = typeof options.slugCallback === 'function' ? options.slugCallback : self._slugDefault;
+ self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2');
+ self.captionTemplate = self._getLayoutTemplate('caption');
+ self.previewGenericTemplate = self._getPreviewTemplate('generic');
+ if (!self.imageCanvas && self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) {
+ self.imageCanvas = document.createElement('canvas');
+ self.imageCanvasContext = self.imageCanvas.getContext('2d');
+ }
+ if ($h.isEmpty($el.attr('id'))) {
+ $el.attr('id', $h.uniqId());
+ }
+ self.namespace = '.fileinput_' + $el.attr('id').replace(/-/g, '_');
+ if (self.$container === undefined) {
+ self.$container = self._createContainer();
+ } else {
+ self._refreshContainer();
+ }
+ $cont = self.$container;
+ self.$dropZone = $cont.find('.file-drop-zone');
+ self.$progress = $cont.find('.kv-upload-progress');
+ self.$btnUpload = $cont.find('.fileinput-upload');
+ self.$captionContainer = $h.getElement(options, 'elCaptionContainer', $cont.find('.file-caption'));
+ self.$caption = $h.getElement(options, 'elCaptionText', $cont.find('.file-caption-name'));
+ if (!$h.isEmpty(self.msgPlaceholder)) {
+ f = $el.attr('multiple') ? self.filePlural : self.fileSingle;
+ self.$caption.attr('placeholder', self.msgPlaceholder.replace('{files}', f));
+ }
+ self.$captionIcon = self.$captionContainer.find('.file-caption-icon');
+ self.$previewContainer = $h.getElement(options, 'elPreviewContainer', $cont.find('.file-preview'));
+ self.$preview = $h.getElement(options, 'elPreviewImage', $cont.find('.file-preview-thumbnails'));
+ self.$previewStatus = $h.getElement(options, 'elPreviewStatus', $cont.find('.file-preview-status'));
+ self.$errorContainer = $h.getElement(options, 'elErrorContainer',
+ self.$previewContainer.find('.kv-fileinput-error'));
+ self._validateDisabled();
+ if (!$h.isEmpty(self.msgErrorClass)) {
+ $h.addCss(self.$errorContainer, self.msgErrorClass);
+ }
+ if (!refreshMode) {
+ self._resetErrors();
+ self.$errorContainer.hide();
+ self.previewInitId = 'thumb-' + $el.attr('id');
+ self._initPreviewCache();
+ self._initPreview(true);
+ self._initPreviewActions();
+ if (self.$parent.hasClass('file-loading')) {
+ self.$container.insertBefore(self.$parent);
+ self.$parent.remove();
+ }
+ } else {
+ if (!self._errorsExist()) {
+ self.$errorContainer.hide();
+ }
+ }
+ self._setFileDropZoneTitle();
+ if ($el.attr('disabled')) {
+ self.disable();
+ }
+ self._initZoom();
+ if (self.hideThumbnailContent) {
+ $h.addCss(self.$preview, 'hide-content');
+ }
+ },
+ _initFileManager: function () {
+ var self = this;
+ self.uploadStartTime = $h.now();
+ self.fileManager = {
+ stack: {},
+ filesProcessed: [],
+ errors: [],
+ loadedImages: {},
+ totalImages: 0,
+ totalFiles: null,
+ totalSize: null,
+ uploadedSize: 0,
+ stats: {},
+ bpsLog: [],
+ bps: 0,
+ initStats: function (id) {
+ var data = {started: $h.now()};
+ if (id) {
+ self.fileManager.stats[id] = data;
+ } else {
+ self.fileManager.stats = data;
+ }
+ },
+ getUploadStats: function (id, loaded, total) {
+ var fm = self.fileManager,
+ started = id ? fm.stats[id] && fm.stats[id].started || $h.now() : self.uploadStartTime,
+ elapsed = ($h.now() - started) / 1000, bps = Math.ceil(elapsed ? loaded / elapsed : 0),
+ pendingBytes = total - loaded, out, delay = fm.bpsLog.length ? self.bitrateUpdateDelay : 0;
+ setTimeout(function () {
+ var i, j = 0, n = 0, len, beg;
+ fm.bpsLog.push(bps);
+ fm.bpsLog.sort(function (a, b) {
+ return a - b;
+ });
+ len = fm.bpsLog.length;
+ beg = len > 10 ? len - 10 : Math.ceil(len / 2);
+ for (i = len; i > beg; i--) {
+ n = parseFloat(fm.bpsLog[i]);
+ j++;
+ }
+ fm.bps = (j > 0 ? n / j : 0) * 64;
+ }, delay);
+ out = {
+ fileId: id,
+ started: started,
+ elapsed: elapsed,
+ loaded: loaded,
+ total: total,
+ bps: fm.bps,
+ bitrate: self._getSize(fm.bps, self.bitRateUnits),
+ pendingBytes: pendingBytes
+ };
+ if (id) {
+ fm.stats[id] = out;
+ } else {
+ fm.stats = out;
+ }
+ return out;
+ },
+ exists: function (id) {
+ return $.inArray(id, self.fileManager.getIdList()) !== -1;
+ },
+ count: function () {
+ return self.fileManager.getIdList().length;
+ },
+ total: function () {
+ var fm = self.fileManager;
+ if (!fm.totalFiles) {
+ fm.totalFiles = fm.count();
+ }
+ return fm.totalFiles;
+ },
+ getTotalSize: function () {
+ var fm = self.fileManager;
+ if (fm.totalSize) {
+ return fm.totalSize;
+ }
+ fm.totalSize = 0;
+ $.each(self.getFileStack(), function (id, f) {
+ var size = parseFloat(f.size);
+ fm.totalSize += isNaN(size) ? 0 : size;
+ });
+ return fm.totalSize;
+ },
+ add: function (file, id) {
+ if (!id) {
+ id = self.fileManager.getId(file);
+ }
+ if (!id) {
+ return;
+ }
+ self.fileManager.stack[id] = {
+ file: file,
+ name: $h.getFileName(file),
+ relativePath: $h.getFileRelativePath(file),
+ size: file.size,
+ nameFmt: self._getFileName(file, ''),
+ sizeFmt: self._getSize(file.size)
+ };
+ },
+ remove: function ($thumb) {
+ var id = self._getThumbFileId($thumb);
+ self.fileManager.removeFile(id);
+ },
+ removeFile: function (id) {
+ var fm = self.fileManager;
+ if (!id) {
+ return;
+ }
+ delete fm.stack[id];
+ delete fm.loadedImages[id];
+ },
+ move: function (idFrom, idTo) {
+ var result = {}, stack = self.fileManager.stack;
+ if (!idFrom && !idTo || idFrom === idTo) {
+ return;
+ }
+ $.each(stack, function (k, v) {
+ if (k !== idFrom) {
+ result[k] = v;
+ }
+ if (k === idTo) {
+ result[idFrom] = stack[idFrom];
+ }
+ });
+ self.fileManager.stack = result;
+ },
+ list: function () {
+ var files = [];
+ $.each(self.getFileStack(), function (k, v) {
+ if (v && v.file) {
+ files.push(v.file);
+ }
+ });
+ return files;
+ },
+ isPending: function (id) {
+ return $.inArray(id, self.fileManager.filesProcessed) === -1 && self.fileManager.exists(id);
+ },
+ isProcessed: function () {
+ var filesProcessed = true, fm = self.fileManager;
+ $.each(self.getFileStack(), function (id) {
+ if (fm.isPending(id)) {
+ filesProcessed = false;
+ }
+ });
+ return filesProcessed;
+ },
+ clear: function () {
+ var fm = self.fileManager;
+ self.isDuplicateError = false;
+ self.isPersistentError = false;
+ fm.totalFiles = null;
+ fm.totalSize = null;
+ fm.uploadedSize = 0;
+ fm.stack = {};
+ fm.errors = [];
+ fm.filesProcessed = [];
+ fm.stats = {};
+ fm.bpsLog = [];
+ fm.bps = 0;
+ fm.clearImages();
+ },
+ clearImages: function () {
+ self.fileManager.loadedImages = {};
+ self.fileManager.totalImages = 0;
+ },
+ addImage: function (id, config) {
+ self.fileManager.loadedImages[id] = config;
+ },
+ removeImage: function (id) {
+ delete self.fileManager.loadedImages[id];
+ },
+ getImageIdList: function () {
+ return $h.getObjectKeys(self.fileManager.loadedImages);
+ },
+ getImageCount: function () {
+ return self.fileManager.getImageIdList().length;
+ },
+ getId: function (file) {
+ return self._getFileId(file);
+ },
+ getIndex: function (id) {
+ return self.fileManager.getIdList().indexOf(id);
+ },
+ getThumb: function (id) {
+ var $thumb = null;
+ self._getThumbs().each(function () {
+ var $t = $(this);
+ if (self._getThumbFileId($t) === id) {
+ $thumb = $t;
+ }
+ });
+ return $thumb;
+ },
+ getThumbIndex: function ($thumb) {
+ var id = self._getThumbFileId($thumb);
+ return self.fileManager.getIndex(id);
+ },
+ getIdList: function () {
+ return $h.getObjectKeys(self.fileManager.stack);
+ },
+ getFile: function (id) {
+ return self.fileManager.stack[id] || null;
+ },
+ getFileName: function (id, fmt) {
+ var file = self.fileManager.getFile(id);
+ if (!file) {
+ return '';
+ }
+ return fmt ? (file.nameFmt || '') : file.name || '';
+ },
+ getFirstFile: function () {
+ var ids = self.fileManager.getIdList(), id = ids && ids.length ? ids[0] : null;
+ return self.fileManager.getFile(id);
+ },
+ setFile: function (id, file) {
+ if (self.fileManager.getFile(id)) {
+ self.fileManager.stack[id].file = file;
+ } else {
+ self.fileManager.add(file, id);
+ }
+ },
+ setProcessed: function (id) {
+ self.fileManager.filesProcessed.push(id);
+ },
+ getProgress: function () {
+ var total = self.fileManager.total(), filesProcessed = self.fileManager.filesProcessed.length;
+ if (!total) {
+ return 0;
+ }
+ return Math.ceil(filesProcessed / total * 100);
+
+ },
+ setProgress: function (id, pct) {
+ var f = self.fileManager.getFile(id);
+ if (!isNaN(pct) && f) {
+ f.progress = pct;
+ }
+ }
+ };
+ },
+ _setUploadData: function (fd, config) {
+ var self = this;
+ $.each(config, function (key, value) {
+ var param = self.uploadParamNames[key] || key;
+ if ($h.isArray(value)) {
+ fd.append(param, value[0], value[1]);
+ } else {
+ fd.append(param, value);
+ }
+ });
+ },
+ _initResumableUpload: function () {
+ var self = this, opts = self.resumableUploadOptions, logs = $h.logMessages, rm, fm = self.fileManager;
+ if (!self.enableResumableUpload) {
+ return;
+ }
+ if (opts.fallback !== false && typeof opts.fallback !== 'function') {
+ opts.fallback = function (s) {
+ s._log(logs.noResumableSupport);
+ s.enableResumableUpload = false;
+ };
+ }
+ if (!$h.hasResumableUploadSupport() && opts.fallback !== false) {
+ opts.fallback(self);
+ return;
+ }
+ if (!self.uploadUrl && self.enableResumableUpload) {
+ self._log(logs.noUploadUrl);
+ self.enableResumableUpload = false;
+ return;
+
+ }
+ opts.chunkSize = parseFloat(opts.chunkSize);
+ if (opts.chunkSize <= 0 || isNaN(opts.chunkSize)) {
+ self._log(logs.invalidChunkSize, {chunkSize: opts.chunkSize});
+ self.enableResumableUpload = false;
+ return;
+ }
+ rm = self.resumableManager = {
+ init: function (id, f, index) {
+ rm.logs = [];
+ rm.stack = [];
+ rm.error = '';
+ rm.id = id;
+ rm.file = f.file;
+ rm.fileName = f.name;
+ rm.fileIndex = index;
+ rm.completed = false;
+ rm.lastProgress = 0;
+ if (self.showPreview) {
+ rm.$thumb = fm.getThumb(id) || null;
+ rm.$progress = rm.$btnDelete = null;
+ if (rm.$thumb && rm.$thumb.length) {
+ rm.$progress = rm.$thumb.find('.file-thumb-progress');
+ rm.$btnDelete = rm.$thumb.find('.kv-file-remove');
+ }
+ }
+ rm.chunkSize = opts.chunkSize * self.bytesToKB;
+ rm.chunkCount = rm.getTotalChunks();
+ },
+ setAjaxError: function (jqXHR, textStatus, errorThrown, isTest) {
+ if (jqXHR.responseJSON && jqXHR.responseJSON.error) {
+ errorThrown = jqXHR.responseJSON.error.toString();
+ }
+ if (!isTest) {
+ rm.error = errorThrown;
+ }
+ if (opts.showErrorLog) {
+ self._log(logs.ajaxError, {
+ status: jqXHR.status,
+ error: errorThrown,
+ text: jqXHR.responseText || ''
+ });
+ }
+ },
+ reset: function () {
+ rm.stack = [];
+ rm.chunksProcessed = {};
+ },
+ setProcessed: function (status) {
+ var id = rm.id, msg, $thumb = rm.$thumb, $prog = rm.$progress, hasThumb = $thumb && $thumb.length,
+ params = {id: hasThumb ? $thumb.attr('id') : '', index: fm.getIndex(id), fileId: id}, tokens,
+ skipErrorsAndProceed = self.resumableUploadOptions.skipErrorsAndProceed;
+ rm.completed = true;
+ rm.lastProgress = 0;
+ if (hasThumb) {
+ $thumb.removeClass('file-uploading');
+ }
+ if (status === 'success') {
+ fm.uploadedSize += rm.file.size;
+ if (self.showPreview) {
+ self._setProgress(101, $prog);
+ self._setThumbStatus($thumb, 'Success');
+ self._initUploadSuccess(rm.chunksProcessed[id].data, $thumb);
+ }
+ fm.removeFile(id);
+ delete rm.chunksProcessed[id];
+ self._raise('fileuploaded', [params.id, params.index, params.fileId]);
+ if (fm.isProcessed()) {
+ self._setProgress(101);
+ }
+ } else {
+ if (status !== 'cancel') {
+ if (self.showPreview) {
+ self._setThumbStatus($thumb, 'Error');
+ self._setPreviewError($thumb, true);
+ self._setProgress(101, $prog, self.msgProgressError);
+ self._setProgress(101, self.$progress, self.msgProgressError);
+ self.cancelling = !skipErrorsAndProceed;
+ }
+ if (!self.$errorContainer.find('li[data-file-id="' + params.fileId + '"]').length) {
+ tokens = {file: rm.fileName, max: opts.maxRetries, error: rm.error};
+ msg = self.msgResumableUploadRetriesExceeded.setTokens(tokens);
+ $.extend(params, tokens);
+ self._showFileError(msg, params, 'filemaxretries');
+ if (skipErrorsAndProceed) {
+ fm.removeFile(id);
+ delete rm.chunksProcessed[id];
+ if (fm.isProcessed()) {
+ self._setProgress(101);
+ }
+ }
+ }
+ }
+ }
+ if (fm.isProcessed()) {
+ rm.reset();
+ }
+ },
+ check: function () {
+ var status = true;
+ $.each(rm.logs, function (index, value) {
+ if (!value) {
+ status = false;
+ return false;
+ }
+ });
+ },
+ processedResumables: function () {
+ var logs = rm.logs, i, count = 0;
+ if (!logs || !logs.length) {
+ return 0;
+ }
+ for (i = 0; i < logs.length; i++) {
+ if (logs[i] === true) {
+ count++;
+ }
+ }
+ return count;
+ },
+ getUploadedSize: function () {
+ var size = rm.processedResumables() * rm.chunkSize;
+ return size > rm.file.size ? rm.file.size : size;
+ },
+ getTotalChunks: function () {
+ var chunkSize = parseFloat(rm.chunkSize);
+ if (!isNaN(chunkSize) && chunkSize > 0) {
+ return Math.ceil(rm.file.size / chunkSize);
+ }
+ return 0;
+ },
+ getProgress: function () {
+ var chunksProcessed = rm.processedResumables(), total = rm.chunkCount;
+ if (total === 0) {
+ return 0;
+ }
+ return Math.ceil(chunksProcessed / total * 100);
+ },
+ checkAborted: function (intervalId) {
+ if (self._isAborted()) {
+ clearInterval(intervalId);
+ self.unlock();
+ }
+ },
+ upload: function () {
+ var ids = fm.getIdList(), flag = 'new', intervalId;
+ intervalId = setInterval(function () {
+ var id;
+ rm.checkAborted(intervalId);
+ if (flag === 'new') {
+ self.lock();
+ flag = 'processing';
+ id = ids.shift();
+ fm.initStats(id);
+ if (fm.stack[id]) {
+ rm.init(id, fm.stack[id], fm.getIndex(id));
+ rm.processUpload();
+ }
+ }
+ if (!fm.isPending(id) && rm.completed) {
+ flag = 'new';
+ }
+ if (fm.isProcessed()) {
+ var $initThumbs = self.$preview.find('.file-preview-initial');
+ if ($initThumbs.length) {
+ $h.addCss($initThumbs, $h.SORT_CSS);
+ self._initSortable();
+ }
+ clearInterval(intervalId);
+ self._clearFileInput();
+ self.unlock();
+ setTimeout(function () {
+ var data = self.previewCache.data;
+ if (data) {
+ self.initialPreview = data.content;
+ self.initialPreviewConfig = data.config;
+ self.initialPreviewThumbTags = data.tags;
+ }
+ self._raise('filebatchuploadcomplete', [
+ self.initialPreview,
+ self.initialPreviewConfig,
+ self.initialPreviewThumbTags,
+ self._getExtraData()
+ ]);
+ }, self.processDelay);
+ }
+ }, self.processDelay);
+ },
+ uploadResumable: function () {
+ var i, pool, tm = self.taskManager, total = rm.chunkCount;
+ pool = tm.addPool(rm.id);
+ for (i = 0; i < total; i++) {
+ rm.logs[i] = !!(rm.chunksProcessed[rm.id] && rm.chunksProcessed[rm.id][i]);
+ if (!rm.logs[i]) {
+ rm.pushAjax(i, 0);
+ }
+ }
+ pool.run(opts.maxThreads)
+ .done(function () {
+ rm.setProcessed('success');
+ })
+ .fail(function () {
+ rm.setProcessed(pool.cancelled ? 'cancel' : 'error');
+ });
+ },
+ processUpload: function () {
+ var fd, f, id = rm.id, fnBefore, fnSuccess, fnError, fnComplete, outData;
+ if (!opts.testUrl) {
+ rm.uploadResumable();
+ return;
+ }
+ fd = new FormData();
+ f = fm.stack[id];
+ self._setUploadData(fd, {
+ fileId: id,
+ fileName: f.fileName,
+ fileSize: f.size,
+ fileRelativePath: f.relativePath,
+ chunkSize: rm.chunkSize,
+ chunkCount: rm.chunkCount
+ });
+ fnBefore = function (jqXHR) {
+ outData = self._getOutData(fd, jqXHR);
+ self._raise('filetestbeforesend', [id, fm, rm, outData]);
+ };
+ fnSuccess = function (data, textStatus, jqXHR) {
+ outData = self._getOutData(fd, jqXHR, data);
+ var pNames = self.uploadParamNames, chunksUploaded = pNames.chunksUploaded || 'chunksUploaded',
+ params = [id, fm, rm, outData];
+ if (!data[chunksUploaded] || !$h.isArray(data[chunksUploaded])) {
+ self._raise('filetesterror', params);
+ } else {
+ if (!rm.chunksProcessed[id]) {
+ rm.chunksProcessed[id] = {};
+ }
+ $.each(data[chunksUploaded], function (key, index) {
+ rm.logs[index] = true;
+ rm.chunksProcessed[id][index] = true;
+ });
+ rm.chunksProcessed[id].data = data;
+ self._raise('filetestsuccess', params);
+ }
+ rm.uploadResumable();
+ };
+ fnError = function (jqXHR, textStatus, errorThrown) {
+ outData = self._getOutData(fd, jqXHR);
+ self._raise('filetestajaxerror', [id, fm, rm, outData]);
+ rm.setAjaxError(jqXHR, textStatus, errorThrown, true);
+ rm.uploadResumable();
+ };
+ fnComplete = function () {
+ self._raise('filetestcomplete', [id, fm, rm, self._getOutData(fd)]);
+ };
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex, opts.testUrl);
+ },
+ pushAjax: function (index, retry) {
+ var tm = self.taskManager, pool = tm.getPool(rm.id);
+ pool.addTask(pool.size() + 1, function (deferrer) {
+ // use fifo chunk stack
+ var arr = rm.stack.shift(), index;
+ index = arr[0];
+ if (!rm.chunksProcessed[rm.id] || !rm.chunksProcessed[rm.id][index]) {
+ rm.sendAjax(index, arr[1], deferrer);
+ } else {
+ self._log(logs.chunkQueueError, {index: index});
+ }
+ });
+ rm.stack.push([index, retry]);
+ },
+ sendAjax: function (index, retry, deferrer) {
+ var f, chunkSize = rm.chunkSize, id = rm.id, file = rm.file, $thumb = rm.$thumb,
+ msgs = $h.logMessages, $btnDelete = rm.$btnDelete, logError = function (msg, tokens) {
+ if (tokens) {
+ msg = msg.setTokens(tokens);
+ }
+ msg = msgs.resumableRequestError.setTokens({msg: msg});
+ self._log(msg);
+ deferrer.reject(msg);
+ };
+ if (rm.chunksProcessed[id] && rm.chunksProcessed[id][index]) {
+ return;
+ }
+ if (retry > opts.maxRetries) {
+ logError(msgs.resumableMaxRetriesReached, {n: opts.maxRetries});
+ rm.setProcessed('error');
+ return;
+ }
+ var fd, outData, fnBefore, fnSuccess, fnError, fnComplete, slice = file.slice ? 'slice' :
+ (file.mozSlice ? 'mozSlice' : (file.webkitSlice ? 'webkitSlice' : 'slice')),
+ blob = file[slice](chunkSize * index, chunkSize * (index + 1));
+ fd = new FormData();
+ f = fm.stack[id];
+ self._setUploadData(fd, {
+ chunkCount: rm.chunkCount,
+ chunkIndex: index,
+ chunkSize: chunkSize,
+ chunkSizeStart: chunkSize * index,
+ fileBlob: [blob, rm.fileName],
+ fileId: id,
+ fileName: rm.fileName,
+ fileRelativePath: f.relativePath,
+ fileSize: file.size,
+ retryCount: retry
+ });
+ if (rm.$progress && rm.$progress.length) {
+ rm.$progress.show();
+ }
+ fnBefore = function (jqXHR) {
+ outData = self._getOutData(fd, jqXHR);
+ if (self.showPreview) {
+ if (!$thumb.hasClass('file-preview-success')) {
+ self._setThumbStatus($thumb, 'Loading');
+ $h.addCss($thumb, 'file-uploading');
+ }
+ $btnDelete.attr('disabled', true);
+ }
+ self._raise('filechunkbeforesend', [id, index, retry, fm, rm, outData]);
+ };
+ fnSuccess = function (data, textStatus, jqXHR) {
+ if (self._isAborted()) {
+ logError(msgs.resumableAborting);
+ return;
+ }
+ outData = self._getOutData(fd, jqXHR, data);
+ var paramNames = self.uploadParamNames, chunkIndex = paramNames.chunkIndex || 'chunkIndex',
+ params = [id, index, retry, fm, rm, outData];
+ if (data.error) {
+ if (opts.showErrorLog) {
+ self._log(logs.retryStatus, {
+ retry: retry + 1,
+ filename: rm.fileName,
+ chunk: index
+ });
+ }
+ self._raise('filechunkerror', params);
+ rm.pushAjax(index, retry + 1);
+ rm.error = data.error;
+ logError(data.error);
+ } else {
+ rm.logs[data[chunkIndex]] = true;
+ if (!rm.chunksProcessed[id]) {
+ rm.chunksProcessed[id] = {};
+ }
+ rm.chunksProcessed[id][data[chunkIndex]] = true;
+ rm.chunksProcessed[id].data = data;
+ deferrer.resolve.call(null, data);
+ self._raise('filechunksuccess', params);
+ rm.check();
+ }
+ };
+ fnError = function (jqXHR, textStatus, errorThrown) {
+ if (self._isAborted()) {
+ logError(msgs.resumableAborting);
+ return;
+ }
+ outData = self._getOutData(fd, jqXHR);
+ rm.setAjaxError(jqXHR, textStatus, errorThrown);
+ self._raise('filechunkajaxerror', [id, index, retry, fm, rm, outData]);
+ rm.pushAjax(index, retry + 1); // push another task
+ logError(msgs.resumableRetryError, {n: retry - 1}); // resolve the current task
+ };
+ fnComplete = function () {
+ if (!self._isAborted()) {
+ self._raise('filechunkcomplete', [id, index, retry, fm, rm, self._getOutData(fd)]);
+ }
+ };
+ self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex);
+ }
+ };
+ rm.reset();
+ },
+ _initTemplateDefaults: function () {
+ var self = this, tMain1, tMain2, tPreview, tFileIcon, tClose, tCaption, tBtnDefault, tBtnLink, tBtnBrowse,
+ tModalMain, tModal, tProgress, tSize, tFooter, tActions, tActionDelete, tActionUpload, tActionDownload,
+ tActionZoom, tActionDrag, tIndicator, tTagBef, tTagBef1, tTagBef2, tTagAft, tGeneric, tHtml, tImage,
+ tText, tOffice, tGdocs, tVideo, tAudio, tFlash, tObject, tPdf, tOther, tStyle, tZoomCache, vDefaultDim,
+ tStats, tModalLabel, tDescClose, renderObject = function (type, mime) {
+ return '\n';
+ }, defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss();
+ tMain1 = '{preview}\n' +
+ '\n' +
+ '';
+ tMain2 = '{preview}\n\n\n' +
+ '{remove}\n{cancel}\n{upload}\n{browse}\n';
+ tPreview = '\n' +
+ ' {close}' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ '
\n' +
+ '
';
+ tClose = $h.closeButton('fileinput-remove');
+ tFileIcon = '';
+ // noinspection HtmlUnknownAttribute
+ tCaption = '\n';
+ //noinspection HtmlUnknownAttribute
+ tBtnDefault = '';
+ //noinspection HtmlUnknownTarget,HtmlUnknownAttribute
+ tBtnLink = '{icon} {label}';
+ //noinspection HtmlUnknownAttribute
+ tBtnBrowse = '{icon} {label}
';
+ tModalLabel = $h.MODAL_ID + 'Label';
+ tModalMain = '';
+ tModal = '\n' +
+ '
\n' +
+ ' \n' +
+ '
\n' +
+ '
\n' + '{prev} {next}\n' +
+ '
\n' +
+ '
\n' +
+ '
\n';
+ tDescClose = '';
+ tProgress = '\n' +
+ '
\n' +
+ ' {status}\n' +
+ '
\n' +
+ '
{stats}';
+ tStats = '' +
+ '{pendingTime} ' +
+ '{uploadSpeed}' +
+ '
';
+ tSize = ' ({sizeText})';
+ tFooter = '';
+ tActions = '\n' +
+ ' \n' +
+ '
\n' +
+ '{drag}\n' +
+ '';
+ //noinspection HtmlUnknownAttribute
+ tActionDelete = '\n';
+ tActionUpload = '';
+ tActionDownload = '{downloadIcon}';
+ tActionZoom = '';
+ tActionDrag = '{dragIcon}';
+ tIndicator = '{indicator}
';
+ tTagBef = '\n';
+ tTagBef2 = tTagBef + ' title="{caption}">
\n';
+ tTagAft = '
{footer}\n{zoomCache}
\n';
+ tGeneric = '{content}\n';
+ tStyle = ' {style}';
+ tHtml = renderObject('html', 'text/html');
+ tText = renderObject('text', 'text/plain;charset=UTF-8');
+ tPdf = renderObject('pdf', 'application/pdf');
+ tImage = '

\n';
+ tOffice = '
';
+ tGdocs = '
';
+ tVideo = '
\n';
+ tAudio = '
\n';
+ tFlash = '