text: /*! Widget: resizable - updated 6/26/2015 (v2.22.2) */
  /*jshint browser:true, jquery:true, unused:false */
  ;
  (function ($, window) {
  	'use strict';
  	var ts = $.tablesorter || {};
  
  	$.extend(ts.css, {
  		resizableContainer: 'tablesorter-resizable-container',
  		resizableHandle: 'tablesorter-resizable-handle',
  		resizableNoSelect: 'tablesorter-disableSelection',
  		resizableStorage: 'tablesorter-resizable'
  	});
  
  	// Add extra scroller css
  	$(function () {
  		var s = '<style>' +
  			'body.' + ts.css.resizableNoSelect + ' { -ms-user-select: none; -moz-user-select: -moz-none;' +
  			'-khtml-user-select: none; -webkit-user-select: none; user-select: none; }' +
  			'.' + ts.css.resizableContainer + ' { position: relative; height: 1px; }' +
  				// make handle z-index > than stickyHeader z-index, so the handle stays above sticky header
  			'.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px;' +
  			'top: 1px; cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
  			'</style>';
  		$(s).appendTo('body');
  	});
  
  	ts.resizable = {
  		init: function (c, wo) {
  			if (c.$table.hasClass('hasResizable')) {
  				return;
  			}
  			c.$table.addClass('hasResizable');
  
  			var noResize, $header, column, storedSizes, tmp,
  				$table = c.$table,
  				$parent = $table.parent(),
  				marginTop = parseInt($table.css('margin-top'), 10),
  
  			// internal variables
  				vars = wo.resizable_vars = {
  					useStorage: ts.storage && wo.resizable !== false,
  					$wrap: $parent,
  					mouseXPosition: 0,
  					$target: null,
  					$next: null,
  					overflow: $parent.css('overflow') === 'auto' ||
  					$parent.css('overflow') === 'scroll' ||
  					$parent.css('overflow-x') === 'auto' ||
  					$parent.css('overflow-x') === 'scroll',
  					storedSizes: []
  				};
  
  			// set default widths
  			ts.resizableReset(c.table, true);
  
  			// now get measurements!
  			vars.tableWidth = $table.width();
  			// attempt to autodetect
  			vars.fullWidth = Math.abs($parent.width() - vars.tableWidth) < 20;
  
  			/*
  			 // Hacky method to determine if table width is set to 'auto'
  			 // http://stackoverflow.com/a/20892048/145346
  			 if ( !vars.fullWidth ) {
  			 tmp = $table.width();
  			 $header = $table.wrap('<span>').parent(); // temp variable
  			 storedSizes = parseInt( $table.css( 'margin-left' ), 10 ) || 0;
  			 $table.css( 'margin-left', storedSizes + 50 );
  			 vars.tableWidth = $header.width() > tmp ? 'auto' : tmp;
  			 $table.css( 'margin-left', storedSizes ? storedSizes : '' );
  			 $header = null;
  			 $table.unwrap('<span>');
  			 }
  			 */
  
  			if (vars.useStorage && vars.overflow) {
  				// save table width
  				ts.storage(c.table, 'tablesorter-table-original-css-width', vars.tableWidth);
  				tmp = ts.storage(c.table, 'tablesorter-table-resized-width') || 'auto';
  				ts.resizable.setWidth($table, tmp, true);
  			}
  			wo.resizable_vars.storedSizes = storedSizes = ( vars.useStorage ?
  				ts.storage(c.table, ts.css.resizableStorage) :
  				[] ) || [];
  			ts.resizable.setWidths(c, wo, storedSizes);
  			ts.resizable.updateStoredSizes(c, wo);
  
  			wo.$resizable_container = $('<div class="' + ts.css.resizableContainer + '">')
  				.css({top: marginTop})
  				.insertBefore($table);
  			// add container
  			for (column = 0; column < c.columns; column++) {
  				$header = c.$headerIndexed[column];
  				tmp = ts.getColumnData(c.table, c.headers, column);
  				noResize = ts.getData($header, tmp, 'resizable') === 'false';
  				if (!noResize) {
  					$('<div class="' + ts.css.resizableHandle + '">')
  						.appendTo(wo.$resizable_container)
  						.attr({
  							'data-column': column,
  							'unselectable': 'on'
  						})
  						.data('header', $header)
  						.bind('selectstart', false);
  				}
  			}
  			$table.one('tablesorter-initialized', function () {
  				ts.resizable.setHandlePosition(c, wo);
  				ts.resizable.bindings(this.config, this.config.widgetOptions);
  			});
  		},
  
  		updateStoredSizes: function (c, wo) {
  			var column, $header,
  				len = c.columns,
  				vars = wo.resizable_vars;
  			vars.storedSizes = [];
  			for (column = 0; column < len; column++) {
  				$header = c.$headerIndexed[column];
  				vars.storedSizes[column] = $header.is(':visible') ? $header.width() : 0;
  			}
  		},
  
  		setWidth: function ($el, width, overflow) {
  			// overflow tables need min & max width set as well
  			$el.css({
  				'width': width,
  				'min-width': overflow ? width : '',
  				'max-width': overflow ? width : ''
  			});
  		},
  
  		setWidths: function (c, wo, storedSizes) {
  			var column, $temp,
  				vars = wo.resizable_vars,
  				$extra = $(c.namespace + '_extra_headers'),
  				$col = c.$table.children('colgroup').children('col');
  			storedSizes = storedSizes || vars.storedSizes || [];
  			// process only if table ID or url match
  			if (storedSizes.length) {
  				for (column = 0; column < c.columns; column++) {
  					// set saved resizable widths
  					ts.resizable.setWidth(c.$headerIndexed[column], storedSizes[column], vars.overflow);
  					if ($extra.length) {
  						// stickyHeaders needs to modify min & max width as well
  						$temp = $extra.eq(column).add($col.eq(column));
  						ts.resizable.setWidth($temp, storedSizes[column], vars.overflow);
  					}
  				}
  				$temp = $(c.namespace + '_extra_table');
  				if ($temp.length && !ts.hasWidget(c.table, 'scroller')) {
  					ts.resizable.setWidth($temp, c.$table.outerWidth(), vars.overflow);
  				}
  			}
  		},
  
  		setHandlePosition: function (c, wo) {
  			var startPosition,
  				hasScroller = ts.hasWidget(c.table, 'scroller'),
  				tableHeight = c.$table.height(),
  				$handles = wo.$resizable_container.children(),
  				handleCenter = Math.floor($handles.width() / 2);
  
  			if (hasScroller) {
  				tableHeight = 0;
  				c.$table.closest('.' + ts.css.scrollerWrap).children().each(function () {
  					var $this = $(this);
  					// center table has a max-height set
  					tableHeight += $this.filter('[style*="height"]').length ? $this.height() : $this.children('table').height();
  				});
  			}
  			// subtract out table left position from resizable handles. Fixes #864
  			startPosition = c.$table.position().left;
  			$handles.each(function () {
  				var $this = $(this),
  					column = parseInt($this.attr('data-column'), 10),
  					columns = c.columns - 1,
  					$header = $this.data('header');
  				if (!$header) {
  					return;
  				} // see #859
  				if (!$header.is(':visible')) {
  					$this.hide();
  				}
  				else if (column < columns || column === columns && wo.resizable_addLastColumn) {
  					$this.css({
  						display: 'inline-block',
  						height: tableHeight,
  						left: $header.position().left - startPosition + $header.outerWidth() - handleCenter
  					});
  				}
  			});
  		},
  
  		// prevent text selection while dragging resize bar
  		toggleTextSelection: function (c, toggle) {
  			var namespace = c.namespace + 'tsresize';
  			c.widgetOptions.resizable_vars.disabled = toggle;
  			$('body').toggleClass(ts.css.resizableNoSelect, toggle);
  			if (toggle) {
  				$('body')
  					.attr('unselectable', 'on')
  					.bind('selectstart' + namespace, false);
  			}
  			else {
  				$('body')
  					.removeAttr('unselectable')
  					.unbind('selectstart' + namespace);
  			}
  		},
  
  		bindings: function (c, wo) {
  			var namespace = c.namespace + 'tsresize';
  			wo.$resizable_container.children().bind('mousedown', function (event) {
  				// save header cell and mouse position
  				var column,
  					vars = wo.resizable_vars,
  					$extras = $(c.namespace + '_extra_headers'),
  					$header = $(event.target).data('header');
  
  				column = parseInt($header.attr('data-column'), 10);
  				vars.$target = $header = $header.add($extras.filter('[data-column="' + column + '"]'));
  				vars.target = column;
  
  				// if table is not as wide as it's parent, then resize the table
  				vars.$next = event.shiftKey || wo.resizable_targetLast ?
  					$header.parent().children().not('.resizable-false').filter(':last') :
  					$header.nextAll(':not(.resizable-false)').eq(0);
  
  				column = parseInt(vars.$next.attr('data-column'), 10);
  				vars.$next = vars.$next.add($extras.filter('[data-column="' + column + '"]'));
  				vars.next = column;
  
  				vars.mouseXPosition = event.pageX;
  				ts.resizable.updateStoredSizes(c, wo);
  				ts.resizable.toggleTextSelection(c, true);
  			});
  
  			$(document)
  				.bind('mousemove' + namespace, function (event) {
  					var vars = wo.resizable_vars;
  					// ignore mousemove if no mousedown
  					if (!vars.disabled || vars.mouseXPosition === 0 || !vars.$target) {
  						return;
  					}
  					if (wo.resizable_throttle) {
  						clearTimeout(vars.timer);
  						vars.timer = setTimeout(function () {
  							ts.resizable.mouseMove(c, wo, event);
  						}, isNaN(wo.resizable_throttle) ? 5 : wo.resizable_throttle);
  					}
  					else {
  						ts.resizable.mouseMove(c, wo, event);
  					}
  				})
  				.bind('mouseup' + namespace, function () {
  					if (!wo.resizable_vars.disabled) {
  						return;
  					}
  					ts.resizable.toggleTextSelection(c, false);
  					ts.resizable.stopResize(c, wo);
  					ts.resizable.setHandlePosition(c, wo);
  				});
  
  			// resizeEnd event triggered by scroller widget
  			$(window).bind('resize' + namespace + ' resizeEnd' + namespace, function () {
  				ts.resizable.setHandlePosition(c, wo);
  			});
  
  			// right click to reset columns to default widths
  			c.$table
  				.bind('columnUpdate' + namespace, function () {
  					ts.resizable.setHandlePosition(c, wo);
  				})
  				.find('thead:first')
  				.add($(c.namespace + '_extra_table').find('thead:first'))
  				.bind('contextmenu' + namespace, function () {
  					// $.isEmptyObject() needs jQuery 1.4+; allow right click if already reset
  					var allowClick = wo.resizable_vars.storedSizes.length === 0;
  					ts.resizableReset(c.table);
  					ts.resizable.setHandlePosition(c, wo);
  					wo.resizable_vars.storedSizes = [];
  					return allowClick;
  				});
  
  		},
  
  		mouseMove: function (c, wo, event) {
  			if (wo.resizable_vars.mouseXPosition === 0 || !wo.resizable_vars.$target) {
  				return;
  			}
  			// resize columns
  			var column,
  				total = 0,
  				vars = wo.resizable_vars,
  				$next = vars.$next,
  				tar = vars.storedSizes[vars.target],
  				leftEdge = event.pageX - vars.mouseXPosition;
  			if (vars.overflow) {
  				if (tar + leftEdge > 0) {
  					vars.storedSizes[vars.target] += leftEdge;
  					ts.resizable.setWidth(vars.$target, vars.storedSizes[vars.target], true);
  					// update the entire table width
  					for (column = 0; column < c.columns; column++) {
  						total += vars.storedSizes[column];
  					}
  					ts.resizable.setWidth(c.$table.add($(c.namespace + '_extra_table')), total);
  				}
  				if (!$next.length) {
  					// if expanding right-most column, scroll the wrapper
  					vars.$wrap[0].scrollLeft = c.$table.width();
  				}
  			}
  			else if (vars.fullWidth) {
  				vars.storedSizes[vars.target] += leftEdge;
  				vars.storedSizes[vars.next] -= leftEdge;
  				ts.resizable.setWidths(c, wo);
  			}
  			else {
  				vars.storedSizes[vars.target] += leftEdge;
  				ts.resizable.setWidths(c, wo);
  			}
  			vars.mouseXPosition = event.pageX;
  			// dynamically update sticky header widths
  			c.$table.trigger('stickyHeadersUpdate');
  		},
  
  		stopResize: function (c, wo) {
  			var vars = wo.resizable_vars;
  			ts.resizable.updateStoredSizes(c, wo);
  			if (vars.useStorage) {
  				// save all column widths
  				ts.storage(c.table, ts.css.resizableStorage, vars.storedSizes);
  				ts.storage(c.table, 'tablesorter-table-resized-width', c.$table.width());
  			}
  			vars.mouseXPosition = 0;
  			vars.$target = vars.$next = null;
  			// will update stickyHeaders, just in case, see #912
  			c.$table.trigger('stickyHeadersUpdate');
  		}
  	};
  
  	// this widget saves the column widths if
  	// $.tablesorter.storage function is included
  	// **************************
  	ts.addWidget({
  		id: 'resizable',
  		priority: 40,
  		options: {
  			resizable: true, // save column widths to storage
  			resizable_addLastColumn: false,
  			resizable_widths: [],
  			resizable_throttle: false, // set to true (5ms) or any number 0-10 range
  			resizable_targetLast: false,
  			resizable_fullWidth: null
  		},
  		init: function (table, thisWidget, c, wo) {
  			ts.resizable.init(c, wo);
  		},
  		remove: function (table, c, wo, refreshing) {
  			if (wo.$resizable_container) {
  				var namespace = c.namespace + 'tsresize';
  				c.$table.add($(c.namespace + '_extra_table'))
  					.removeClass('hasResizable')
  					.children('thead')
  					.unbind('contextmenu' + namespace);
  
  				wo.$resizable_container.remove();
  				ts.resizable.toggleTextSelection(c, false);
  				ts.resizableReset(table, refreshing);
  				$(document).unbind('mousemove' + namespace + ' mouseup' + namespace);
  			}
  		}
  	});
  
  	ts.resizableReset = function (table, refreshing) {
  		$(table).each(function () {
  			var index, $t,
  				c = this.config,
  				wo = c && c.widgetOptions,
  				vars = wo.resizable_vars;
  			if (table && c && c.$headerIndexed.length) {
  				// restore the initial table width
  				if (vars.overflow && vars.tableWidth) {
  					ts.resizable.setWidth(c.$table, vars.tableWidth, true);
  					if (vars.useStorage) {
  						ts.storage(table, 'tablesorter-table-resized-width', 'auto');
  					}
  				}
  				for (index = 0; index < c.columns; index++) {
  					$t = c.$headerIndexed[index];
  					if (wo.resizable_widths && wo.resizable_widths[index]) {
  						ts.resizable.setWidth($t, wo.resizable_widths[index], vars.overflow);
  					}
  					else if (!$t.hasClass('resizable-false')) {
  						// don't clear the width of any column that is not resizable
  						ts.resizable.setWidth($t, '', vars.overflow);
  					}
  				}
  
  				// reset stickyHeader widths
  				c.$table.trigger('stickyHeadersUpdate');
  				if (ts.storage && !refreshing) {
  					ts.storage(this, ts.css.resizableStorage, {});
  				}
  			}
  		});
  	};
  
  })(jQuery, window);
  