text: // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  
  ;(function (factory) {
      var objectTypes = {
          'boolean': false,
          'function': true,
          'object': true,
          'number': false,
          'string': false,
          'undefined': false
      };
  
      var root = (objectTypes[typeof window] && window) || this,
          freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
          freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
          moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
          freeGlobal = objectTypes[typeof global] && global;
  
      if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
          root = freeGlobal;
      }
  
      // Because of build optimizers
      if (typeof define === 'function' && define.amd) {
          define(['rx-lite'], function (Rx, exports) {
              return factory(root, exports, Rx);
          });
      } else if (typeof module === 'object' && module && module.exports === freeExports) {
          module.exports = factory(root, module.exports, require('rx-lite'));
      } else {
          root.Rx = factory(root, {}, root.Rx);
      }
  }.call(this, function (root, exp, Rx, undefined) {
  
    // References
    var Observable = Rx.Observable,
      observableProto = Observable.prototype,
      AnonymousObservable = Rx.AnonymousObservable,
      AbstractObserver = Rx.internals.AbstractObserver,
      CompositeDisposable = Rx.CompositeDisposable,
      Notification = Rx.Notification,
      Subject = Rx.Subject,
      Observer = Rx.Observer,
      disposableEmpty = Rx.Disposable.empty,
      disposableCreate = Rx.Disposable.create,
      inherits = Rx.internals.inherits,
      addProperties = Rx.internals.addProperties,
      timeoutScheduler = Rx.Scheduler.timeout,
      currentThreadScheduler = Rx.Scheduler.currentThread,
      identity = Rx.helpers.identity,
      isScheduler = Rx.Scheduler.isScheduler,
      isFunction = Rx.helpers.isFunction,
      checkDisposed = Rx.Disposable.checkDisposed;
  
    var errorObj = {e: {}};
    var tryCatchTarget;
    function tryCatcher() {
      try {
        return tryCatchTarget.apply(this, arguments);
      } catch (e) {
        errorObj.e = e;
        return errorObj;
      }
    }
    function tryCatch(fn) {
      if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
      tryCatchTarget = fn;
      return tryCatcher;
    }
    function thrower(e) {
      throw e;
    }
  
    var StopAndWaitObservable = (function (__super__) {
  
      function subscribe (observer) {
        this.subscription = this.source.subscribe(new StopAndWaitObserver(observer, this, this.subscription));
  
        var self = this;
        timeoutScheduler.schedule(function () { self.source.request(1); });
  
        return this.subscription;
      }
  
      inherits(StopAndWaitObservable, __super__);
  
      function StopAndWaitObservable (source) {
        __super__.call(this, subscribe, source);
        this.source = source;
      }
  
      var StopAndWaitObserver = (function (__sub__) {
  
        inherits(StopAndWaitObserver, __sub__);
  
        function StopAndWaitObserver (observer, observable, cancel) {
          __sub__.call(this);
          this.observer = observer;
          this.observable = observable;
          this.cancel = cancel;
        }
  
        var stopAndWaitObserverProto = StopAndWaitObserver.prototype;
  
        stopAndWaitObserverProto.completed = function () {
          this.observer.onCompleted();
          this.dispose();
        };
  
        stopAndWaitObserverProto.error = function (error) {
          this.observer.onError(error);
          this.dispose();
        }
  
        stopAndWaitObserverProto.next = function (value) {
          this.observer.onNext(value);
  
          var self = this;
          timeoutScheduler.schedule(function () {
            self.observable.source.request(1);
          });
        };
  
        stopAndWaitObserverProto.dispose = function () {
          this.observer = null;
          if (this.cancel) {
            this.cancel.dispose();
            this.cancel = null;
          }
          __sub__.prototype.dispose.call(this);
        };
  
        return StopAndWaitObserver;
      }(AbstractObserver));
  
      return StopAndWaitObservable;
    }(Observable));
  
  
    /**
     * Attaches a stop and wait observable to the current observable.
     * @returns {Observable} A stop and wait observable.
     */
    ControlledObservable.prototype.stopAndWait = function () {
      return new StopAndWaitObservable(this);
    };
  
    var WindowedObservable = (function (__super__) {
  
      function subscribe (observer) {
        this.subscription = this.source.subscribe(new WindowedObserver(observer, this, this.subscription));
  
        var self = this;
        timeoutScheduler.schedule(function () {
          self.source.request(self.windowSize);
        });
  
        return this.subscription;
      }
  
      inherits(WindowedObservable, __super__);
  
      function WindowedObservable(source, windowSize) {
        __super__.call(this, subscribe, source);
        this.source = source;
        this.windowSize = windowSize;
      }
  
      var WindowedObserver = (function (__sub__) {
  
        inherits(WindowedObserver, __sub__);
  
        function WindowedObserver(observer, observable, cancel) {
          this.observer = observer;
          this.observable = observable;
          this.cancel = cancel;
          this.received = 0;
        }
  
        var windowedObserverPrototype = WindowedObserver.prototype;
  
        windowedObserverPrototype.completed = function () {
          this.observer.onCompleted();
          this.dispose();
        };
  
        windowedObserverPrototype.error = function (error) {
          this.observer.onError(error);
          this.dispose();
        };
  
        windowedObserverPrototype.next = function (value) {
          this.observer.onNext(value);
  
          this.received = ++this.received % this.observable.windowSize;
          if (this.received === 0) {
            var self = this;
            timeoutScheduler.schedule(function () {
              self.observable.source.request(self.observable.windowSize);
            });
          }
        };
  
        windowedObserverPrototype.dispose = function () {
          this.observer = null;
          if (this.cancel) {
            this.cancel.dispose();
            this.cancel = null;
          }
          __sub__.prototype.dispose.call(this);
        };
  
        return WindowedObserver;
      }(AbstractObserver));
  
      return WindowedObservable;
    }(Observable));
  
    /**
     * Creates a sliding windowed observable based upon the window size.
     * @param {Number} windowSize The number of items in the window
     * @returns {Observable} A windowed observable based upon the window size.
     */
    ControlledObservable.prototype.windowed = function (windowSize) {
      return new WindowedObservable(this, windowSize);
    };
  
      return Rx;
  }));
  