"use strict"; var callable = require("es5-ext/object/valid-callable") , forEach = require("es5-ext/object/for-each") , extensions = require("./lib/registered-extensions") , configure = require("./lib/configure-map") , resolveLength = require("./lib/resolve-length"); module.exports = function self(fn /*, options */) { var options, length, conf; callable(fn); options = Object(arguments[1]); if (options.async && options.promise) { throw new Error("Options 'async' and 'promise' cannot be used together"); } // Do not memoize already memoized function if (hasOwnProperty.call(fn, "__memoized__") && !options.force) return fn; // Resolve length; length = resolveLength(options.length, fn.length, options.async && extensions.async); // Configure cache map conf = configure(fn, length, options); // Bind eventual extensions forEach(extensions, function (extFn, name) { if (options[name]) extFn(options[name], conf, options); }); if (self.__profiler__) self.__profiler__(conf); conf.updateEnv(); return conf.memoized; };