// version 1.6.2
// http://welcome.totheinter.net/columnizer-jquery-plugin/
// created by: Adam Wulf @adamwulf, adam.wulf@gmail.com

(function($){

 $.fn.columnize = function(options) {
	this.cols  =[]; 
	this.offset= 0; 
	this.before=[];
	this.lastOther=0;  
	this.prevMax =0;
	this.debug=0; 
	this.setColumnStart =null;
	this.elipsisText='';

	var defaults = {
		// default width of columns
		width: 400,
		// optional # of columns instead of width
		columns : false,
		// true to build columns once regardless of window resize
		// false to rebuild when content box changes bounds
		buildOnce : false,
		// an object with options if the text should overflow
		// it's container if it can't fit within a specified height
		overflow : false,
		// this function is called after content is columnized
		doneFunc : function(){},
		// if the content should be columnized into a 
		// container node other than it's own node
		target : false,
		// re-columnizing when images reload might make things
		// run slow. so flip this to true if it's causing delays
		ignoreImageLoading : true,
		// should columns float left or right
		columnFloat : "left",
		// ensure the last column is never the tallest column
		lastNeverTallest : false,
		// (int) the minimum number of characters to jump when splitting
		// text nodes. smaller numbers will result in higher accuracy
		// column widths, but will take slightly longer
		accuracy : false,
		// false to round down column widths (for compatibility)
		// true to conserve all decimals in the column widths
		precise : false,
		// don't automatically layout columns, only use manual columnbreak
		manualBreaks : false,
		// previx for all the CSS classes used by this plugin
		// default to empty string for backwards compatibility
		cssClassPrefix : "",
		elipsisText:'...',
		debug:0
	};
	options = $.extend(defaults, options);

	if(typeof(options.width) == "string"){
		options.width = parseInt(options.width,10);
		if(isNaN(options.width)){
			options.width = defaults.width;
		}
	}
	if(typeof options.setColumnStart== 'function') {
		this.setColumnStart=options.setColumnStart;
	}
	if(typeof options.elipsisText== 'string') {
		this.elipsisText=options.elipsisText;
	}
	if(options.debug) { // assert is off by default
		this.debug=options.debug;
	}
	if(!options.setWidth) {
		if (options.precise) {
			options.setWidth = function (numCols) {
				return 100 / numCols;
			};
		} else {
			options.setWidth = function (numCols) {
				return Math.floor(100 / numCols);
			};
		}
	}
	
	/**
	 * appending a text node to a <table> will
	 * cause a jquery crash.
	 * so wrap all append() calls and revert to
	 * a simple appendChild() in case it fails
	 */
	function appendSafe($target, $elem){
		try{
			$target.append($elem);
		}catch(e){
			$target[0].appendChild($elem[0]);
		}
	}

    return this.each(function() {
		var $inBox = options.target ? $(options.target) : $(this);
		var maxHeight = $(this).height();
		var $cache = $('<div></div>'); // this is where we'll put the real content
		var lastWidth = 0;
		var columnizing = false;
		var manualBreaks = options.manualBreaks;
		var cssClassPrefix = defaults.cssClassPrefix;
		if(typeof(options.cssClassPrefix) == "string"){
			cssClassPrefix = options.cssClassPrefix;
		}


		var adjustment = 0;

		appendSafe($cache, $(this).contents().clone(true));

		// images loading after dom load
		// can screw up the column heights,
		// so recolumnize after images load
		if(!options.ignoreImageLoading && !options.target){
			if(!$inBox.data("imageLoaded")){
				$inBox.data("imageLoaded", true);
				if($(this).find("img").length > 0){
					// only bother if there are
					// actually images...
					var func = function($inBox,$cache){ return function(){
							if(!$inBox.data("firstImageLoaded")){
								$inBox.data("firstImageLoaded", "true");
								appendSafe($inBox.empty(), $cache.children().clone(true));
								$inBox.columnize(options);
							}
						};
					}($(this), $cache);
					$(this).find("img").one("load", func);
					$(this).find("img").one("abort", func);
					return;
				}
			}
		}

		$inBox.empty();

		columnizeIt();

		if(!options.buildOnce){
			$(window).resize(function() {
				if(!options.buildOnce){
					if($inBox.data("timeout")){
						clearTimeout($inBox.data("timeout"));
					}
					$inBox.data("timeout", setTimeout(columnizeIt, 200));
				}
			});
		}

		function prefixTheClassName(className, withDot){
			var dot = withDot ? "." : "";
			if(cssClassPrefix.length){
				return dot + cssClassPrefix + "-" + className;
			}
			return dot + className;
		}

		/**
		 * this fuction builds as much of a column as it can without
		 * splitting nodes in half. If the last node in the new column
		 * is a text node, then it will try to split that text node. otherwise
		 * it will leave the node in $pullOutHere and return with a height
		 * smaller than targetHeight.
		 * 
         * Returns a boolean on whether we did some splitting successfully at a text point
         * (so we know we don't need to split a real element). return false if the caller should
         * split a node if possible to end this column.
		 *
		 * @param putInHere, the jquery node to put elements into for the current column
		 * @param $pullOutHere, the jquery node to pull elements out of (uncolumnized html)
		 * @param $parentColumn, the jquery node for the currently column that's being added to
		 * @param targetHeight, the ideal height for the column, get as close as we can to this height
		 */
		function columnize($putInHere, $pullOutHere, $parentColumn, targetHeight){
			//
			// add as many nodes to the column as we can,
			// but stop once our height is too tall
			while((manualBreaks || $parentColumn.height() < targetHeight) &&
				$pullOutHere[0].childNodes.length){
				var node = $pullOutHere[0].childNodes[0];
				//
				// Because we're not cloning, jquery will actually move the element"
				// http://welcome.totheinter.net/2009/03/19/the-undocumented-life-of-jquerys-append/
				if($(node).find(prefixTheClassName("columnbreak", true)).length){
					//
					// our column is on a column break, so just end here
					return;
				}
				if($(node).hasClass(prefixTheClassName("columnbreak"))){
					//
					// our column is on a column break, so just end here
					return;
				}
				appendSafe($putInHere, $(node));
			}
			if($putInHere[0].childNodes.length === 0) return;

			// now we're too tall, so undo the last one
			var kids = $putInHere[0].childNodes;
			var lastKid = kids[kids.length-1];
			$putInHere[0].removeChild(lastKid);
			var $item = $(lastKid);

			// now lets try to split that last node
			// to fit as much of it as we can into this column
			if($item[0].nodeType == 3){
				// it's a text node, split it up
				var oText = $item[0].nodeValue;
				var counter2 = options.width / 18;
				if(options.accuracy)
				counter2 = options.accuracy;
				var columnText;
				var latestTextNode = null;
				while($parentColumn.height() < targetHeight && oText.length){
					//
					// it's been brought up that this won't work for chinese
					// or other languages that don't have the same use of whitespace
					// as english. This will need to be updated in the future
					// to better handle non-english languages.
					//
					// https://github.com/adamwulf/Columnizer-jQuery-Plugin/issues/124
					var indexOfSpace = oText.indexOf(' ', counter2);
					if (indexOfSpace != -1) {
						columnText = oText.substring(0, indexOfSpace);
					} else {
						columnText = oText;
					}
					latestTextNode = document.createTextNode(columnText);
					appendSafe($putInHere, $(latestTextNode));

					if(oText.length > counter2 && indexOfSpace != -1){
						oText = oText.substring(indexOfSpace);
					}else{
						oText = "";
					}
				}
				if($parentColumn.height() >= targetHeight && latestTextNode !== null){
					// too tall :(
					$putInHere[0].removeChild(latestTextNode);
					oText = latestTextNode.nodeValue + oText;
				}
				if(oText.length){
					$item[0].nodeValue = oText;
				}else{
					return false; // we ate the whole text node, move on to the next node
				}
			}

			if($pullOutHere.contents().length){
				$pullOutHere.prepend($item);
			}else{
				appendSafe($pullOutHere, $item);
			}

			return $item[0].nodeType == 3;
		}

		/**
		 * Split up an element, which is more complex than splitting text. We need to create 
		 * two copies of the element with it's contents divided between each
		 */
		function split($putInHere, $pullOutHere, $parentColumn, targetHeight){
			if($putInHere.contents(":last").find(prefixTheClassName("columnbreak", true)).length){
				//
				// our column is on a column break, so just end here
				return;
			}
			if($putInHere.contents(":last").hasClass(prefixTheClassName("columnbreak"))){
				//
				// our column is on a column break, so just end here
				return;
			}
			if($pullOutHere.contents().length){
				var $cloneMe = $pullOutHere.contents(":first");
				//
				// make sure we're splitting an element
				if( typeof $cloneMe.get(0) == 'undefined' || $cloneMe.get(0).nodeType != 1 ) return;

				//
				// clone the node with all data and events
				var $clone = $cloneMe.clone(true);
				//
				// need to support both .prop and .attr if .prop doesn't exist.
				// this is for backwards compatibility with older versions of jquery.
				if($cloneMe.hasClass(prefixTheClassName("columnbreak"))){
					//
					// ok, we have a columnbreak, so add it into
					// the column and exit
					appendSafe($putInHere, $clone);
					$cloneMe.remove();
				}else if (manualBreaks){
					// keep adding until we hit a manual break
					appendSafe($putInHere, $clone);
					$cloneMe.remove();
				}else if($clone.get(0).nodeType == 1 && !$clone.hasClass(prefixTheClassName("dontend"))){
					appendSafe($putInHere, $clone);
					if($clone.is("img") && $parentColumn.height() < targetHeight + 20){
						//
						// we can't split an img in half, so just add it
						// to the column and remove it from the pullOutHere section
						$cloneMe.remove();
					}else if($cloneMe.hasClass(prefixTheClassName("dontsplit")) && $parentColumn.height() < targetHeight + 20){
						//
						// pretty close fit, and we're not allowed to split it, so just
						// add it to the column, remove from pullOutHere, and be done
						$cloneMe.remove();
					}else if($clone.is("img") || $cloneMe.hasClass(prefixTheClassName("dontsplit"))){
						//
						// it's either an image that's too tall, or an unsplittable node
						// that's too tall. leave it in the pullOutHere and we'll add it to the 
						// next column
						$clone.remove();
					}else{
						//
						// ok, we're allowed to split the node in half, so empty out
						// the node in the column we're building, and start splitting
						// it in half, leaving some of it in pullOutHere
						$clone.empty();
						if(!columnize($clone, $cloneMe, $parentColumn, targetHeight)){
							// this node may still have non-text nodes to split
							// add the split class and then recur
							$cloneMe.addClass(prefixTheClassName("split"));
							
							//if this node was ol element, the child should continue the number ordering
							if($cloneMe.get(0).tagName == 'OL'){
								var startWith = $clone.get(0).childElementCount + $clone.get(0).start;
								$cloneMe.attr('start',startWith+1);
							}
							
							if($cloneMe.children().length){
								split($clone, $cloneMe, $parentColumn, targetHeight);
							}
						}else{
							// this node only has text node children left, add the
							// split class and move on.
							$cloneMe.addClass(prefixTheClassName("split"));
						}
						if($clone.get(0).childNodes.length === 0){
							// it was split, but nothing is in it :(
							$clone.remove();
							$cloneMe.removeClass(prefixTheClassName("split"));
						}else if($clone.get(0).childNodes.length == 1){
                            // was the only child node a text node w/ whitespace?
                            var onlyNode = $clone.get(0).childNodes[0];
                            if(onlyNode.nodeType == 3){
                                // text node
                                var whitespace = /\s/;
                                var str = onlyNode.nodeValue;
                                if(whitespace.test(str)){
                                    // yep, only a whitespace textnode
                                    $clone.remove();
									$cloneMe.removeClass(prefixTheClassName("split"));
                                }
                            }
                        }
					}
				}
			}
		}


		function singleColumnizeIt() {
			if ($inBox.data("columnized") && $inBox.children().length == 1) {
				return;
			}
			$inBox.data("columnized", true);
			$inBox.data("columnizing", true);

			$inBox.empty();
			$inBox.append($("<div class='"
				+ prefixTheClassName("first") + " "
				+ prefixTheClassName("last") + " "
				+ prefixTheClassName("column") + " "
				+ "' style='width:100%; float: " + options.columnFloat + ";'></div>")); //"
			$col = $inBox.children().eq($inBox.children().length-1);
			$destroyable = $cache.clone(true);
			if(options.overflow){
				targetHeight = options.overflow.height;
				columnize($col, $destroyable, $col, targetHeight);
				// make sure that the last item in the column isn't a "dontend"
				if(!$destroyable.contents().find(":first-child").hasClass(prefixTheClassName("dontend"))){
					split($col, $destroyable, $col, targetHeight);
				}

				while($col.contents(":last").length && checkDontEndColumn($col.contents(":last").get(0))){
					var $lastKid = $col.contents(":last");
					$lastKid.remove();
					$destroyable.prepend($lastKid);
				}

				var html = "";
				var div = document.createElement('DIV');
				while($destroyable[0].childNodes.length > 0){
					var kid = $destroyable[0].childNodes[0];
					if(kid.attributes){
						for(var i=0;i<kid.attributes.length;i++){
							if(kid.attributes[i].nodeName.indexOf("jQuery") === 0){
								kid.removeAttribute(kid.attributes[i].nodeName);
							}
						}
					}
					div.innerHTML = "";
					div.appendChild($destroyable[0].childNodes[0]);
					html += div.innerHTML;
				}
				var overflow = $(options.overflow.id)[0];
				overflow.innerHTML = html;

			}else{
				appendSafe($col, $destroyable.contents());
			}
			$inBox.data("columnizing", false);

			if(options.overflow && options.overflow.doneFunc){
				options.overflow.doneFunc();
			}
			options.doneFunc();
		}

		/**
		 * returns true if the input dom node
		 * should not end a column.
		 * returns false otherwise
		 */
		function checkDontEndColumn(dom){
			if(dom.nodeType == 3){
				// text node. ensure that the text
				// is not 100% whitespace
				if(/^\s+$/.test(dom.nodeValue)){
						//
						// ok, it's 100% whitespace,
						// so we should return checkDontEndColumn
						// of the inputs previousSibling
						if(!dom.previousSibling) return false;
					return checkDontEndColumn(dom.previousSibling);
				}
				return false;
			}
			if(dom.nodeType != 1) return false;
			if($(dom).hasClass(prefixTheClassName("dontend"))) return true;
			if(dom.childNodes.length === 0) return false;
			return checkDontEndColumn(dom.childNodes[dom.childNodes.length-1]);
		}

		function columnizeIt() {
			//reset adjustment var
			adjustment = 0;
			if(lastWidth == $inBox.width()) return;
			lastWidth = $inBox.width();

			var numCols = Math.round($inBox.width() / options.width);
			var optionWidth = options.width;
			var optionHeight = options.height;
			if(options.columns) numCols = options.columns;
			if(manualBreaks){
				numCols = $cache.find(prefixTheClassName("columnbreak", true)).length + 1;
				optionWidth = false;
			}

//			if ($inBox.data("columnized") && numCols == $inBox.children().length) {
//				return;
//			}
			if(numCols <= 1){
				return singleColumnizeIt();
			}
			if($inBox.data("columnizing")) return;
			$inBox.data("columnized", true);
			$inBox.data("columnizing", true);

			$inBox.empty();
			$inBox.append($("<div style='width:" + options.setWidth(numCols) + "%; float: " + options.columnFloat + ";'></div>")); //"
			$col = $inBox.children(":last");
			appendSafe($col, $cache.clone());
			maxHeight = $col.height();
			$inBox.empty();

			var targetHeight = maxHeight / numCols;
			var firstTime = true;
			var maxLoops = 3;
			var scrollHorizontally = false;
			if(options.overflow){
				maxLoops = 1;
				targetHeight = options.overflow.height;
			}else if(optionHeight && optionWidth){
				maxLoops = 1;
				targetHeight = optionHeight;
				scrollHorizontally = true;
			}

			//
			// We loop as we try and workout a good height to use. We know it initially as an average 
			// but if the last column is higher than the first ones (which can happen, depending on split
			// points) we need to raise 'adjustment'. We try this over a few iterations until we're 'solid'.
			//
			// also, lets hard code the max loops to 20. that's /a lot/ of loops for columnizer,
			// and should keep run aways in check. if somehow someone has content combined with
			// options that would cause an infinite loop, then this'll definitely stop it.
			for(var loopCount=0;loopCount<maxLoops && loopCount<20;loopCount++){
				$inBox.empty();
				var $destroyable, className, $col, $lastKid;
				try{
					$destroyable = $cache.clone(true);
				}catch(e){
					// jquery in ie6 can't clone with true
					$destroyable = $cache.clone();
				}
				$destroyable.css("visibility", "hidden");
				// create the columns
				for (var i = 0; i < numCols; i++) {
					/* create column */
					className = (i === 0) ? prefixTheClassName("first") : "";
					className += " " + prefixTheClassName("column");
					className = (i == numCols - 1) ? (prefixTheClassName("last") + " " + className) : className;
					$inBox.append($("<div class='" + className + "' style='width:" + options.setWidth(numCols) + "%; float: " + options.columnFloat + ";'></div>")); //"
				}

				// fill all but the last column (unless overflowing)
				i = 0;
				while(i < numCols - (options.overflow ? 0 : 1) || scrollHorizontally && $destroyable.contents().length){
					if($inBox.children().length <= i){
						// we ran out of columns, make another
						$inBox.append($("<div class='" + className + "' style='width:" + options.setWidth(numCols) + "%; float: " + options.columnFloat + ";'></div>")); //"
					}
					$col = $inBox.children().eq(i);
					if(scrollHorizontally){
						$col.width(optionWidth + "px");
					}
					columnize($col, $destroyable, $col, targetHeight);
					// make sure that the last item in the column isn't a "dontend"
					split($col, $destroyable, $col, targetHeight);

					while($col.contents(":last").length && checkDontEndColumn($col.contents(":last").get(0))){
						$lastKid = $col.contents(":last");
						$lastKid.remove();
						$destroyable.prepend($lastKid);
					}
					i++;

					//
					// https://github.com/adamwulf/Columnizer-jQuery-Plugin/issues/47
					//
					// check for infinite loop.
					//
					// this could happen when a dontsplit or dontend item is taller than the column
					// we're trying to build, and its never actually added to a column.
					//
					// this results in empty columns being added with the dontsplit item
					// perpetually waiting to get put into a column. lets force the issue here
					if($col.contents().length === 0 && $destroyable.contents().length){
						//
						// ok, we're building zero content columns. this'll happen forever
						// since nothing can ever get taken out of destroyable.
						//
						// to fix, lets put 1 item from destroyable into the empty column
						// before we iterate
						$col.append($destroyable.contents(":first"));
					}else if(i == numCols - (options.overflow ? 0 : 1) && !options.overflow){
						//
						// ok, we're about to exit the while loop because we're done with all
						// columns except the last column.
						//
						// if $destroyable still has columnbreak nodes in it, then we need to keep
						// looping and creating more columns.
						if($destroyable.find(prefixTheClassName("columnbreak", true)).length){
							numCols ++;
						}
					}
				}
				if(options.overflow && !scrollHorizontally){
					var IE6 = false;
					/*@cc_on 
					@if (@_jscript_version < 5.7)
						IE6 = true;
					@end
					@*/
					var IE7 = (document.all) && (navigator.appVersion.indexOf("MSIE 7.") != -1);
					if(IE6 || IE7){
						var html = "";
						var div = document.createElement('DIV');
						while($destroyable[0].childNodes.length > 0){
							var kid = $destroyable[0].childNodes[0];
							for(i=0;i<kid.attributes.length;i++){
								if(kid.attributes[i].nodeName.indexOf("jQuery") === 0){
									kid.removeAttribute(kid.attributes[i].nodeName);
								}
							}
							div.innerHTML = "";
							div.appendChild($destroyable[0].childNodes[0]);
							html += div.innerHTML;
						}
						var overflow = $(options.overflow.id)[0];
						overflow.innerHTML = html;
					}else{
						$(options.overflow.id).empty().append($destroyable.contents().clone(true));
					}
				}else if(!scrollHorizontally){
					// the last column in the series
					$col = $inBox.children().eq($inBox.children().length-1);
					$destroyable.contents().each( function() {
						$col.append( $(this) );
					});
					var afterH = $col.height();
					var diff = afterH - targetHeight;
					var totalH = 0;
					var min = 10000000;
					var max = 0;
					var lastIsMax = false;
					var numberOfColumnsThatDontEndInAColumnBreak = 0;
					$inBox.children().each(function($inBox){ return function($item){
						var $col = $inBox.children().eq($item);
						var endsInBreak = $col.children(":last").find(prefixTheClassName("columnbreak", true)).length;
						if(!endsInBreak){
							var h = $col.height();
							lastIsMax = false;
							totalH += h;
							if(h > max) {
								max = h;
								lastIsMax = true;
							}
							if(h < min) min = h;
							numberOfColumnsThatDontEndInAColumnBreak++;
						}
					};
				}($inBox));

					var avgH = totalH / numberOfColumnsThatDontEndInAColumnBreak;
					if(totalH === 0){
						//
						// all columns end in a column break,
						// so we're done here
						loopCount = maxLoops;
					}else if(options.lastNeverTallest && lastIsMax){
						// the last column is the tallest
						// so allow columns to be taller
						// and retry
						//
						// hopefully this'll mean more content fits into
						// earlier columns, so that the last column
						// can be shorter than the rest
						adjustment += 5;

						targetHeight = targetHeight + 30;
						if(loopCount == maxLoops-1) maxLoops++;
					}else if(max - min > 30){
						// too much variation, try again
						targetHeight = avgH + 30;
					}else if(Math.abs(avgH-targetHeight) > 20){
						// too much variation, try again
						targetHeight = avgH;
					}else {
						// solid, we're done
						loopCount = maxLoops;
					}
				}else{
					// it's scrolling horizontally, fix the width/classes of the columns
					$inBox.children().each(function(i){
						$col = $inBox.children().eq(i);
						$col.width(optionWidth + "px");
						if(i === 0){
							$col.addClass(prefixTheClassName("first"));
						}else if(i==$inBox.children().length-1){
							$col.addClass(prefixTheClassName("last"));
						}else{
							$col.removeClass(prefixTheClassName("first"));
							$col.removeClass(prefixTheClassName("last"));
						}
					});
					$inBox.width($inBox.children().length * optionWidth + "px");
				}
				$inBox.append($("<br style='clear:both;'>"));
			}
			$inBox.find(prefixTheClassName("column", true)).find(":first" + prefixTheClassName("removeiffirst", true)).remove();
			$inBox.find(prefixTheClassName("column", true)).find(':last' + prefixTheClassName("removeiflast", true)).remove();
			$inBox.find(prefixTheClassName("split", true)).find(":first" + prefixTheClassName("removeiffirst", true)).remove();
			$inBox.find(prefixTheClassName("split", true)).find(':last' + prefixTheClassName("removeiflast", true)).remove();
			$inBox.data("columnizing", false);

			if(options.overflow){
				options.overflow.doneFunc();
			}
			options.doneFunc();
		}
    });
 };

$.fn.renumberByJS=function($searchTag, $colno, $targetId, $targetClass ) {
	this.setList = function($cols, $list, $tag1) {
		var $parents	= this.before.parents();
		var $rest;

		$rest			= $($cols[this.offset-1]).find('>*');

		if( ($rest.last())[0].tagName!=$tag1.toUpperCase()) {
			if(this.debug) {
				console.log("Last item in previous column, isn't a list...");
			}
			return 0;
		}
		$rest			= $rest.length;
		var $tint		= 1;

		if(this.lastOther<=0) {
			$tint		= this.before.children().length+1;
		} else {
			$tint		= $($parents[this.lastOther]).children().length+1;
		}
		// if the first LI in the current column is split, decrement, as we want the same number/key
		if( $($cols[this.offset]).find($tag1+':first li.split').length ) {
			var $whereElipsis=$($cols[this.offset-1]).find($tag1+':last li:last');
			if( this.elipsisText==='' || 
				$($cols[this.offset-1]).find($tag1+':last ~ div').length || 
				$($cols[this.offset-1]).find($tag1+':last ~ p').length  ) {
				;
			} else {
				if($($whereElipsis).find('ul, ol, dl').length ==0 ) {

					var $txt=$whereElipsis.last().text();
					// char counting, 'cus MSIE 8 is appearently stupid
					var $len=$txt.length;
					if($txt.substring($len-1)==';') {
						if($txt.substring($len-4)!=this.elipsisText+';') {
							$txt=$txt.substring(0, $len-1)+this.elipsisText+';';
						}
					} else {
						if($txt.substring($len-3)!=this.elipsisText) {
							$txt+=this.elipsisText;
						}
					}
					$whereElipsis.last().text($txt);
				}
			}
			// an item in split between two columns.  it only holds one key...
			if($($cols[this.offset]).find($tag1+':first >li.split >'+$tag1).length==0) {
				$tint--; 
			}
		}
		if($rest==1) {
			// the last column only held one thing, so assume its wrapped to the column before that as well.
			$tint		+= this.prevMax ;
		}
		if(this.nest>1) {
			if(this.debug) {
				console.log("Supposed to be a nested list...decr");
			}
			$tint--;
// some how, id previous list starts split, need  secins decrement, 
// if "split" is now correct, reference this
			var $tt		= $($cols[this.offset -1]).find($tag1+':first li.split:first');
			if($tt.length>0) {
				if(this.debug) {
					console.log("Previous column started with a split item, so that count is one less than expected");
				}
				$tint--;
			}


			$tt			= $($cols[this.offset]).find($tag1+':first li:first').clone();
			$tt.children().remove();
			if( $.trim($tt.text()).length>0 ){
				if(this.debug) {
					console.log("If that was a complete list in the previous column, don't decr.");
				}
				$tint++;

				if($($cols[this.offset-1]).find(">"+$tag1+':last ').children().length==0 ) {
					if(this.debug) {
						console.log("unless that was empty, in which case revert");
					}
					$tint--;
				}
			}

		} else {
			var $tt		= $($cols[this.offset]).find($tag1+':first li:first '+$tag1+".split li.split");
			if($tt.length>0) {
				if(this.debug) {
					console.log("[Nested] Column started with a split item, so that count is one less than expected");
				}
				$tint--;
			}

		}

		if(this.debug) {
			console.log("Setting the start value to "+$tint+" ("+this.prevMax +")");
		}
		if($tint >0) {
			// if the above computation leads to 0, or an empty list (more likely), don't set, leave as 1
			if(typeof this.setColumnStart == 'function') {
				this.setColumnStart($list, $tint);
			} else {
				$list.attr('start', $tint);
			}
		}
		return 0; 
	}

	if(typeof $targetId === 'undefined') { $targetId=false; }
	if(typeof $targetClass === 'undefined') { $targetClass=false; }
	if(! $targetId && !$targetClass ) {
		throw "renumberByJS(): Bad param, must pass an id or a class";
	}

	var $target 			='';
	this.prevMax			=1;
	
	if($targetClass) {
		$target 			="."+$targetClass;
	} else {
		$target 			="#"+$targetId;
	}
	var $tag1				= $searchTag.toLowerCase();
	var $tag2				= $searchTag.toUpperCase();
	
	this.cols  				= $($target);
	if(this.debug) {
		console.log("There are "+this.cols.length+" items, looking for "+$tag1);
	}

	this.before				= $(this.cols[0]).find($tag1+':last');
	this.prevMax			= this.before.children().length;

// start at 1, as must compare to previous...
	for(this.offset=1; this.offset<this.cols.length; this.offset++) {
		if(this.debug) {
			console.log("iterating "+this.offset+"...[of "+this.cols.length+"]");
		}
// if the first column again, nothing to the left of you, do nothing...
		if(this.offset % $colno==0) { 
			if(this.debug) {
				console.log("First column (in theory..)");
			}

			this.prevMax	= 1;
			continue;
		}
		
		this.before			= $(this.cols[this.offset-1]).find($tag1+':last');
// if there are no occurences of the searchTag, do nothing
		if(this.before.length) {
			if(this.debug) {
				console.log("Have some "+$searchTag+" elements in the previous column");
			}

			var $list		= $(this.cols[this.offset]).find($tag1+':first');
			var $first		= $(this.cols[this.offset]).find('*:first');
			if($first[0] !== $list[0]) {
// don't renumber anything, its not a rollover list
				continue;
			}

			var $parents	= this.before.parents();
			this.lastOther	= 0;
			var $found		= false;
			for(; this.lastOther<$parents.length; this.lastOther++) {
				if($parents[this.lastOther].tagName != $tag2 && $parents[this.lastOther].tagName != "LI") {
					$found  = true;
					this.lastOther--;
					break;
				}
			}
			
			this.nest		=1;
			if($(this.cols[this.offset]).find(">"+$tag1+':first li '+$tag1+":first").length) {
				this.nest	= 2;
			}
			this.setList(this.cols, $list, $tag1);
			this.lastOther--;
			$list			= $(this.cols[this.offset]).find($tag1+':first li '+$tag1+":first");
			if($list.length) {
// I hope the two columns have same nesting, or its busted
				
				this.before= $(this.cols[this.offset-1]).find(">"+$tag1+':last li '+$tag1+":last");
				this.prevMax= 0;
				this.nest	=1;
				this.setList(this.cols, $list, $tag1);
			}
			var $reset		= $(this.cols[this.offset-1]).find(">"+$tag1+':last');
			this.prevMax	= $reset.children().length;
		}
	}
	return 0;
};

})(jQuery);
