text: /*! 
   * angular-loading-bar v0.6.0
   * https://chieffancypants.github.io/angular-loading-bar
   * Copyright (c) 2014 Wes Cruver
   * License: MIT
   */
  /*
   * angular-loading-bar
   *
   * intercepts XHR requests and creates a loading bar.
   * Based on the excellent nprogress work by rstacruz (more info in readme)
   *
   * (c) 2013 Wes Cruver
   * License: MIT
   */
  
  
  (function() {
  
  'use strict';
  
  // Alias the loading bar for various backwards compatibilities since the project has matured:
  angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']);
  angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']);
  
  
  /**
   * loadingBarInterceptor service
   *
   * Registers itself as an Angular interceptor and listens for XHR requests.
   */
  angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar'])
    .config(['$httpProvider', function ($httpProvider) {
  
      var interceptor = ['$q', '$cacheFactory', '$timeout', '$rootScope', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, cfpLoadingBar) {
  
        /**
         * The total number of requests made
         */
        var reqsTotal = 0;
  
        /**
         * The number of requests completed (either successfully or not)
         */
        var reqsCompleted = 0;
  
        /**
         * The amount of time spent fetching before showing the loading bar
         */
        var latencyThreshold = cfpLoadingBar.latencyThreshold;
  
        /**
         * $timeout handle for latencyThreshold
         */
        var startTimeout;
  
  
        /**
         * calls cfpLoadingBar.complete() which removes the
         * loading bar from the DOM.
         */
        function setComplete() {
          $timeout.cancel(startTimeout);
          cfpLoadingBar.complete();
          reqsCompleted = 0;
          reqsTotal = 0;
        }
  
        /**
         * Determine if the response has already been cached
         * @param  {Object}  config the config option from the request
         * @return {Boolean} retrns true if cached, otherwise false
         */
        function isCached(config) {
          var cache;
          var defaultCache = $cacheFactory.get('$http');
          var defaults = $httpProvider.defaults;
  
          // Choose the proper cache source. Borrowed from angular: $http service
          if ((config.cache || defaults.cache) && config.cache !== false &&
            (config.method === 'GET' || config.method === 'JSONP')) {
              cache = angular.isObject(config.cache) ? config.cache
                : angular.isObject(defaults.cache) ? defaults.cache
                : defaultCache;
          }
  
          var cached = cache !== undefined ?
            cache.get(config.url) !== undefined : false;
  
          if (config.cached !== undefined && cached !== config.cached) {
            return config.cached;
          }
          config.cached = cached;
          return cached;
        }
  
  
        return {
          'request': function(config) {
            // Check to make sure this request hasn't already been cached and that
            // the requester didn't explicitly ask us to ignore this request:
            if (!config.ignoreLoadingBar && !isCached(config)) {
              $rootScope.$broadcast('cfpLoadingBar:loading', {url: config.url});
              if (reqsTotal === 0) {
                startTimeout = $timeout(function() {
                  cfpLoadingBar.start();
                }, latencyThreshold);
              }
              reqsTotal++;
              cfpLoadingBar.set(reqsCompleted / reqsTotal);
            }
            return config;
          },
  
          'response': function(response) {
            if (!response.config.ignoreLoadingBar && !isCached(response.config)) {
              reqsCompleted++;
              $rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url});
              if (reqsCompleted >= reqsTotal) {
                setComplete();
              } else {
                cfpLoadingBar.set(reqsCompleted / reqsTotal);
              }
            }
            return response;
          },
  
          'responseError': function(rejection) {
            if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) {
              reqsCompleted++;
              $rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url});
              if (reqsCompleted >= reqsTotal) {
                setComplete();
              } else {
                cfpLoadingBar.set(reqsCompleted / reqsTotal);
              }
            }
            return $q.reject(rejection);
          }
        };
      }];
  
      $httpProvider.interceptors.push(interceptor);
    }]);
  
  
  /**
   * Loading Bar
   *
   * This service handles adding and removing the actual element in the DOM.
   * Generally, best practices for DOM manipulation is to take place in a
   * directive, but because the element itself is injected in the DOM only upon
   * XHR requests, and it's likely needed on every view, the best option is to
   * use a service.
   */
  angular.module('cfp.loadingBar', [])
    .provider('cfpLoadingBar', function() {
  
      this.includeSpinner = true;
      this.includeBar = true;
      this.latencyThreshold = 100;
      this.startSize = 0.02;
      this.parentSelector = 'body';
      this.loadingBarColor = '#29d';
      this.spinnerColor = '#29d';
      this.spinnerTemplate = '<div id="loading-bar-spinner"><div class="spinner-icon"></div></div>';
      this.loadingBarTemplate = '<div id="loading-bar"><div class="bar"><div class="peg"></div></div></div>';
  
      this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) {
        var $animate;
        var $parentSelector = this.parentSelector,
          loadingBarContainer = angular.element(this.loadingBarTemplate),
          loadingBar = loadingBarContainer.find('div').eq(0),
          spinner = angular.element(this.spinnerTemplate),
          loadingBarColor = this.loadingBarColor,
          spinnerColor = this.spinnerColor
  
        var incTimeout,
          completeTimeout,
          started = false,
          status = 0;
  
        var includeSpinner = this.includeSpinner;
        var includeBar = this.includeBar;
        var startSize = this.startSize;
  
        /**
         * Inserts the loading bar element into the dom, and sets it to 2%
         */
        function _start() {
          if (!$animate) {         
            $animate = $injector.get('$animate');
          }
  
          var $parent = $document.find($parentSelector).eq(0);
          $timeout.cancel(completeTimeout);
  
          // do not continually broadcast the started event:
          if (started) {
            return;
          }
  
          $rootScope.$broadcast('cfpLoadingBar:started');
          started = true;
  
          if (includeBar) {          
            $animate.enter(loadingBarContainer, $parent);                    
            document.body.querySelector($parentSelector + ">div#loading-bar>.bar").style.backgroundColor = loadingBarColor;
            document.body.querySelector($parentSelector + ">div#loading-bar>.bar>.peg").style.boxShadowColor = loadingBarColor;          
            
          }
  
          if (includeSpinner) {
            $animate.enter(spinner, $parent);
            document.body.querySelector($parentSelector + ">div#loading-bar-spinner>.spinner-icon").style.borderTopColor = spinnerColor;
            document.body.querySelector($parentSelector + ">div#loading-bar-spinner>.spinner-icon").style.borderLeftColor = spinnerColor;
          }
  
          _set(startSize);
        }
  
        /**
         * Set the loading bar's width to a certain percent.
         *
         * @param n any value between 0 and 1
         */
        function _set(n) {
          if (!started) {
            return;
          }
          var pct = (n * 100) + '%';
          loadingBar.css('width', pct);
          status = n;
  
          // increment loadingbar to give the illusion that there is always
          // progress but make sure to cancel the previous timeouts so we don't
          // have multiple incs running at the same time.
          $timeout.cancel(incTimeout);
          incTimeout = $timeout(function() {
            _inc();
          }, 250);
        }
  
        /**
         * Increments the loading bar by a random amount
         * but slows down as it progresses
         */
        function _inc() {
          if (_status() >= 1) {
            return;
          }
  
          var rnd = 0;
  
          // TODO: do this mathmatically instead of through conditions
  
          var stat = _status();
          if (stat >= 0 && stat < 0.25) {
            // Start out between 3 - 6% increments
            rnd = (Math.random() * (5 - 3 + 1) + 3) / 100;
          } else if (stat >= 0.25 && stat < 0.65) {
            // increment between 0 - 3%
            rnd = (Math.random() * 3) / 100;
          } else if (stat >= 0.65 && stat < 0.9) {
            // increment between 0 - 2%
            rnd = (Math.random() * 2) / 100;
          } else if (stat >= 0.9 && stat < 0.99) {
            // finally, increment it .5 %
            rnd = 0.005;
          } else {
            // after 99%, don't increment:
            rnd = 0;
          }
  
          var pct = _status() + rnd;
          _set(pct);
        }
  
        function _status() {
          return status;
        }
  
        function _completeAnimation() {
          status = 0;
          started = false;
        }
  
        function _complete() {
          if (!$animate) {
            $animate = $injector.get('$animate');
          }
  
          $rootScope.$broadcast('cfpLoadingBar:completed');
          _set(1);
  
          $timeout.cancel(completeTimeout);
  
          // Attempt to aggregate any start/complete calls within 500ms:
          completeTimeout = $timeout(function() {
            var promise = $animate.leave(loadingBarContainer, _completeAnimation);
            if (promise && promise.then) {
              promise.then(_completeAnimation);
            }
            $animate.leave(spinner);
          }, 500);
        }
  
        return {
          start            : _start,
          set              : _set,
          status           : _status,
          inc              : _inc,
          complete         : _complete,
          includeSpinner   : this.includeSpinner,
          latencyThreshold : this.latencyThreshold,
          parentSelector   : this.parentSelector,
          startSize        : this.startSize
        };
  
  
      }];     //
    });       // wtf javascript. srsly
  })();       //
  