function makeSortby(/* fields ...*/) {
	const aFields = Array.prototype.slice.apply(arguments),
		aNorms = [],
		aFuncs = [];
	for (let i = 0; i < arguments.length; i++) {
		aNorms[i] = 1;
		if ( typeof aFields[i] === 'function' ) {
			aFuncs[i] = aFields[i];
			continue;
		}
		aFuncs[i] = function($,n) { return $[n]; };
		if ( aFields[i].indexOf("!") === 0 ) {
			aNorms[i] = -1;
			aFields[i] = aFields[i].slice(1);
		}
		if ( aFields[i] === 'deprecated' ) {
			aFuncs[i] = function($,n) { return !!$[n]; };
		} else if ( aFields[i] === 'static' ) {
			aFields[i] = 'scope';
			aFuncs[i] = function($,n) { return $[n] === 'static'; };
		} else if ( aFields[i].indexOf("#") === 0 ) {
			aFields[i] = aFields[i].slice(1);
			aFuncs[i] = function($,n) { return $.comment.getTag(n).length > 0; };
		}
	}
	return function(a, b) {
		// debug(`compare ${a.longname} : ${b.longname}`);
		let r = 0;
		for (let i = 0; r === 0 && i < aFields.length; i++) {
			let va = aFuncs[i](a,aFields[i]);
			let vb = aFuncs[i](b,aFields[i]);
			if ( va && !vb ) {
				r = -aNorms[i];
			} else if ( !va && vb ) {
				r = aNorms[i];
			} else if ( va && vb ) {
				va = String(va).toLowerCase();
				vb = String(vb).toLowerCase();
				if (va < vb) {
					r = -aNorms[i];
				}
				if (va > vb) {
					r = aNorms[i];
				}
			}
			// debug(`  ${aFields[i]}: ${va} ? ${vb} = ${r}`);
		}
		return r;
	};
}
/* Make a symbol sorter by some attribute. */
Make a symbol sorter by some attribute.
Make a symbol sorter by some attribute .
function makeSortby() {
	const aFields = Array.prototype.slice.apply(arguments),
		aNorms = [],
		aFuncs = [];
	for (let i = 0; i < arguments.length; i++) {
		aNorms[i] = 1;
		if ( typeof aFields[i] === 'function' ) {
			aFuncs[i] = aFields[i];
			continue;
		}
		aFuncs[i] = function($,n) { return $[n]; };
		if ( aFields[i].indexOf("!") === 0 ) {
			aNorms[i] = -1;
			aFields[i] = aFields[i].slice(1);
		}
		if ( aFields[i] === 'deprecated' ) {
			aFuncs[i] = function($,n) { return !!$[n]; };
		} else if ( aFields[i] === 'static' ) {
			aFields[i] = 'scope';
			aFuncs[i] = function($,n) { return $[n] === 'static'; };
		} else if ( aFields[i].indexOf("#") === 0 ) {
			aFields[i] = aFields[i].slice(1);
			aFuncs[i] = function($,n) { return $.comment.getTag(n).length > 0; };
		}
	}
	return function(a, b) {
		let r = 0;
		for (let i = 0; r === 0 && i < aFields.length; i++) {
			let va = aFuncs[i](a,aFields[i]);
			let vb = aFuncs[i](b,aFields[i]);
			if ( va && !vb ) {
				r = -aNorms[i];
			} else if ( !va && vb ) {
				r = aNorms[i];
			} else if ( va && vb ) {
				va = String(va).toLowerCase();
				vb = String(vb).toLowerCase();
				if (va < vb) {
					r = -aNorms[i];
				}
				if (va > vb) {
					r = aNorms[i];
				}
			}
		}
		return r;
	};
}
function makeSortby ( ) { const aFields = Array . prototype . slice . apply ( arguments ) , aNorms = [ ] , aFuncs = [ ] ; for ( let i = 0 ; i < arguments . length ; i ++ ) { aNorms [ i ] = 1 ; if ( typeof aFields [ i ] === 'function' ) { aFuncs [ i ] = aFields [ i ] ; continue ; } aFuncs [ i ] = function ( $ , n ) { return $ [ n ] ; } ; if ( aFields [ i ] . indexOf ( "!" ) === 0 ) { aNorms [ i ] = - 1 ; aFields [ i ] = aFields [ i ] . slice ( 1 ) ; } if ( aFields [ i ] === 'deprecated' ) { aFuncs [ i ] = function ( $ , n ) { return ! ! $ [ n ] ; } ; } else if ( aFields [ i ] === 'static' ) { aFields [ i ] = 'scope' ; aFuncs [ i ] = function ( $ , n ) { return $ [ n ] === 'static' ; } ; } else if ( aFields [ i ] . indexOf ( "#" ) === 0 ) { aFields [ i ] = aFields [ i ] . slice ( 1 ) ; aFuncs [ i ] = function ( $ , n ) { return $ . comment . getTag ( n ) . length > 0 ; } ; } } return function ( a , b ) { let r = 0 ; for ( let i = 0 ; r === 0 && i < aFields . length ; i ++ ) { let va = aFuncs [ i ] ( a , aFields [ i ] ) ; let vb = aFuncs [ i ] ( b , aFields [ i ] ) ; if ( va && ! vb ) { r = - aNorms [ i ] ; } else if ( ! va && vb ) { r = aNorms [ i ] ; } else if ( va && vb ) { va = String ( va ) . toLowerCase ( ) ; vb = String ( vb ) . toLowerCase ( ) ; if ( va < vb ) { r = - aNorms [ i ] ; } if ( va > vb ) { r = aNorms [ i ] ; } } } return r ; } ; }
Make a symbol sorter by some attribute.
Make a symbol sorter by some attribute .
/* fields ...*/ // debug(`compare ${a.longname} : ${b.longname}`); // debug(`  ${aFields[i]}: ${va} ? ${vb} = ${r}`);