/*
naturalSort.js
- by Jim Palmer and other contributors

The MIT License (MIT)

Copyright (c) 2011 Jim Palmer and other contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

//    naturalSort.js 0.7.0
//    https://github.com/jarinudom/naturalSort.js
//    (c) 2011 Jim Palmer and other contributors
//    naturalSort.js may be freely distributed under the MIT license.
//    Generated by CoffeeScript 1.7.1
(function() {
  window.naturalSort = function(a, b) {
    var cLoc, dre, hre, i, numS, oFxNcL, oFyNcL, ore, re, sre, x, xD, xN, y, yD, yN;
    re = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/g;
    sre = /(^[ ]*|[ ]*$)/g;
    dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
    hre = /^0x[0-9a-f]+$/i;
    ore = /^0/;
    i = function(s) {
      return naturalSort.insensitive && ('' + s).toLowerCase() || '' + s;
    };
    x = i(a).replace(sre, '') || '';
    y = i(b).replace(sre, '') || '';
    xN = x.replace(re, '\u0000$1\u0000').replace(/\0$/, '').replace(/^\0/, '').split('\u0000');
    yN = y.replace(re, '\u0000$1\u0000').replace(/\0$/, '').replace(/^\0/, '').split('\u0000');
    xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && x.match(dre) && Date.parse(x));
    yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null;
    oFxNcL = void 0;
    oFyNcL = void 0;
    if (yD) {
      if (xD < yD) {
        return -1;
      }
      if (xD > yD) {
        return 1;
      }
    }
    cLoc = 0;
    numS = Math.max(xN.length, yN.length);
    while (cLoc < numS) {
      oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
      oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
      if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
        return (isNaN(oFxNcL) ? 1 : -1);
      } else if (typeof oFxNcL !== typeof oFyNcL) {
        oFxNcL += '';
        oFyNcL += '';
      }
      if (oFxNcL < oFyNcL) {
        return -1;
      }
      if (oFxNcL > oFyNcL) {
        return 1;
      }
      cLoc++;
    }
    return 0;
  };

}).call(this);
