text: // A stable array sort, because `Array#sort()` is not guaranteed stable.
  // This is an implementation of merge sort, without recursion.
  
  var stable = function (arr, comp) {
    return exec(arr.slice(), comp)
  }
  
  stable.inplace = function (arr, comp) {
    var result = exec(arr, comp)
  
    // This simply copies back if the result isn't in the original array,
    // which happens on an odd number of passes.
    if (result !== arr) {
      pass(result, null, arr.length, arr)
    }
  
    return arr
  }
  
  // Execute the sort using the input array and a second buffer as work space.
  // Returns one of those two, containing the final result.
  function exec(arr, comp) {
    if (typeof(comp) !== 'function') {
      comp = function (a, b) {
        return String(a).localeCompare(b)
      }
    }
  
    // Short-circuit when there's nothing to sort.
    var len = arr.length
    if (len <= 1) {
      return arr
    }
  
    // Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc.
    // Chunks are the size of the left or right hand in merge sort.
    // Stop when the left-hand covers all of the array.
    var buffer = new Array(len)
    for (var chk = 1; chk < len; chk *= 2) {
      pass(arr, comp, chk, buffer)
  
      var tmp = arr
      arr = buffer
      buffer = tmp
    }
  
    return arr
  }
  
  // Run a single pass with the given chunk size.
  var pass = function (arr, comp, chk, result) {
    var len = arr.length
    var i = 0
    // Step size / double chunk size.
    var dbl = chk * 2
    // Bounds of the left and right chunks.
    var l, r, e
    // Iterators over the left and right chunk.
    var li, ri
  
    // Iterate over pairs of chunks.
    for (l = 0; l < len; l += dbl) {
      r = l + chk
      e = r + chk
      if (r > len) r = len
      if (e > len) e = len
  
      // Iterate both chunks in parallel.
      li = l
      ri = r
      while (true) {
        // Compare the chunks.
        if (li < r && ri < e) {
          // This works for a regular `sort()` compatible comparator,
          // but also for a simple comparator like: `a > b`
          if (comp(arr[li], arr[ri]) <= 0) {
            result[i++] = arr[li++]
          }
          else {
            result[i++] = arr[ri++]
          }
        }
        // Nothing to compare, just flush what's left.
        else if (li < r) {
          result[i++] = arr[li++]
        }
        else if (ri < e) {
          result[i++] = arr[ri++]
        }
        // Both iterators are at the chunk ends.
        else {
          break
        }
      }
    }
  }
  
  export default stable
  