<commit_before>import { typeOf } from 'ember-metal/utils';
import Comparable from 'ember-runtime/mixins/comparable';

Ember.TYPE_ORDER = {
  'undefined': 0,
  'null': 1,
  'boolean': 2,
  'number': 3,
  'string': 4,
  'array': 5,
  'object': 6,
  'instance': 7,
  'function': 8,
  'class': 9,
  'date': 10
};

//
// the spaceship operator
//
function spaceship(a, b) {
  var diff = a - b;
  return (diff > 0) - (diff < 0);
}

/**
 This will compare two javascript values of possibly different types.
 It will tell you which one is greater than the other by returning:

  - -1 if the first is smaller than the second,
  - 0 if both are equal,
  - 1 if the first is greater than the second.

 The order is calculated based on `Ember.ORDER_DEFINITION`, if types are different.
 In case they have the same type an appropriate comparison for this type is made.

  ```javascript
  Ember.compare('hello', 'hello');  // 0
  Ember.compare('abc', 'dfg');      // -1
  Ember.compare(2, 1);              // 1
  ```

 @method compare
 @for Ember
 @param {Object} v First value to compare
 @param {Object} w Second value to compare
 @return {Number} -1 if v < w, 0 if v = w and 1 if v > w.
*/
export default function compare(v, w) {
  if (v === w) {
    return 0;
  }

  var type1 = typeOf(v);
  var type2 = typeOf(w);

  if (Comparable) {
    if (type1 ==='instance' && Comparable.detect(v.constructor)) {
      return v.constructor.compare(v, w);
    }

    if (type2 === 'instance' && Comparable.detect(w.constructor)) {
      return 1 - w.constructor.compare(w, v);
    }
  }

  var res = spaceship(Ember.TYPE_ORDER[type1], Ember.TYPE_ORDER[type2]);
  if (res !== 0) {
    return res;
  }

  // types are equal - so we have to check values now
  switch (type1) {
    case 'boolean':
    case 'number':
      return spaceship(v,w);

    case 'string':
      return Math.sign(v.localeCompare(w));

    case 'array':
      var vLen = v.length;
      var wLen = w.length;
      var len = Math.min(vLen, wLen);

      for (var i = 0; i < len; i++) {
        var r = compare(v[i], w[i]);
        if (r !== 0) {
          return r;
        }
      }

      // all elements are equal now
      // shorter array should be ordered first
      return spaceship(vLen, wLen);

    case 'instance':
      if (Comparable && Comparable.detect(v)) {
        return v.compare(v, w);
      }
      return 0;

    case 'date':
      return spaceship(v.getTime(), w.getTime());

    default:
      return 0;
  }
}<commit_msg>nodejs apparently does not have Math.sign, also moved TYPE_ORDER to be local to compare.js<commit_after>import { typeOf } from 'ember-metal/utils';
import Comparable from 'ember-runtime/mixins/comparable';

var TYPE_ORDER = {
  'undefined': 0,
  'null': 1,
  'boolean': 2,
  'number': 3,
  'string': 4,
  'array': 5,
  'object': 6,
  'instance': 7,
  'function': 8,
  'class': 9,
  'date': 10
};

//
// the spaceship operator
//
function spaceship(a, b) {
  var diff = a - b;
  return (diff > 0) - (diff < 0);
}

/**
 This will compare two javascript values of possibly different types.
 It will tell you which one is greater than the other by returning:

  - -1 if the first is smaller than the second,
  - 0 if both are equal,
  - 1 if the first is greater than the second.

 The order is calculated based on `Ember.ORDER_DEFINITION`, if types are different.
 In case they have the same type an appropriate comparison for this type is made.

  ```javascript
  Ember.compare('hello', 'hello');  // 0
  Ember.compare('abc', 'dfg');      // -1
  Ember.compare(2, 1);              // 1
  ```

 @method compare
 @for Ember
 @param {Object} v First value to compare
 @param {Object} w Second value to compare
 @return {Number} -1 if v < w, 0 if v = w and 1 if v > w.
*/
export default function compare(v, w) {
  if (v === w) {
    return 0;
  }

  var type1 = typeOf(v);
  var type2 = typeOf(w);

  if (Comparable) {
    if (type1 ==='instance' && Comparable.detect(v.constructor)) {
      return v.constructor.compare(v, w);
    }

    if (type2 === 'instance' && Comparable.detect(w.constructor)) {
      return 1 - w.constructor.compare(w, v);
    }
  }

  var res = spaceship(TYPE_ORDER[type1], TYPE_ORDER[type2]);
  if (res !== 0) {
    return res;
  }

  // types are equal - so we have to check values now
  switch (type1) {
    case 'boolean':
    case 'number':
      return spaceship(v,w);

    case 'string':
      return spaceship(v.localeCompare(w), 0);

    case 'array':
      var vLen = v.length;
      var wLen = w.length;
      var len = Math.min(vLen, wLen);

      for (var i = 0; i < len; i++) {
        var r = compare(v[i], w[i]);
        if (r !== 0) {
          return r;
        }
      }

      // all elements are equal now
      // shorter array should be ordered first
      return spaceship(vLen, wLen);

    case 'instance':
      if (Comparable && Comparable.detect(v)) {
        return v.compare(v, w);
      }
      return 0;

    case 'date':
      return spaceship(v.getTime(), w.getTime());

    default:
      return 0;
  }
}
{'fraction_non_alphanumeric': 0.1408785120696478, 'fraction_numerical': 0.01563118322121092, 'mean_word_length': 2.4528688524590163, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '233665', 'n_tokens_mistral': 1770, 'n_tokens_neox': 1673, 'n_words': 585}