function natcompare (left, right) {
    var non_number = new RegExp ("[^0-9]*");
    var number = new RegExp ("[0-9]+([.][0-9]+)?");
    var ml, mr;
    var l = left.toLocaleLowerCase ();
    var r = right.toLocaleLowerCase ();

    while (true) {
	if (l.length == 0) {
	    if (r.length == 0)
		return 0;
	    else
		return -1;
	}
	if (r.length == 0)
	    return -1;

	ml = non_number.exec (l);
	mr = non_number.exec (r);
	if (ml && mr) {
	    var diff = ml[0].localeCompare (mr[0]);
	    if (diff != 0)
		return diff;
	    l = l.substring (ml[0].length);
	    r = r.substring (mr[0].length);
	} else if (ml && !mr || !ml && mr) {
	    /* one side starting with non-number, the other with number */
	    return l.localeCompare (r);
	}
	ml = number.exec (l);
	mr = number.exec (r);
	if (ml && mr) {
	    var fl = parseFloat (ml[0]);
	    var fr = parseFloat (mr[0]);
	    var diff = fl - fr;
	    if (diff != 0.0)
		return diff;
	    l = l.substring (ml[0].length);
	    r = r.substring (mr[0].length);
	}
    }
}

function natsort (a) {
    a.sort (natcompare);
}
