/*
Wrap code within a context and returns back a new function to be executed

@param {object} options A specific set of options for this context [optional]
@param {function} func The function to be wrapped in a new context
@param {function} _before A function to call before the try/catch wrapper [optional, private]
@return {function} The newly wrapped functions with a context
function wrap(options, func, _before) {
	    var self = this; // 1 argument has been passed, and it's not a function
	    // so just return it

	    if (isUndefined$1(func) && !isFunction$1(options)) {
	      return options;
	    } // options is optional


	    if (isFunction$1(options)) {
	      func = options;
	      options = undefined;
	    } // At this point, we've passed along 2 arguments, and the second one
	    // is not a function either, so we'll just return the second argument.


	    if (!isFunction$1(func)) {
	      return func;
	    } // We don't wanna wrap it twice!


	    try {
	      if (func.__raven__) {
	        return func;
	      } // If this has already been wrapped in the past, return that


	      if (func.__raven_wrapper__) {
	        return func.__raven_wrapper__;
	      }
	    } catch (e) {
	      // Just accessing custom props in some Selenium environments
	      // can cause a "Permission denied" exception (see raven-js#495).
	      // Bail on wrapping and return the function as-is (defers to window.onerror).
	      return func;
	    }

	    function wrapped() {
	      var args = [],
	          i = arguments.length,
	          deep = !options || options && options.deep !== false;

	      if (_before && isFunction$1(_before)) {
	        _before.apply(this, arguments);
	      } // Recursively wrap all of a function's arguments that are
	      // functions themselves.


	      while (i--) {
	        args[i] = deep ? self.wrap(options, arguments[i]) : arguments[i];
	      }

	      try {
	        // Attempt to invoke user-land function
	        // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
	        //       means Raven caught an error invoking your application code. This is
	        //       expected behavior and NOT indicative of a bug with Raven.js.
	        return func.apply(this, args);
	      } catch (e) {
	        self._ignoreNextOnError();

	        self.captureException(e, options);
	        throw e;
	      }
	    } // copy over properties of the old function


	    for (var property in func) {
	      if (hasKey$1(func, property)) {
	        wrapped[property] = func[property];
	      }
	    }

	    wrapped.prototype = func.prototype;
	    func.__raven_wrapper__ = wrapped; // Signal that this function has been wrapped/filled already
	    // for both debugging and to prevent it to being wrapped/filled twice

	    wrapped.__raven__ = true;
	    wrapped.__orig__ = func;
	    return wrapped;
	  }