"use strict";

// Generated by CoffeeScript 2.4.1
(function () {
  var _arity, _copy, _curry2, _pipe, ƒ;

  _arity = function _arity(n, fn) {
    switch (n) {
      case 0:
        return function () {
          return fn.apply(this, arguments);
        };

      case 1:
        return function (a) {
          return fn.apply(this, arguments);
        };

      case 2:
        return function (a, b) {
          return fn.apply(this, arguments);
        };

      case 3:
        return function (a, b, c) {
          return fn.apply(this, arguments);
        };

      case 4:
        return function (a, b, c, d) {
          return fn.apply(this, arguments);
        };

      case 5:
        return function (a, b, c, d, e) {
          return fn.apply(this, arguments);
        };

      case 6:
        return function (a, b, c, d, e, f) {
          return fn.apply(this, arguments);
        };

      case 7:
        return function (a, b, c, d, e, f, g) {
          return fn.apply(this, arguments);
        };

      case 8:
        return function (a, b, c, d, e, f, g, h) {
          return fn.apply(this, arguments);
        };

      case 9:
        return function (a, b, c, d, e, f, g, h, i) {
          return fn.apply(this, arguments);
        };

      case 10:
        return function (a, b, c, d, e, f, g, h, i, j) {
          return fn.apply(this, arguments);
        };

      case 11:
        return function (a, b, c, d, e, f, g, h, i, j, k) {
          return fn.apply(this, arguments);
        };

      case 12:
        return function (a, b, c, d, e, f, g, h, i, j, k, l) {
          return fn.apply(this, arguments);
        };
    }
  };

  _copy = function _copy(list) {
    return Array.prototype.slice.call(list);
  };

  _curry2 = function _curry(fn, currentArgs, remainingArity) {
    if (remainingArity <= 0) {
      return fn.apply(this, currentArgs);
    }

    return _arity(remainingArity, function () {
      var calledArgs;
      calledArgs = _copy(arguments);
      return _curry2(fn, currentArgs.concat(calledArgs), remainingArity - calledArgs.length);
    });
  };

  _pipe = function _pipe(f, g) {
    return function () {
      return g.call(this, f.apply(this, arguments));
    };
  };

  ƒ = function _(fn) {
    return _curry2(fn, [], fn.length);
  };

  ƒ.arity = ƒ(_arity); // Lists

  ƒ.map = ƒ(function (fn, list) {
    return list.map(fn);
  });
  ƒ.filter = ƒ(function (fn, list) {
    return list.filter(fn);
  });
  ƒ.reduce = ƒ(function (fn, acc, list) {
    var item, len, o;

    for (o = 0, len = list.length; o < len; o++) {
      item = list[o];
      acc = fn(acc, item);
    }

    return acc;
  });
  ƒ.slice = ƒ(function (from, to, list) {
    return list.slice(from, to);
  });
  ƒ.nth = ƒ(function (n, list) {
    if (n < 0) {
      n = list.length + n;
    }

    return list[n];
  });
  ƒ.tail = ƒ.slice(1, 2e308);
  ƒ.init = ƒ.slice(0, -1);
  ƒ.first = ƒ.nth(0);
  ƒ.last = ƒ.nth(-1);

  ƒ.reverse = function (list) {
    return _copy(list).reverse();
  };

  ƒ.lengthfn = function (list) {
    return list.length;
  };

  ƒ.append = ƒ(function (item, list) {
    return list.concat([item]);
  });
  ƒ.prepend = ƒ(function (item, list) {
    return [item].concat(list);
  });
  ƒ.drop = ƒ(function (n, list) {
    return ƒ.slice(Math.max(0, n), 2e308, list);
  });
  ƒ.take = ƒ(function (n, list) {
    return ƒ.slice(0, Math.max(0, n), list);
  });
  ƒ.splitAt = ƒ(function (n, list) {
    return [ƒ.slice(0, n, list), ƒ.slice(n, list.length, list)];
  });
  ƒ.any = ƒ(function (fn, list) {
    var item, len, o;

    for (o = 0, len = list.length; o < len; o++) {
      item = list[o];

      if (fn(item)) {
        return true;
      }
    }

    return false;
  });
  ƒ.all = ƒ(function (fn, list) {
    var item, len, o;

    for (o = 0, len = list.length; o < len; o++) {
      item = list[o];

      if (!fn(item)) {
        return false;
      }
    }

    return true;
  });
  ƒ.zip = ƒ(function (list1, list2) {
    var i, o, ref, results;
    results = [];

    for (i = o = 0, ref = Math.min(list1.length, list2.length); 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
      results.push([list1[i], list2[i]]);
    }

    return results;
  });

  ƒ.of = function (a) {
    return [a];
  };

  ƒ.pluck = function (prop) {
    return ƒ.map(ƒ.prop(prop));
  };

  ƒ.aperture = ƒ(function (n, list) {
    var i, o, ref, results;
    results = [];

    for (i = o = 0, ref = list.length - (n - 1); 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
      results.push(ƒ.slice(list, i, i + n));
    }

    return results;
  });
  ƒ.sort = ƒ(function (fn, list) {
    return list.slice(0).sort(fn);
  });
  ƒ.asc = ƒ(function (fn, list) {
    var sort;
    sort = ƒ.sort(function (a, b) {
      var fa, fb;
      fa = fn(a);
      fb = fn(b);

      if (fa > fb) {
        return 1;
      }

      if (fa < fb) {
        return -1;
      }

      return 0;
    });
    return sort(list);
  });
  ƒ.desc = ƒ(function (fn, list) {
    var sort;
    sort = ƒ.sort(function (a, b) {
      var fa, fb;
      fa = fn(a);
      fb = fn(b);

      if (fa < fb) {
        return 1;
      }

      if (fa > fb) {
        return -1;
      }

      return 0;
    });
    return sort(list);
  });
  ƒ.find = ƒ(function (fn, list) {
    var item, len, o;

    for (o = 0, len = list.length; o < len; o++) {
      item = list[o];

      if (fn(item)) {
        return item;
      }
    }

    return void 0;
  }); // Flow

  ƒ.pipe = function (first) {
    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      args[_key - 1] = arguments[_key];
    }

    return ƒ(_arity(first.length, ƒ.reduce(function (f, g) {
      return function () {
        return g.call(this, f.apply(this, arguments));
      };
    }, first, args)));
  };

  ƒ.compose = function () {
    return ƒ.pipe.apply(this, ƒ.reverse(arguments));
  };

  ƒ.both = ƒ(function (fn1, fn2) {
    return _arity(Math.min(fn1.length, fn2.length), function () {
      return fn1.apply(this, arguments) && fn2.apply(this, arguments);
    });
  });
  ƒ.either = ƒ(function (fn1, fn2) {
    return _arity(Math.min(fn1.length, fn2.length), function () {
      return fn1.apply(this, arguments) || fn2.apply(this, arguments);
    });
  });
  ƒ.converge = ƒ(function (fn, fns) {
    var arity;
    arity = reduce(Math.max, 0, ƒ.pluck('length', fns));
    return ƒ(_arity(arity, function () {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }

      var context;
      context = this;
      return fn.apply(context, ƒ.map(function (fn) {
        return fn.apply(context, args);
      }, fns));
    }));
  });

  ƒ.identity = function (n) {
    return n;
  };

  ƒ.always = ƒ(function (n, _) {
    return n;
  });
  ƒ.ap = ƒ(function (fns, list) {
    return ƒ.reduce(function (acc, f) {
      return ƒ.concat(acc, map(f, list));
    }, [], fns);
  });
  ƒ.applyFn = ƒ(function (fn, args) {
    return fn.apply(this, args);
  });

  ƒ.callFn = function (fn) {
    for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
      args[_key3 - 1] = arguments[_key3];
    }

    return fn.apply(this, args);
  }; // Object


  ƒ.prop = ƒ(function (prop, obj) {
    return obj[prop];
  });
  ƒ.propEq = ƒ(function (prop, value, obj) {
    return obj[prop] === value;
  });

  ƒ.isEmpty = function (obj) {
    return obj === '';
  };

  ƒ.isNil = function (obj) {
    return obj == null;
  };

  ƒ.exists = ƒ.compose(ƒ.not, ƒ.either(ƒ.isEmpty, ƒ.isNil), ƒ.prop);
  ƒ.isValid = ƒ(function (validate, prop) {
    return ƒ.compose(validate, ƒ.prop(prop));
  }); // Math

  ƒ.add = ƒ(function (a, b) {
    return a + b;
  });
  ƒ.sub = ƒ(function (a, b) {
    return a - b;
  });
  ƒ.mult = ƒ(function (a, b) {
    return a * b;
  });
  ƒ.div = ƒ(function (a, b) {
    return a / b;
  });

  ƒ.dec = function (n) {
    return n - 1;
  };

  ƒ.inc = function (n) {
    return n + 1;
  };

  ƒ.mod = ƒ(function (m, p) {
    return (m % p + p) % p;
  });
  ƒ.and = ƒ(function (a, b) {
    return a && b;
  });
  ƒ.or = ƒ(function (a, b) {
    return a || b;
  });

  ƒ.not = function (a) {
    return !a;
  }; // Stats


  ƒ.sum = ƒ.reduce(ƒ.add, 0);

  ƒ.avg = function (list) {
    return ƒ.sum(list) / list.length;
  };

  ƒ.median = function (list) {
    if (list.length === 0) {
      return 0 / 0;
    }

    list = _copy(list);
    list.sort(function (a, b) {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return list[Math.floor(list.length / 2)];
  };

  module.exports = ƒ;
}).call(void 0);