template/html/jquery-tablesorter.js
function( a, b ) {
         if ( a === b ) { return 0; }
         var aNum, bNum, aFloat, bFloat, indx, max,
          regex = ts.regex;
         // first try and sort Hex codes
         if ( regex.hex.test( b ) ) {
            aNum = parseInt( a.match( regex.hex ), 16 );
            bNum = parseInt( b.match( regex.hex ), 16 );
            if ( aNum < bNum ) { return -1; }
            if ( aNum > bNum ) { return 1; }
         }
         // chunk/tokenize
         aNum = a.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' );
         bNum = b.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' );
         max = Math.max( aNum.length, bNum.length );
         // natural sorting through split numeric strings and default strings
         for ( indx = 0; indx < max; indx++ ) {
            // find floats not starting with '0', string or 0 if not defined
            aFloat = isNaN( aNum[ indx ] ) ? aNum[ indx ] || 0 : parseFloat( aNum[ indx ] ) || 0;
            bFloat = isNaN( bNum[ indx ] ) ? bNum[ indx ] || 0 : parseFloat( bNum[ indx ] ) || 0;
            // handle numeric vs string comparison - number < string - (Kyle Adams)
            if ( isNaN( aFloat ) !== isNaN( bFloat ) ) { return isNaN( aFloat ) ? 1 : -1; }
            // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
            if ( typeof aFloat !== typeof bFloat ) {
               aFloat += '';
               bFloat += '';
            }
            if ( aFloat < bFloat ) { return -1; }
            if ( aFloat > bFloat ) { return 1; }
         }
         return 0;
      }
function( a, b ) {
         if ( a === b ) { return 0; }
         var aNum, bNum, aFloat, bFloat, indx, max,
          regex = ts.regex;
         // first try and sort Hex codes
         if ( regex.hex.test( b ) ) {
            aNum = parseInt( a.match( regex.hex ), 16 );
            bNum = parseInt( b.match( regex.hex ), 16 );
            if ( aNum < bNum ) { return -1; }
            if ( aNum > bNum ) { return 1; }
         }
         // chunk/tokenize
         aNum = a.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' );
         bNum = b.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' );
         max = Math.max( aNum.length, bNum.length );
         // natural sorting through split numeric strings and default strings
         for ( indx = 0; indx < max; indx++ ) {
            // find floats not starting with '0', string or 0 if not defined
            aFloat = isNaN( aNum[ indx ] ) ? aNum[ indx ] || 0 : parseFloat( aNum[ indx ] ) || 0;
            bFloat = isNaN( bNum[ indx ] ) ? bNum[ indx ] || 0 : parseFloat( bNum[ indx ] ) || 0;
            // handle numeric vs string comparison - number < string - (Kyle Adams)
            if ( isNaN( aFloat ) !== isNaN( bFloat ) ) { return isNaN( aFloat ) ? 1 : -1; }
            // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
            if ( typeof aFloat !== typeof bFloat ) {
               aFloat += '';
               bFloat += '';
            }
            if ( aFloat < bFloat ) { return -1; }
            if ( aFloat > bFloat ) { return 1; }
         }
         return 0;
      }
Natural sort - https://github.com/overset/javascript-natural-sort (date sorting removed) this function will only accept strings, or you'll see 'TypeError: undefined is not a function' I could add a = a.toString(); b = b.toString(); but it'll slow down the sort overall