function $TimeoutProvider() {
  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {

    var deferreds = {};


    /**
     * @ngdoc service
     * @name $timeout
     *
     * @description
     * AngularJS's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
     * block and delegates any exceptions to
     * {@link ng.$exceptionHandler $exceptionHandler} service.
     *
     * The return value of calling `$timeout` is a promise, which will be resolved when
     * the delay has passed and the timeout function, if provided, is executed.
     *
     * To cancel a timeout request, call `$timeout.cancel(promise)`.
     *
     * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
     * synchronously flush the queue of deferred functions.
     *
     * If you only want a promise that will be resolved after some specified delay
     * then you can call `$timeout` without the `fn` function.
     *
     * @param {function()=} fn A function, whose execution should be delayed.
     * @param {number=} [delay=0] Delay in milliseconds.
     * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
     *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
     * @param {...*=} Pass additional parameters to the executed function.
     * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise
     *   will be resolved with the return value of the `fn` function.
     *
     */
    function timeout(fn, delay, invokeApply) {
      if (!isFunction(fn)) {
        invokeApply = delay;
        delay = fn;
        fn = noop;
      }

      var args = sliceArgs(arguments, 3),
          skipApply = (isDefined(invokeApply) && !invokeApply),
          deferred = (skipApply ? $$q : $q).defer(),
          promise = deferred.promise,
          timeoutId;

      timeoutId = $browser.defer(function() {
        try {
          deferred.resolve(fn.apply(null, args));
        } catch (e) {
          deferred.reject(e);
          $exceptionHandler(e);
        } finally {
          delete deferreds[promise.$$timeoutId];
        }

        if (!skipApply) $rootScope.$apply();
      }, delay, '$timeout');

      promise.$$timeoutId = timeoutId;
      deferreds[timeoutId] = deferred;

      return promise;
    }


    /**
     * @ngdoc method
     * @name $timeout#cancel
     *
     * @description
     * Cancels a task associated with the `promise`. As a result of this, the promise will be
     * resolved with a rejection.
     *
     * @param {Promise=} promise Promise returned by the `$timeout` function.
     * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
     *   canceled.
     */
    timeout.cancel = function(promise) {
      if (!promise) return false;

      if (!promise.hasOwnProperty('$$timeoutId')) {
        throw $timeoutMinErr('badprom',
            '`$timeout.cancel()` called with a promise that was not generated by `$timeout()`.');
      }

      if (!deferreds.hasOwnProperty(promise.$$timeoutId)) return false;

      var id = promise.$$timeoutId;
      var deferred = deferreds[id];

      // Timeout cancels should not report an unhandled promise.
      markQExceptionHandled(deferred.promise);
      deferred.reject('canceled');
      delete deferreds[id];

      return $browser.defer.cancel(id);
    };

    return timeout;
  }];
}
@ngdoc input
@name input[range]

@description
Native range input with validation and transformation.

The model for the range input must always be a `Number`.

IE9 and other browsers that do not support the `range` type fall back
to a text input without any default values for `min`, `max` and `step`. Model binding,
validation and number parsing are nevertheless supported.

Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`
in a way that never allows the input to hold an invalid value. That means:
- any non-numerical value is set to `(max + min) / 2`.
- any numerical value that is less than the current min val, or greater than the current max val
is set to the min / max val respectively.
- additionally, the current `step` is respected, so the nearest value that satisfies a step
is used.

See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))
for more info.

This has the following consequences for AngularJS:

Since the element value should always reflect the current model value, a range input
will set the bound ngModel expression to the value that the browser has set for the
input element. For example, in the following input `<input type="range" ng-model="model.value">`,
if the application sets `model.value = null`, the browser will set the input to `'50'`.
AngularJS will then set the model to `50`, to prevent input and model value being out of sync.

That means the model for range will immediately be set to `50` after `ngModel` has been
initialized. It also means a range input can never have the required error.

This does not only affect changes to the model value, but also to the values of the `min`,
`max`, and `step` attributes. When these change in a way that will cause the browser to modify
the input value, AngularJS will also update the model value.

Automatic value adjustment also means that a range input element can never have the `required`,
`min`, or `max` errors.

However, `step` is currently only fully implemented by Firefox. Other browsers have problems
when the step value changes dynamically - they do not adjust the element value correctly, but
instead may set the `stepMismatch` error. If that's the case, the AngularJS will set the `step`
error on the input, and set the model to `undefined`.

Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do
not set the `min` and `max` attributes, which means that the browser won't automatically adjust
the input value based on their values, and will always assume min = 0, max = 100, and step = 1.

@param {string}  ngModel Assignable AngularJS expression to data-bind to.
@param {string=} name Property name of the form under which the control is published.
@param {string=} min Sets the `min` validation to ensure that the value entered is greater
                 than `min`. Can be interpolated.
@param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.
                 Can be interpolated.
@param {string=} step Sets the `step` validation to ensure that the value entered matches the `step`
                 Can be interpolated.
@param {expression=} ngChange AngularJS expression to be executed when the ngModel value changes due
                     to user interaction with the input element.
@param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the
                     element. **Note** : `ngChecked` should not be used alongside `ngModel`.
                     Checkout {@link ng.directive:ngChecked ngChecked} for usage.

@example
      <example name="range-input-directive" module="rangeExample">
        <file name="index.html">
          <script>
            angular.module('rangeExample', [])
              .controller('ExampleController', ['$scope', function($scope) {
                $scope.value = 75;
                $scope.min = 10;
                $scope.max = 90;
              }]);
          </script>
          <form name="myForm" ng-controller="ExampleController">

            Model as range: <input type="range" name="range" ng-model="value" min="{{min}}"  max="{{max}}">
            <hr>
            Model as number: <input type="number" ng-model="value"><br>
            Min: <input type="number" ng-model="min"><br>
            Max: <input type="number" ng-model="max"><br>
            value = <code>{{value}}</code><br/>
            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
            myForm.range.$error = <code>{{myForm.range.$error}}</code>
          </form>
        </file>
      </example>
## Range Input with ngMin & ngMax attributes
@example
      <example name="range-input-directive-ng" module="rangeExample">
        <file name="index.html">
          <script>
            angular.module('rangeExample', [])
              .controller('ExampleController', ['$scope', function($scope) {
                $scope.value = 75;
                $scope.min = 10;
                $scope.max = 90;
              }]);
          </script>
          <form name="myForm" ng-controller="ExampleController">
            Model as range: <input type="range" name="range" ng-model="value" ng-min="min" ng-max="max">
            <hr>
            Model as number: <input type="number" ng-model="value"><br>
            Min: <input type="number" ng-model="min"><br>
            Max: <input type="number" ng-model="max"><br>
            value = <code>{{value}}</code><br/>
            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
            myForm.range.$error = <code>{{myForm.range.$error}}</code>
          </form>
        </file>
      </example>