function range(startOrEnd, opt_end, opt_step) {
  const array = [];
  let start = 0;
  let end = startOrEnd;
  const step = opt_step || 1;
  if (opt_end !== undefined) {
    start = startOrEnd;
    end = opt_end;
  }

  if (step * (end - start) < 0) {
    // Sign mismatch: start + step will never reach the end value.
    return [];
  }

  if (step > 0) {
    for (let i = start; i < end; i += step) {
      array.push(i);
    }
  } else {
    for (let i = start; i > end; i += step) {
      array.push(i);
    }
  }
  return array;
}
Creates a range of numbers in an arithmetic progression.

Range takes 1, 2, or 3 arguments:
<pre>
range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
range(-2, -5, -1) produces [-2, -3, -4]
range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
</pre>

@param {number} startOrEnd The starting value of the range if an end argument
    is provided. Otherwise, the start value is 0, and this is the end value.
@param {number=} opt_end The optional end value of the range.
@param {number=} opt_step The step size between range values. Defaults to 1
    if opt_step is undefined or 0.
@return {!Array<number>} An array of numbers for the requested range. May be
    an empty array if adding the step would not converge toward the end
    value.