{"banner":"/*\n * @workpoint/angular-ui-bootstrap\n * http://angular-ui.github.io/bootstrap/\n\n * Version: 2.5.9 - 2019-10-18\n * License: MIT\n */","cssBanner":"/* Include this file in your html if you are using the CSP mode. */\n\n","files":{"src/collapse/collapse.js":"angular.module('ui.bootstrap.collapse', [])\n\n  .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) {\n    var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null;\n    return {\n      link: function(scope, element, attrs) {\n        var expandingExpr = $parse(attrs.expanding),\n          expandedExpr = $parse(attrs.expanded),\n          collapsingExpr = $parse(attrs.collapsing),\n          collapsedExpr = $parse(attrs.collapsed),\n          horizontal = false,\n          css = {},\n          cssTo = {};\n\n        init();\n\n        function init() {\n          horizontal = !!('horizontal' in attrs);\n          if (horizontal) {\n            css = {\n              width: ''\n            };\n            cssTo = {width: '0'};\n          } else {\n            css = {\n              height: ''\n            };\n            cssTo = {height: '0'};\n          }\n          if (!scope.$eval(attrs.uibCollapse)) {\n            element.addClass('in')\n              .addClass('collapse')\n              .attr('aria-expanded', true)\n              .attr('aria-hidden', false)\n              .css(css);\n          }\n        }\n\n        function getScrollFromElement(element) {\n          if (horizontal) {\n            return {width: element.scrollWidth + 'px'};\n          }\n          return {height: element.scrollHeight + 'px'};\n        }\n\n        function expand() {\n          if (element.hasClass('collapse') && element.hasClass('in')) {\n            return;\n          }\n\n          $q.resolve(expandingExpr(scope))\n            .then(function() {\n              element.removeClass('collapse')\n                .addClass('collapsing')\n                .attr('aria-expanded', true)\n                .attr('aria-hidden', false);\n\n              if ($animateCss) {\n                $animateCss(element, {\n                  addClass: 'in',\n                  easing: 'ease',\n                  css: {\n                    overflow: 'hidden'\n                  },\n                  to: getScrollFromElement(element[0])\n                }).start()['finally'](expandDone);\n              } else {\n                $animate.addClass(element, 'in', {\n                  css: {\n                    overflow: 'hidden'\n                  },\n                  to: getScrollFromElement(element[0])\n                }).then(expandDone);\n              }\n            }, angular.noop);\n        }\n\n        function expandDone() {\n          element.removeClass('collapsing')\n            .addClass('collapse')\n            .css(css);\n          expandedExpr(scope);\n        }\n\n        function collapse() {\n          if (!element.hasClass('collapse') && !element.hasClass('in')) {\n            return collapseDone();\n          }\n\n          $q.resolve(collapsingExpr(scope))\n            .then(function() {\n              element\n              // IMPORTANT: The width must be set before adding \"collapsing\" class.\n              // Otherwise, the browser attempts to animate from width 0 (in\n              // collapsing class) to the given width here.\n                .css(getScrollFromElement(element[0]))\n                // initially all panel collapse have the collapse class, this removal\n                // prevents the animation from jumping to collapsed state\n                .removeClass('collapse')\n                .addClass('collapsing')\n                .attr('aria-expanded', false)\n                .attr('aria-hidden', true);\n\n              if ($animateCss) {\n                $animateCss(element, {\n                  removeClass: 'in',\n                  to: cssTo\n                }).start()['finally'](collapseDone);\n              } else {\n                $animate.removeClass(element, 'in', {\n                  to: cssTo\n                }).then(collapseDone);\n              }\n            }, angular.noop);\n        }\n\n        function collapseDone() {\n          element.css(cssTo); // Required so that collapse works when animation is disabled\n          element.removeClass('collapsing')\n            .addClass('collapse');\n          collapsedExpr(scope);\n        }\n\n        scope.$watch(attrs.uibCollapse, function(shouldCollapse) {\n          if (shouldCollapse) {\n            collapse();\n          } else {\n            expand();\n          }\n        });\n      }\n    };\n  }]);\n","src/tabindex/tabindex.js":"angular.module('ui.bootstrap.tabindex', [])\n\n.directive('uibTabindexToggle', function() {\n  return {\n    restrict: 'A',\n    link: function(scope, elem, attrs) {\n      attrs.$observe('disabled', function(disabled) {\n        attrs.$set('tabindex', disabled ? -1 : null);\n      });\n    }\n  };\n});\n","src/accordion/accordion.js":"angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse', 'ui.bootstrap.tabindex'])\n\n.constant('uibAccordionConfig', {\n  closeOthers: true\n})\n\n.controller('UibAccordionController', ['$scope', '$attrs', 'uibAccordionConfig', function($scope, $attrs, accordionConfig) {\n  // This array keeps track of the accordion groups\n  this.groups = [];\n\n  // Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to\n  this.closeOthers = function(openGroup) {\n    var closeOthers = angular.isDefined($attrs.closeOthers) ?\n      $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;\n    if (closeOthers) {\n      angular.forEach(this.groups, function(group) {\n        if (group !== openGroup) {\n          group.isOpen = false;\n        }\n      });\n    }\n  };\n\n  // This is called from the accordion-group directive to add itself to the accordion\n  this.addGroup = function(groupScope) {\n    var that = this;\n    this.groups.push(groupScope);\n\n    groupScope.$on('$destroy', function(event) {\n      that.removeGroup(groupScope);\n    });\n  };\n\n  // This is called from the accordion-group directive when to remove itself\n  this.removeGroup = function(group) {\n    var index = this.groups.indexOf(group);\n    if (index !== -1) {\n      this.groups.splice(index, 1);\n    }\n  };\n}])\n\n// The accordion directive simply sets up the directive controller\n// and adds an accordion CSS class to itself element.\n.directive('uibAccordion', function() {\n  return {\n    controller: 'UibAccordionController',\n    controllerAs: 'accordion',\n    transclude: true,\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/accordion/accordion.html';\n    }\n  };\n})\n\n// The accordion-group directive indicates a block of html that will expand and collapse in an accordion\n.directive('uibAccordionGroup', function() {\n  return {\n    require: '^uibAccordion',         // We need this directive to be inside an accordion\n    transclude: true,              // It transcludes the contents of the directive into the template\n    restrict: 'A',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/accordion/accordion-group.html';\n    },\n    scope: {\n      heading: '@',               // Interpolate the heading attribute onto this scope\n      panelClass: '@?',           // Ditto with panelClass\n      isOpen: '=?',\n      isDisabled: '=?'\n    },\n    controller: function() {\n      this.setHeading = function(element) {\n        this.heading = element;\n      };\n    },\n    link: function(scope, element, attrs, accordionCtrl) {\n      element.addClass('panel');\n      accordionCtrl.addGroup(scope);\n\n      scope.openClass = attrs.openClass || 'panel-open';\n      scope.panelClass = attrs.panelClass || 'panel-default';\n      scope.$watch('isOpen', function(value) {\n        element.toggleClass(scope.openClass, !!value);\n        if (value) {\n          accordionCtrl.closeOthers(scope);\n        }\n      });\n\n      scope.toggleOpen = function($event) {\n        if (!scope.isDisabled) {\n          if (!$event || $event.which === 32) {\n            scope.isOpen = !scope.isOpen;\n          }\n        }\n      };\n\n      var id = 'accordiongroup-' + scope.$id + '-' + Math.floor(Math.random() * 10000);\n      scope.headingId = id + '-tab';\n      scope.panelId = id + '-panel';\n    }\n  };\n})\n\n// Use accordion-heading below an accordion-group to provide a heading containing HTML\n.directive('uibAccordionHeading', function() {\n  return {\n    transclude: true,   // Grab the contents to be used as the heading\n    template: '',       // In effect remove this element!\n    replace: true,\n    require: '^uibAccordionGroup',\n    link: function(scope, element, attrs, accordionGroupCtrl, transclude) {\n      // Pass the heading to the accordion-group controller\n      // so that it can be transcluded into the right place in the template\n      // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]\n      accordionGroupCtrl.setHeading(transclude(scope, angular.noop));\n    }\n  };\n})\n\n// Use in the accordion-group template to indicate where you want the heading to be transcluded\n// You must provide the property on the accordion-group controller that will hold the transcluded element\n.directive('uibAccordionTransclude', function() {\n  return {\n    require: '^uibAccordionGroup',\n    link: function(scope, element, attrs, controller) {\n      scope.$watch(function() { return controller[attrs.uibAccordionTransclude]; }, function(heading) {\n        if (heading) {\n          var elem = angular.element(element[0].querySelector(getHeaderSelectors()));\n          elem.html('');\n          elem.append(heading);\n        }\n      });\n    }\n  };\n\n  function getHeaderSelectors() {\n      return 'uib-accordion-header,' +\n          'data-uib-accordion-header,' +\n          'x-uib-accordion-header,' +\n          'uib\\\\:accordion-header,' +\n          '[uib-accordion-header],' +\n          '[data-uib-accordion-header],' +\n          '[x-uib-accordion-header]';\n  }\n});\n","src/alert/alert.js":"angular.module('ui.bootstrap.alert', [])\n\n.controller('UibAlertController', ['$scope', '$element', '$attrs', '$interpolate', '$timeout', function($scope, $element, $attrs, $interpolate, $timeout) {\n  $scope.closeable = !!$attrs.close;\n  $element.addClass('alert');\n  $attrs.$set('role', 'alert');\n  if ($scope.closeable) {\n    $element.addClass('alert-dismissible');\n  }\n\n  var dismissOnTimeout = angular.isDefined($attrs.dismissOnTimeout) ?\n    $interpolate($attrs.dismissOnTimeout)($scope.$parent) : null;\n\n  if (dismissOnTimeout) {\n    $timeout(function() {\n      $scope.close();\n    }, parseInt(dismissOnTimeout, 10));\n  }\n}])\n\n.directive('uibAlert', function() {\n  return {\n    controller: 'UibAlertController',\n    controllerAs: 'alert',\n    restrict: 'A',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/alert/alert.html';\n    },\n    transclude: true,\n    scope: {\n      close: '&'\n    }\n  };\n});\n","src/buttons/buttons.js":"angular.module('ui.bootstrap.buttons', [])\n\n.constant('uibButtonConfig', {\n  activeClass: 'active',\n  toggleEvent: 'click'\n})\n\n.controller('UibButtonsController', ['uibButtonConfig', function(buttonConfig) {\n  this.activeClass = buttonConfig.activeClass || 'active';\n  this.toggleEvent = buttonConfig.toggleEvent || 'click';\n}])\n\n.directive('uibBtnRadio', ['$parse', function($parse) {\n  return {\n    require: ['uibBtnRadio', 'ngModel'],\n    controller: 'UibButtonsController',\n    controllerAs: 'buttons',\n    link: function(scope, element, attrs, ctrls) {\n      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n      var uncheckableExpr = $parse(attrs.uibUncheckable);\n\n      element.find('input').css({display: 'none'});\n\n      //model -> UI\n      ngModelCtrl.$render = function() {\n        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.uibBtnRadio)));\n      };\n\n      //ui->model\n      element.on(buttonsCtrl.toggleEvent, function() {\n        if (attrs.disabled) {\n          return;\n        }\n\n        var isActive = element.hasClass(buttonsCtrl.activeClass);\n\n        if (!isActive || angular.isDefined(attrs.uncheckable)) {\n          scope.$apply(function() {\n            ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.uibBtnRadio));\n            ngModelCtrl.$render();\n          });\n        }\n      });\n\n      if (attrs.uibUncheckable) {\n        scope.$watch(uncheckableExpr, function(uncheckable) {\n          attrs.$set('uncheckable', uncheckable ? '' : undefined);\n        });\n      }\n    }\n  };\n}])\n\n.directive('uibBtnCheckbox', function() {\n  return {\n    require: ['uibBtnCheckbox', 'ngModel'],\n    controller: 'UibButtonsController',\n    controllerAs: 'button',\n    link: function(scope, element, attrs, ctrls) {\n      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n\n      element.find('input').css({display: 'none'});\n\n      function getTrueValue() {\n        return getCheckboxValue(attrs.btnCheckboxTrue, true);\n      }\n\n      function getFalseValue() {\n        return getCheckboxValue(attrs.btnCheckboxFalse, false);\n      }\n\n      function getCheckboxValue(attribute, defaultValue) {\n        return angular.isDefined(attribute) ? scope.$eval(attribute) : defaultValue;\n      }\n\n      //model -> UI\n      ngModelCtrl.$render = function() {\n        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));\n      };\n\n      //ui->model\n      element.on(buttonsCtrl.toggleEvent, function() {\n        if (attrs.disabled) {\n          return;\n        }\n\n        scope.$apply(function() {\n          ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());\n          ngModelCtrl.$render();\n        });\n      });\n    }\n  };\n});\n","src/carousel/carousel.js":"angular.module('ui.bootstrap.carousel', [])\n\n.controller('UibCarouselController', ['$scope', '$element', '$interval', '$timeout', '$animate', function($scope, $element, $interval, $timeout, $animate) {\n  var self = this,\n    slides = self.slides = $scope.slides = [],\n    SLIDE_DIRECTION = 'uib-slideDirection',\n    currentIndex = $scope.active,\n    currentInterval, isPlaying;\n\n  var destroyed = false;\n  $element.addClass('carousel');\n\n  self.addSlide = function(slide, element) {\n    slides.push({\n      slide: slide,\n      element: element\n    });\n    slides.sort(function(a, b) {\n      return +a.slide.index - +b.slide.index;\n    });\n    //if this is the first slide or the slide is set to active, select it\n    if (slide.index === $scope.active || slides.length === 1 && !angular.isNumber($scope.active)) {\n      if ($scope.$currentTransition) {\n        $scope.$currentTransition = null;\n      }\n\n      currentIndex = slide.index;\n      $scope.active = slide.index;\n      setActive(currentIndex);\n      self.select(slides[findSlideIndex(slide)]);\n      if (slides.length === 1) {\n        $scope.play();\n      }\n    }\n  };\n\n  self.getCurrentIndex = function() {\n    for (var i = 0; i < slides.length; i++) {\n      if (slides[i].slide.index === currentIndex) {\n        return i;\n      }\n    }\n  };\n\n  self.next = $scope.next = function() {\n    var newIndex = (self.getCurrentIndex() + 1) % slides.length;\n\n    if (newIndex === 0 && $scope.noWrap()) {\n      $scope.pause();\n      return;\n    }\n\n    return self.select(slides[newIndex], 'next');\n  };\n\n  self.prev = $scope.prev = function() {\n    var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1;\n\n    if ($scope.noWrap() && newIndex === slides.length - 1) {\n      $scope.pause();\n      return;\n    }\n\n    return self.select(slides[newIndex], 'prev');\n  };\n\n  self.removeSlide = function(slide) {\n    var index = findSlideIndex(slide);\n\n    //get the index of the slide inside the carousel\n    slides.splice(index, 1);\n    if (slides.length > 0 && currentIndex === index) {\n      if (index >= slides.length) {\n        currentIndex = slides.length - 1;\n        $scope.active = currentIndex;\n        setActive(currentIndex);\n        self.select(slides[slides.length - 1]);\n      } else {\n        currentIndex = index;\n        $scope.active = currentIndex;\n        setActive(currentIndex);\n        self.select(slides[index]);\n      }\n    } else if (currentIndex > index) {\n      currentIndex--;\n      $scope.active = currentIndex;\n    }\n\n    //clean the active value when no more slide\n    if (slides.length === 0) {\n      currentIndex = null;\n      $scope.active = null;\n    }\n  };\n\n  /* direction: \"prev\" or \"next\" */\n  self.select = $scope.select = function(nextSlide, direction) {\n    var nextIndex = findSlideIndex(nextSlide.slide);\n    //Decide direction if it's not given\n    if (direction === undefined) {\n      direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev';\n    }\n    //Prevent this user-triggered transition from occurring if there is already one in progress\n    if (nextSlide.slide.index !== currentIndex &&\n      !$scope.$currentTransition) {\n      goNext(nextSlide.slide, nextIndex, direction);\n    }\n  };\n\n  /* Allow outside people to call indexOf on slides array */\n  $scope.indexOfSlide = function(slide) {\n    return +slide.slide.index;\n  };\n\n  $scope.isActive = function(slide) {\n    return $scope.active === slide.slide.index;\n  };\n\n  $scope.isPrevDisabled = function() {\n    return $scope.active === 0 && $scope.noWrap();\n  };\n\n  $scope.isNextDisabled = function() {\n    return $scope.active === slides.length - 1 && $scope.noWrap();\n  };\n\n  $scope.pause = function() {\n    if (!$scope.noPause) {\n      isPlaying = false;\n      resetTimer();\n    }\n  };\n\n  $scope.play = function() {\n    if (!isPlaying) {\n      isPlaying = true;\n      restartTimer();\n    }\n  };\n\n  $element.on('mouseenter', $scope.pause);\n  $element.on('mouseleave', $scope.play);\n\n  $scope.$on('$destroy', function() {\n    destroyed = true;\n    resetTimer();\n  });\n\n  $scope.$watch('noTransition', function(noTransition) {\n    $animate.enabled($element, !noTransition);\n  });\n\n  $scope.$watch('interval', restartTimer);\n\n  $scope.$watchCollection('slides', resetTransition);\n\n  $scope.$watch('active', function(index) {\n    if (angular.isNumber(index) && currentIndex !== index) {\n      for (var i = 0; i < slides.length; i++) {\n        if (slides[i].slide.index === index) {\n          index = i;\n          break;\n        }\n      }\n\n      var slide = slides[index];\n      if (slide) {\n        setActive(index);\n        self.select(slides[index]);\n        currentIndex = index;\n      }\n    }\n  });\n\n  function getSlideByIndex(index) {\n    for (var i = 0, l = slides.length; i < l; ++i) {\n      if (slides[i].index === index) {\n        return slides[i];\n      }\n    }\n  }\n\n  function setActive(index) {\n    for (var i = 0; i < slides.length; i++) {\n      slides[i].slide.active = i === index;\n    }\n  }\n\n  function goNext(slide, index, direction) {\n    if (destroyed) {\n      return;\n    }\n\n    angular.extend(slide, {direction: direction});\n    angular.extend(slides[currentIndex].slide || {}, {direction: direction});\n    if ($animate.enabled($element) && !$scope.$currentTransition &&\n      slides[index].element && self.slides.length > 1) {\n      slides[index].element.data(SLIDE_DIRECTION, slide.direction);\n      var currentIdx = self.getCurrentIndex();\n\n      if (angular.isNumber(currentIdx) && slides[currentIdx].element) {\n        slides[currentIdx].element.data(SLIDE_DIRECTION, slide.direction);\n      }\n\n      $scope.$currentTransition = true;\n      $animate.on('addClass', slides[index].element, function(element, phase) {\n        if (phase === 'close') {\n          $scope.$currentTransition = null;\n          $animate.off('addClass', element);\n        }\n      });\n    }\n\n    $scope.active = slide.index;\n    currentIndex = slide.index;\n    setActive(index);\n\n    //every time you change slides, reset the timer\n    restartTimer();\n  }\n\n  function findSlideIndex(slide) {\n    for (var i = 0; i < slides.length; i++) {\n      if (slides[i].slide === slide) {\n        return i;\n      }\n    }\n  }\n\n  function resetTimer() {\n    if (currentInterval) {\n      $interval.cancel(currentInterval);\n      currentInterval = null;\n    }\n  }\n\n  function resetTransition(slides) {\n    if (!slides.length) {\n      $scope.$currentTransition = null;\n    }\n  }\n\n  function restartTimer() {\n    resetTimer();\n    var interval = +$scope.interval;\n    if (!isNaN(interval) && interval > 0) {\n      currentInterval = $interval(timerFn, interval);\n    }\n  }\n\n  function timerFn() {\n    var interval = +$scope.interval;\n    if (isPlaying && !isNaN(interval) && interval > 0 && slides.length) {\n      $scope.next();\n    } else {\n      $scope.pause();\n    }\n  }\n}])\n\n.directive('uibCarousel', function() {\n  return {\n    transclude: true,\n    controller: 'UibCarouselController',\n    controllerAs: 'carousel',\n    restrict: 'A',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/carousel/carousel.html';\n    },\n    scope: {\n      active: '=',\n      interval: '=',\n      noTransition: '=',\n      noPause: '=',\n      noWrap: '&'\n    }\n  };\n})\n\n.directive('uibSlide', ['$animate', function($animate) {\n  return {\n    require: '^uibCarousel',\n    restrict: 'A',\n    transclude: true,\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/carousel/slide.html';\n    },\n    scope: {\n      actual: '=?',\n      index: '=?'\n    },\n    link: function (scope, element, attrs, carouselCtrl) {\n      element.addClass('item');\n      carouselCtrl.addSlide(scope, element);\n      //when the scope is destroyed then remove the slide from the current slides array\n      scope.$on('$destroy', function() {\n        carouselCtrl.removeSlide(scope);\n      });\n\n      scope.$watch('active', function(active) {\n        $animate[active ? 'addClass' : 'removeClass'](element, 'active');\n      });\n    }\n  };\n}])\n\n.animation('.item', ['$animateCss',\nfunction($animateCss) {\n  var SLIDE_DIRECTION = 'uib-slideDirection';\n\n  function removeClass(element, className, callback) {\n    element.removeClass(className);\n    if (callback) {\n      callback();\n    }\n  }\n\n  return {\n    beforeAddClass: function(element, className, done) {\n      if (className === 'active') {\n        var stopped = false;\n        var direction = element.data(SLIDE_DIRECTION);\n        var directionClass = direction === 'next' ? 'left' : 'right';\n        var removeClassFn = removeClass.bind(this, element,\n          directionClass + ' ' + direction, done);\n        element.addClass(direction);\n\n        $animateCss(element, {addClass: directionClass})\n          .start()\n          .done(removeClassFn);\n\n        return function() {\n          stopped = true;\n        };\n      }\n      done();\n    },\n    beforeRemoveClass: function (element, className, done) {\n      if (className === 'active') {\n        var stopped = false;\n        var direction = element.data(SLIDE_DIRECTION);\n        var directionClass = direction === 'next' ? 'left' : 'right';\n        var removeClassFn = removeClass.bind(this, element, directionClass, done);\n\n        $animateCss(element, {addClass: directionClass})\n          .start()\n          .done(removeClassFn);\n\n        return function() {\n          stopped = true;\n        };\n      }\n      done();\n    }\n  };\n}]);\n","src/dateparser/dateparser.js":"angular.module('ui.bootstrap.dateparser', [])\n\n.service('uibDateParser', ['$log', '$locale', 'dateFilter', 'orderByFilter', 'filterFilter', function($log, $locale, dateFilter, orderByFilter, filterFilter) {\n  // Pulled from https://github.com/mbostock/d3/blob/master/src/format/requote.js\n  var SPECIAL_CHARACTERS_REGEXP = /[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;\n\n  var localeId;\n  var formatCodeToRegex;\n\n  this.init = function() {\n    localeId = $locale.id;\n\n    this.parsers = {};\n    this.formatters = {};\n\n    formatCodeToRegex = [\n      {\n        key: 'yyyy',\n        regex: '\\\\d{4}',\n        apply: function(value) { this.year = +value; },\n        formatter: function(date) {\n          var _date = new Date();\n          _date.setFullYear(Math.abs(date.getFullYear()));\n          return dateFilter(_date, 'yyyy');\n        }\n      },\n      {\n        key: 'yy',\n        regex: '\\\\d{2}',\n        apply: function(value) { value = +value; this.year = value < 69 ? value + 2000 : value + 1900; },\n        formatter: function(date) {\n          var _date = new Date();\n          _date.setFullYear(Math.abs(date.getFullYear()));\n          return dateFilter(_date, 'yy');\n        }\n      },\n      {\n        key: 'y',\n        regex: '\\\\d{1,4}',\n        apply: function(value) { this.year = +value; },\n        formatter: function(date) {\n          var _date = new Date();\n          _date.setFullYear(Math.abs(date.getFullYear()));\n          return dateFilter(_date, 'y');\n        }\n      },\n      {\n        key: 'M!',\n        regex: '0?[1-9]|1[0-2]',\n        apply: function(value) { this.month = value - 1; },\n        formatter: function(date) {\n          var value = date.getMonth();\n          if (/^[0-9]$/.test(value)) {\n            return dateFilter(date, 'MM');\n          }\n\n          return dateFilter(date, 'M');\n        }\n      },\n      {\n        key: 'MMMM',\n        regex: $locale.DATETIME_FORMATS.MONTH.join('|'),\n        apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); },\n        formatter: function(date) { return dateFilter(date, 'MMMM'); }\n      },\n      {\n        key: 'MMM',\n        regex: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n        apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); },\n        formatter: function(date) { return dateFilter(date, 'MMM'); }\n      },\n      {\n        key: 'MM',\n        regex: '0[1-9]|1[0-2]',\n        apply: function(value) { this.month = value - 1; },\n        formatter: function(date) { return dateFilter(date, 'MM'); }\n      },\n      {\n        key: 'M',\n        regex: '[1-9]|1[0-2]',\n        apply: function(value) { this.month = value - 1; },\n        formatter: function(date) { return dateFilter(date, 'M'); }\n      },\n      {\n        key: 'd!',\n        regex: '[0-2]?[0-9]{1}|3[0-1]{1}',\n        apply: function(value) { this.date = +value; },\n        formatter: function(date) {\n          var value = date.getDate();\n          if (/^[1-9]$/.test(value)) {\n            return dateFilter(date, 'dd');\n          }\n\n          return dateFilter(date, 'd');\n        }\n      },\n      {\n        key: 'dd',\n        regex: '[0-2][0-9]{1}|3[0-1]{1}',\n        apply: function(value) { this.date = +value; },\n        formatter: function(date) { return dateFilter(date, 'dd'); }\n      },\n      {\n        key: 'd',\n        regex: '[1-2]?[0-9]{1}|3[0-1]{1}',\n        apply: function(value) { this.date = +value; },\n        formatter: function(date) { return dateFilter(date, 'd'); }\n      },\n      {\n        key: 'EEEE',\n        regex: $locale.DATETIME_FORMATS.DAY.join('|'),\n        formatter: function(date) { return dateFilter(date, 'EEEE'); }\n      },\n      {\n        key: 'EEE',\n        regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n        formatter: function(date) { return dateFilter(date, 'EEE'); }\n      },\n      {\n        key: 'HH',\n        regex: '(?:0|1)[0-9]|2[0-3]',\n        apply: function(value) { this.hours = +value; },\n        formatter: function(date) { return dateFilter(date, 'HH'); }\n      },\n      {\n        key: 'hh',\n        regex: '0[0-9]|1[0-2]',\n        apply: function(value) { this.hours = +value; },\n        formatter: function(date) { return dateFilter(date, 'hh'); }\n      },\n      {\n        key: 'H',\n        regex: '1?[0-9]|2[0-3]',\n        apply: function(value) { this.hours = +value; },\n        formatter: function(date) { return dateFilter(date, 'H'); }\n      },\n      {\n        key: 'h',\n        regex: '[0-9]|1[0-2]',\n        apply: function(value) { this.hours = +value; },\n        formatter: function(date) { return dateFilter(date, 'h'); }\n      },\n      {\n        key: 'mm',\n        regex: '[0-5][0-9]',\n        apply: function(value) { this.minutes = +value; },\n        formatter: function(date) { return dateFilter(date, 'mm'); }\n      },\n      {\n        key: 'm',\n        regex: '[0-9]|[1-5][0-9]',\n        apply: function(value) { this.minutes = +value; },\n        formatter: function(date) { return dateFilter(date, 'm'); }\n      },\n      {\n        key: 'sss',\n        regex: '[0-9][0-9][0-9]',\n        apply: function(value) { this.milliseconds = +value; },\n        formatter: function(date) { return dateFilter(date, 'sss'); }\n      },\n      {\n        key: 'ss',\n        regex: '[0-5][0-9]',\n        apply: function(value) { this.seconds = +value; },\n        formatter: function(date) { return dateFilter(date, 'ss'); }\n      },\n      {\n        key: 's',\n        regex: '[0-9]|[1-5][0-9]',\n        apply: function(value) { this.seconds = +value; },\n        formatter: function(date) { return dateFilter(date, 's'); }\n      },\n      {\n        key: 'a',\n        regex: $locale.DATETIME_FORMATS.AMPMS.join('|'),\n        apply: function(value) {\n          if (this.hours === 12) {\n            this.hours = 0;\n          }\n\n          if (value === 'PM') {\n            this.hours += 12;\n          }\n        },\n        formatter: function(date) { return dateFilter(date, 'a'); }\n      },\n      {\n        key: 'Z',\n        regex: '[+-]\\\\d{4}',\n        apply: function(value) {\n          var matches = value.match(/([+-])(\\d{2})(\\d{2})/),\n            sign = matches[1],\n            hours = matches[2],\n            minutes = matches[3];\n          this.hours += toInt(sign + hours);\n          this.minutes += toInt(sign + minutes);\n        },\n        formatter: function(date) {\n          return dateFilter(date, 'Z');\n        }\n      },\n      {\n        key: 'ww',\n        regex: '[0-4][0-9]|5[0-3]',\n        formatter: function(date) { return dateFilter(date, 'ww'); }\n      },\n      {\n        key: 'w',\n        regex: '[0-9]|[1-4][0-9]|5[0-3]',\n        formatter: function(date) { return dateFilter(date, 'w'); }\n      },\n      {\n        key: 'GGGG',\n        regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\\s/g, '\\\\s'),\n        formatter: function(date) { return dateFilter(date, 'GGGG'); }\n      },\n      {\n        key: 'GGG',\n        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),\n        formatter: function(date) { return dateFilter(date, 'GGG'); }\n      },\n      {\n        key: 'GG',\n        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),\n        formatter: function(date) { return dateFilter(date, 'GG'); }\n      },\n      {\n        key: 'G',\n        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),\n        formatter: function(date) { return dateFilter(date, 'G'); }\n      }\n    ];\n\n    if (angular.version.major >= 1 && angular.version.minor > 4) {\n      formatCodeToRegex.push({\n        key: 'LLLL',\n        regex: $locale.DATETIME_FORMATS.STANDALONEMONTH.join('|'),\n        apply: function(value) { this.month = $locale.DATETIME_FORMATS.STANDALONEMONTH.indexOf(value); },\n        formatter: function(date) { return dateFilter(date, 'LLLL'); }\n      });\n    }\n  };\n\n  this.init();\n\n  function getFormatCodeToRegex(key) {\n    return filterFilter(formatCodeToRegex, {key: key}, true)[0];\n  }\n\n  this.getParser = function (key) {\n    var f = getFormatCodeToRegex(key);\n    return f && f.apply || null;\n  };\n\n  this.overrideParser = function (key, parser) {\n    var f = getFormatCodeToRegex(key);\n    if (f && angular.isFunction(parser)) {\n      this.parsers = {};\n      f.apply = parser;\n    }\n  }.bind(this);\n\n  function createParser(format) {\n    var map = [], regex = format.split('');\n\n    // check for literal values\n    var quoteIndex = format.indexOf('\\'');\n    if (quoteIndex > -1) {\n      var inLiteral = false;\n      format = format.split('');\n      for (var i = quoteIndex; i < format.length; i++) {\n        if (inLiteral) {\n          if (format[i] === '\\'') {\n            if (i + 1 < format.length && format[i+1] === '\\'') { // escaped single quote\n              format[i+1] = '$';\n              regex[i+1] = '';\n            } else { // end of literal\n              regex[i] = '';\n              inLiteral = false;\n            }\n          }\n          format[i] = '$';\n        } else {\n          if (format[i] === '\\'') { // start of literal\n            format[i] = '$';\n            regex[i] = '';\n            inLiteral = true;\n          }\n        }\n      }\n\n      format = format.join('');\n    }\n\n    angular.forEach(formatCodeToRegex, function(data) {\n      var index = format.indexOf(data.key);\n\n      if (index > -1) {\n        format = format.split('');\n\n        regex[index] = '(' + data.regex + ')';\n        format[index] = '$'; // Custom symbol to define consumed part of format\n        for (var i = index + 1, n = index + data.key.length; i < n; i++) {\n          regex[i] = '';\n          format[i] = '$';\n        }\n        format = format.join('');\n\n        map.push({\n          index: index,\n          key: data.key,\n          apply: data.apply,\n          matcher: data.regex\n        });\n      }\n    });\n\n    return {\n      regex: new RegExp('^' + regex.join('') + '$'),\n      map: orderByFilter(map, 'index')\n    };\n  }\n\n  function createFormatter(format) {\n    var formatters = [];\n    var i = 0;\n    var formatter, literalIdx;\n    while (i < format.length) {\n      if (angular.isNumber(literalIdx)) {\n        if (format.charAt(i) === '\\'') {\n          if (i + 1 >= format.length || format.charAt(i + 1) !== '\\'') {\n            formatters.push(constructLiteralFormatter(format, literalIdx, i));\n            literalIdx = null;\n          }\n        } else if (i === format.length) {\n          while (literalIdx < format.length) {\n            formatter = constructFormatterFromIdx(format, literalIdx);\n            formatters.push(formatter);\n            literalIdx = formatter.endIdx;\n          }\n        }\n\n        i++;\n        continue;\n      }\n\n      if (format.charAt(i) === '\\'') {\n        literalIdx = i;\n        i++;\n        continue;\n      }\n\n      formatter = constructFormatterFromIdx(format, i);\n\n      formatters.push(formatter.parser);\n      i = formatter.endIdx;\n    }\n\n    return formatters;\n  }\n\n  function constructLiteralFormatter(format, literalIdx, endIdx) {\n    return function() {\n      return format.substr(literalIdx + 1, endIdx - literalIdx - 1);\n    };\n  }\n\n  function constructFormatterFromIdx(format, i) {\n    var currentPosStr = format.substr(i);\n    for (var j = 0; j < formatCodeToRegex.length; j++) {\n      if (new RegExp('^' + formatCodeToRegex[j].key).test(currentPosStr)) {\n        var data = formatCodeToRegex[j];\n        return {\n          endIdx: i + data.key.length,\n          parser: data.formatter\n        };\n      }\n    }\n\n    return {\n      endIdx: i + 1,\n      parser: function() {\n        return currentPosStr.charAt(0);\n      }\n    };\n  }\n\n  this.filter = function(date, format) {\n    if (!angular.isDate(date) || isNaN(date) || !format) {\n      return '';\n    }\n\n    format = $locale.DATETIME_FORMATS[format] || format;\n\n    if ($locale.id !== localeId) {\n      this.init();\n    }\n\n    if (!this.formatters[format]) {\n      this.formatters[format] = createFormatter(format);\n    }\n\n    var formatters = this.formatters[format];\n\n    return formatters.reduce(function(str, formatter) {\n      return str + formatter(date);\n    }, '');\n  };\n\n  this.parse = function(input, format, baseDate) {\n    if (!angular.isString(input) || !format) {\n      return input;\n    }\n\n    format = $locale.DATETIME_FORMATS[format] || format;\n    format = format.replace(SPECIAL_CHARACTERS_REGEXP, '\\\\$&');\n\n    if ($locale.id !== localeId) {\n      this.init();\n    }\n\n    if (!this.parsers[format]) {\n      this.parsers[format] = createParser(format, 'apply');\n    }\n\n    var parser = this.parsers[format],\n        regex = parser.regex,\n        map = parser.map,\n        results = input.match(regex),\n        tzOffset = false;\n    if (results && results.length) {\n      var fields, dt;\n      if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) {\n        fields = {\n          year: baseDate.getFullYear(),\n          month: baseDate.getMonth(),\n          date: baseDate.getDate(),\n          hours: baseDate.getHours(),\n          minutes: baseDate.getMinutes(),\n          seconds: baseDate.getSeconds(),\n          milliseconds: baseDate.getMilliseconds()\n        };\n      } else {\n        if (baseDate) {\n          $log.warn('dateparser:', 'baseDate is not a valid date');\n        }\n        fields = { year: 1900, month: 0, date: 1, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 };\n      }\n\n      for (var i = 1, n = results.length; i < n; i++) {\n        var mapper = map[i - 1];\n        if (mapper.matcher === 'Z') {\n          tzOffset = true;\n        }\n\n        if (mapper.apply) {\n          mapper.apply.call(fields, results[i]);\n        }\n      }\n\n      var datesetter = tzOffset ? Date.prototype.setUTCFullYear :\n        Date.prototype.setFullYear;\n      var timesetter = tzOffset ? Date.prototype.setUTCHours :\n        Date.prototype.setHours;\n\n      if (isValid(fields.year, fields.month, fields.date)) {\n        if (angular.isDate(baseDate) && !isNaN(baseDate.getTime()) && !tzOffset) {\n          dt = new Date(baseDate);\n          datesetter.call(dt, fields.year, fields.month, fields.date);\n          timesetter.call(dt, fields.hours, fields.minutes,\n            fields.seconds, fields.milliseconds);\n        } else {\n          dt = new Date(0);\n          datesetter.call(dt, fields.year, fields.month, fields.date);\n          timesetter.call(dt, fields.hours || 0, fields.minutes || 0,\n            fields.seconds || 0, fields.milliseconds || 0);\n        }\n      }\n\n      return dt;\n    }\n  };\n\n  // Check if date is valid for specific month (and year for February).\n  // Month: 0 = Jan, 1 = Feb, etc\n  function isValid(year, month, date) {\n    if (date < 1) {\n      return false;\n    }\n\n    if (month === 1 && date > 28) {\n      return date === 29 && (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0);\n    }\n\n    if (month === 3 || month === 5 || month === 8 || month === 10) {\n      return date < 31;\n    }\n\n    return true;\n  }\n\n  function toInt(str) {\n    return parseInt(str, 10);\n  }\n\n  this.toTimezone = toTimezone;\n  this.fromTimezone = fromTimezone;\n  this.timezoneToOffset = timezoneToOffset;\n  this.addDateMinutes = addDateMinutes;\n  this.convertTimezoneToLocal = convertTimezoneToLocal;\n\n  function toTimezone(date, timezone) {\n    return date && timezone ? convertTimezoneToLocal(date, timezone) : date;\n  }\n\n  function fromTimezone(date, timezone) {\n    return date && timezone ? convertTimezoneToLocal(date, timezone, true) : date;\n  }\n\n  //https://github.com/angular/angular.js/blob/622c42169699ec07fc6daaa19fe6d224e5d2f70e/src/Angular.js#L1207\n  function timezoneToOffset(timezone, fallback) {\n    timezone = timezone.replace(/:/g, '');\n    var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;\n    return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;\n  }\n\n  function addDateMinutes(date, minutes) {\n    date = new Date(date.getTime());\n    date.setMinutes(date.getMinutes() + minutes);\n    return date;\n  }\n\n  function convertTimezoneToLocal(date, timezone, reverse) {\n    reverse = reverse ? -1 : 1;\n    var dateTimezoneOffset = date.getTimezoneOffset();\n    var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n    return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));\n  }\n}]);\n","src/isClass/isClass.js":"// Avoiding use of ng-class as it creates a lot of watchers when a class is to be applied to\n// at most one element.\nangular.module('ui.bootstrap.isClass', [])\n.directive('uibIsClass', [\n         '$animate',\nfunction ($animate) {\n  //                    11111111          22222222\n  var ON_REGEXP = /^\\s*([\\s\\S]+?)\\s+on\\s+([\\s\\S]+?)\\s*$/;\n  //                    11111111           22222222\n  var IS_REGEXP = /^\\s*([\\s\\S]+?)\\s+for\\s+([\\s\\S]+?)\\s*$/;\n\n  var dataPerTracked = {};\n\n  return {\n    restrict: 'A',\n    compile: function(tElement, tAttrs) {\n      var linkedScopes = [];\n      var instances = [];\n      var expToData = {};\n      var lastActivated = null;\n      var onExpMatches = tAttrs.uibIsClass.match(ON_REGEXP);\n      var onExp = onExpMatches[2];\n      var expsStr = onExpMatches[1];\n      var exps = expsStr.split(',');\n\n      return linkFn;\n\n      function linkFn(scope, element, attrs) {\n        linkedScopes.push(scope);\n        instances.push({\n          scope: scope,\n          element: element\n        });\n\n        exps.forEach(function(exp, k) {\n          addForExp(exp, scope);\n        });\n\n        scope.$on('$destroy', removeScope);\n      }\n\n      function addForExp(exp, scope) {\n        var matches = exp.match(IS_REGEXP);\n        var clazz = scope.$eval(matches[1]);\n        var compareWithExp = matches[2];\n        var data = expToData[exp];\n        if (!data) {\n          var watchFn = function(compareWithVal) {\n            var newActivated = null;\n            instances.some(function(instance) {\n              var thisVal = instance.scope.$eval(onExp);\n              if (thisVal === compareWithVal) {\n                newActivated = instance;\n                return true;\n              }\n            });\n            if (data.lastActivated !== newActivated) {\n              if (data.lastActivated) {\n                $animate.removeClass(data.lastActivated.element, clazz);\n              }\n              if (newActivated) {\n                $animate.addClass(newActivated.element, clazz);\n              }\n              data.lastActivated = newActivated;\n            }\n          };\n          expToData[exp] = data = {\n            lastActivated: null,\n            scope: scope,\n            watchFn: watchFn,\n            compareWithExp: compareWithExp,\n            watcher: scope.$watch(compareWithExp, watchFn)\n          };\n        }\n        data.watchFn(scope.$eval(compareWithExp));\n      }\n\n      function removeScope(e) {\n        var removedScope = e.targetScope;\n        var index = linkedScopes.indexOf(removedScope);\n        linkedScopes.splice(index, 1);\n        instances.splice(index, 1);\n        if (linkedScopes.length) {\n          var newWatchScope = linkedScopes[0];\n          angular.forEach(expToData, function(data) {\n            if (data.scope === removedScope) {\n              data.watcher = newWatchScope.$watch(data.compareWithExp, data.watchFn);\n              data.scope = newWatchScope;\n            }\n          });\n        } else {\n          expToData = {};\n        }\n      }\n    }\n  };\n}]);","src/datepicker/datepicker.js":"angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootstrap.isClass'])\n\n.value('$datepickerSuppressError', false)\n\n.value('$datepickerLiteralWarning', true)\n\n.constant('uibDatepickerConfig', {\n  datepickerMode: 'day',\n  formatDay: 'dd',\n  formatMonth: 'MMMM',\n  formatYear: 'yyyy',\n  formatDayHeader: 'EEE',\n  formatDayTitle: 'MMMM yyyy',\n  formatMonthTitle: 'yyyy',\n  maxDate: null,\n  maxMode: 'year',\n  minDate: null,\n  minMode: 'day',\n  monthColumns: 3,\n  ngModelOptions: {},\n  shortcutPropagation: false,\n  showWeeks: true,\n  yearColumns: 5,\n  yearRows: 4\n})\n\n.controller('UibDatepickerController', ['$scope', '$element', '$attrs', '$parse', '$interpolate', '$locale', '$log', 'dateFilter', 'uibDatepickerConfig', '$datepickerLiteralWarning', '$datepickerSuppressError', 'uibDateParser',\n  function($scope, $element, $attrs, $parse, $interpolate, $locale, $log, dateFilter, datepickerConfig, $datepickerLiteralWarning, $datepickerSuppressError, dateParser) {\n  var self = this,\n      ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl;\n      ngModelOptions = {},\n      watchListeners = [];\n\n  $element.addClass('uib-datepicker');\n  $attrs.$set('role', 'application');\n\n  if (!$scope.datepickerOptions) {\n    $scope.datepickerOptions = {};\n  }\n\n  // Modes chain\n  this.modes = ['day', 'month', 'year'];\n\n  [\n    'customClass',\n    'dateDisabled',\n    'datepickerMode',\n    'formatDay',\n    'formatDayHeader',\n    'formatDayTitle',\n    'formatMonth',\n    'formatMonthTitle',\n    'formatYear',\n    'maxDate',\n    'maxMode',\n    'minDate',\n    'minMode',\n    'monthColumns',\n    'showWeeks',\n    'shortcutPropagation',\n    'startingDay',\n    'yearColumns',\n    'yearRows'\n  ].forEach(function(key) {\n    switch (key) {\n      case 'customClass':\n      case 'dateDisabled':\n        $scope[key] = $scope.datepickerOptions[key] || angular.noop;\n        break;\n      case 'datepickerMode':\n        $scope.datepickerMode = angular.isDefined($scope.datepickerOptions.datepickerMode) ?\n          $scope.datepickerOptions.datepickerMode : datepickerConfig.datepickerMode;\n        break;\n      case 'formatDay':\n      case 'formatDayHeader':\n      case 'formatDayTitle':\n      case 'formatMonth':\n      case 'formatMonthTitle':\n      case 'formatYear':\n        self[key] = angular.isDefined($scope.datepickerOptions[key]) ?\n          $interpolate($scope.datepickerOptions[key])($scope.$parent) :\n          datepickerConfig[key];\n        break;\n      case 'monthColumns':\n      case 'showWeeks':\n      case 'shortcutPropagation':\n      case 'yearColumns':\n      case 'yearRows':\n        self[key] = angular.isDefined($scope.datepickerOptions[key]) ?\n          $scope.datepickerOptions[key] : datepickerConfig[key];\n        break;\n      case 'startingDay':\n        if (angular.isDefined($scope.datepickerOptions.startingDay)) {\n          self.startingDay = $scope.datepickerOptions.startingDay;\n        } else if (angular.isNumber(datepickerConfig.startingDay)) {\n          self.startingDay = datepickerConfig.startingDay;\n        } else {\n          self.startingDay = ($locale.DATETIME_FORMATS.FIRSTDAYOFWEEK + 8) % 7;\n        }\n\n        break;\n      case 'maxDate':\n      case 'minDate':\n        $scope.$watch('datepickerOptions.' + key, function(value) {\n          if (value) {\n            if (angular.isDate(value)) {\n              self[key] = dateParser.fromTimezone(new Date(value), ngModelOptions.getOption('timezone'));\n            } else {\n              if ($datepickerLiteralWarning) {\n                $log.warn('Literal date support has been deprecated, please switch to date object usage');\n              }\n\n              self[key] = new Date(dateFilter(value, 'medium'));\n            }\n          } else {\n            self[key] = datepickerConfig[key] ?\n              dateParser.fromTimezone(new Date(datepickerConfig[key]), ngModelOptions.getOption('timezone')) :\n              null;\n          }\n\n          self.refreshView();\n        });\n\n        break;\n      case 'maxMode':\n      case 'minMode':\n        if ($scope.datepickerOptions[key]) {\n          $scope.$watch(function() { return $scope.datepickerOptions[key]; }, function(value) {\n            self[key] = $scope[key] = angular.isDefined(value) ? value : $scope.datepickerOptions[key];\n            if (key === 'minMode' && self.modes.indexOf($scope.datepickerOptions.datepickerMode) < self.modes.indexOf(self[key]) ||\n              key === 'maxMode' && self.modes.indexOf($scope.datepickerOptions.datepickerMode) > self.modes.indexOf(self[key])) {\n              $scope.datepickerMode = self[key];\n              $scope.datepickerOptions.datepickerMode = self[key];\n            }\n          });\n        } else {\n          self[key] = $scope[key] = datepickerConfig[key] || null;\n        }\n\n        break;\n    }\n  });\n\n  $scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000);\n\n  $scope.disabled = angular.isDefined($attrs.disabled) || false;\n  if (angular.isDefined($attrs.ngDisabled)) {\n    watchListeners.push($scope.$parent.$watch($attrs.ngDisabled, function(disabled) {\n      $scope.disabled = disabled;\n      self.refreshView();\n    }));\n  }\n\n  $scope.isActive = function(dateObject) {\n    if (self.compare(dateObject.date, self.activeDate) === 0) {\n      $scope.activeDateId = dateObject.uid;\n      return true;\n    }\n    return false;\n  };\n\n  this.init = function(ngModelCtrl_) {\n    ngModelCtrl = ngModelCtrl_;\n    ngModelOptions = extractOptions(ngModelCtrl);\n\n    if ($scope.datepickerOptions.initDate) {\n      self.activeDate = dateParser.fromTimezone($scope.datepickerOptions.initDate, ngModelOptions.getOption('timezone')) || new Date();\n      $scope.$watch('datepickerOptions.initDate', function(initDate) {\n        if (initDate && (ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue) || ngModelCtrl.$invalid)) {\n          self.activeDate = dateParser.fromTimezone(initDate, ngModelOptions.getOption('timezone'));\n          self.refreshView();\n        }\n      });\n    } else {\n      self.activeDate = new Date();\n    }\n\n    var date = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : new Date();\n    this.activeDate = !isNaN(date) ?\n      dateParser.fromTimezone(date, ngModelOptions.getOption('timezone')) :\n      dateParser.fromTimezone(new Date(), ngModelOptions.getOption('timezone'));\n\n    ngModelCtrl.$render = function() {\n      self.render();\n    };\n  };\n\n  this.render = function() {\n    if (ngModelCtrl.$viewValue) {\n      var date = new Date(ngModelCtrl.$viewValue),\n          isValid = !isNaN(date);\n\n      if (isValid) {\n        this.activeDate = dateParser.fromTimezone(date, ngModelOptions.getOption('timezone'));\n      } else if (!$datepickerSuppressError) {\n        $log.error('Datepicker directive: \"ng-model\" value must be a Date object');\n      }\n    }\n    this.refreshView();\n  };\n\n  this.refreshView = function() {\n    if (this.element) {\n      $scope.selectedDt = null;\n      this._refreshView();\n      if ($scope.activeDt) {\n        $scope.activeDateId = $scope.activeDt.uid;\n      }\n\n      var date = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;\n      date = dateParser.fromTimezone(date, ngModelOptions.getOption('timezone'));\n      ngModelCtrl.$setValidity('dateDisabled', !date ||\n        this.element && !this.isDisabled(date));\n    }\n  };\n\n  this.createDateObject = function(date, format) {\n    var model = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;\n    model = dateParser.fromTimezone(model, ngModelOptions.getOption('timezone'));\n    var today = new Date();\n    today = dateParser.fromTimezone(today, ngModelOptions.getOption('timezone'));\n    var time = this.compare(date, today);\n    var dt = {\n      date: date,\n      label: dateParser.filter(date, format),\n      selected: model && this.compare(date, model) === 0,\n      disabled: this.isDisabled(date),\n      past: time < 0,\n      current: time === 0,\n      future: time > 0,\n      customClass: this.customClass(date) || null\n    };\n\n    if (model && this.compare(date, model) === 0) {\n      $scope.selectedDt = dt;\n    }\n\n    if (self.activeDate && this.compare(dt.date, self.activeDate) === 0) {\n      $scope.activeDt = dt;\n    }\n\n    return dt;\n  };\n\n  this.isDisabled = function(date) {\n    return $scope.disabled ||\n      this.minDate && this.compare(date, this.minDate) < 0 ||\n      this.maxDate && this.compare(date, this.maxDate) > 0 ||\n      $scope.dateDisabled && $scope.dateDisabled({date: date, mode: $scope.datepickerMode});\n  };\n\n  this.customClass = function(date) {\n    return $scope.customClass({date: date, mode: $scope.datepickerMode});\n  };\n\n  // Split array into smaller arrays\n  this.split = function(arr, size) {\n    var arrays = [];\n    while (arr.length > 0) {\n      arrays.push(arr.splice(0, size));\n    }\n    return arrays;\n  };\n\n  $scope.select = function(date) {\n    if ($scope.datepickerMode === self.minMode) {\n      var dt = ngModelCtrl.$viewValue ? dateParser.fromTimezone(new Date(ngModelCtrl.$viewValue), ngModelOptions.getOption('timezone')) : new Date(0, 0, 0, 0, 0, 0, 0);\n      dt.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());\n      dt = dateParser.toTimezone(dt, ngModelOptions.getOption('timezone'));\n      ngModelCtrl.$setViewValue(dt);\n      ngModelCtrl.$render();\n    } else {\n      self.activeDate = date;\n      setMode(self.modes[self.modes.indexOf($scope.datepickerMode) - 1]);\n\n      $scope.$emit('uib:datepicker.mode');\n    }\n\n    $scope.$broadcast('uib:datepicker.focus');\n  };\n\n  $scope.move = function(direction) {\n    var year = self.activeDate.getFullYear() + direction * (self.step.years || 0),\n        month = self.activeDate.getMonth() + direction * (self.step.months || 0);\n    self.activeDate.setFullYear(year, month, 1);\n    self.refreshView();\n  };\n\n  $scope.toggleMode = function(direction) {\n    direction = direction || 1;\n\n    if ($scope.datepickerMode === self.maxMode && direction === 1 ||\n      $scope.datepickerMode === self.minMode && direction === -1) {\n      return;\n    }\n\n    setMode(self.modes[self.modes.indexOf($scope.datepickerMode) + direction]);\n\n    $scope.$emit('uib:datepicker.mode');\n  };\n\n  // Key event mapper\n  $scope.keys = { 13: 'enter', 32: 'space', 33: 'pageup', 34: 'pagedown', 35: 'end', 36: 'home', 37: 'left', 38: 'up', 39: 'right', 40: 'down' };\n\n  var focusElement = function() {\n    self.element[0].focus();\n  };\n\n  // Listen for focus requests from popup directive\n  $scope.$on('uib:datepicker.focus', focusElement);\n\n  $scope.keydown = function(evt) {\n    var key = $scope.keys[evt.which];\n\n    if (!key || evt.shiftKey || evt.altKey || $scope.disabled) {\n      return;\n    }\n\n    evt.preventDefault();\n    if (!self.shortcutPropagation) {\n      evt.stopPropagation();\n    }\n\n    if (key === 'enter' || key === 'space') {\n      if (self.isDisabled(self.activeDate)) {\n        return; // do nothing\n      }\n      $scope.select(self.activeDate);\n    } else if (evt.ctrlKey && (key === 'up' || key === 'down')) {\n      $scope.toggleMode(key === 'up' ? 1 : -1);\n    } else {\n      self.handleKeyDown(key, evt);\n      self.refreshView();\n    }\n  };\n\n  $element.on('keydown', function(evt) {\n    $scope.$apply(function() {\n      $scope.keydown(evt);\n    });\n  });\n\n  $scope.$on('$destroy', function() {\n    //Clear all watch listeners on destroy\n    while (watchListeners.length) {\n      watchListeners.shift()();\n    }\n  });\n\n  function setMode(mode) {\n    $scope.datepickerMode = mode;\n    $scope.datepickerOptions.datepickerMode = mode;\n  }\n\n  function extractOptions(ngModelCtrl) {\n    var ngModelOptions;\n\n    if (angular.version.minor < 6) { // in angular < 1.6 $options could be missing\n      // guarantee a value\n      ngModelOptions = ngModelCtrl.$options ||\n        $scope.datepickerOptions.ngModelOptions ||\n        datepickerConfig.ngModelOptions ||\n        {};\n\n      // mimic 1.6+ api\n      ngModelOptions.getOption = function (key) {\n        return ngModelOptions[key];\n      };\n    } else { // in angular >=1.6 $options is always present\n      // ng-model-options defaults timezone to null; don't let its precedence squash a non-null value\n      var timezone = ngModelCtrl.$options.getOption('timezone') ||\n        ($scope.datepickerOptions.ngModelOptions ? $scope.datepickerOptions.ngModelOptions.timezone : null) ||\n        (datepickerConfig.ngModelOptions ? datepickerConfig.ngModelOptions.timezone : null);\n\n      // values passed to createChild override existing values\n      ngModelOptions = ngModelCtrl.$options // start with a ModelOptions instance\n        .createChild(datepickerConfig.ngModelOptions) // lowest precedence\n        .createChild($scope.datepickerOptions.ngModelOptions)\n        .createChild(ngModelCtrl.$options) // highest precedence\n        .createChild({timezone: timezone}); // to keep from squashing a non-null value\n    }\n\n    return ngModelOptions;\n  }\n}])\n\n.controller('UibDaypickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {\n  var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n  this.step = { months: 1 };\n  this.element = $element;\n  function getDaysInMonth(year, month) {\n    return month === 1 && year % 4 === 0 &&\n      (year % 100 !== 0 || year % 400 === 0) ? 29 : DAYS_IN_MONTH[month];\n  }\n\n  this.init = function(ctrl) {\n    angular.extend(ctrl, this);\n    scope.showWeeks = ctrl.showWeeks;\n    ctrl.refreshView();\n  };\n\n  this.getDates = function(startDate, n) {\n    var dates = new Array(n), current = new Date(startDate), i = 0, date;\n    while (i < n) {\n      date = new Date(current);\n      dates[i++] = date;\n      current.setDate(current.getDate() + 1);\n    }\n    return dates;\n  };\n\n  this._refreshView = function() {\n    var year = this.activeDate.getFullYear(),\n      month = this.activeDate.getMonth(),\n      firstDayOfMonth = new Date(this.activeDate);\n\n    firstDayOfMonth.setFullYear(year, month, 1);\n\n    var difference = this.startingDay - firstDayOfMonth.getDay(),\n      numDisplayedFromPreviousMonth = difference > 0 ?\n        7 - difference : - difference,\n      firstDate = new Date(firstDayOfMonth);\n\n    if (numDisplayedFromPreviousMonth > 0) {\n      firstDate.setDate(-numDisplayedFromPreviousMonth + 1);\n    }\n\n    // 42 is the number of days on a six-week calendar\n    var days = this.getDates(firstDate, 42);\n    for (var i = 0; i < 42; i ++) {\n      days[i] = angular.extend(this.createDateObject(days[i], this.formatDay), {\n        secondary: days[i].getMonth() !== month,\n        uid: scope.uniqueId + '-' + i\n      });\n    }\n\n    scope.labels = new Array(7);\n    for (var j = 0; j < 7; j++) {\n      scope.labels[j] = {\n        abbr: dateFilter(days[j].date, this.formatDayHeader),\n        full: dateFilter(days[j].date, 'EEEE')\n      };\n    }\n\n    scope.title = dateFilter(this.activeDate, this.formatDayTitle);\n    scope.rows = this.split(days, 7);\n\n    if (scope.showWeeks) {\n      scope.weekNumbers = [];\n      var thursdayIndex = (4 + 7 - this.startingDay) % 7,\n          numWeeks = scope.rows.length;\n      for (var curWeek = 0; curWeek < numWeeks; curWeek++) {\n        scope.weekNumbers.push(\n          getISO8601WeekNumber(scope.rows[curWeek][thursdayIndex].date));\n      }\n    }\n  };\n\n  this.compare = function(date1, date2) {\n    var _date1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());\n    var _date2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());\n    _date1.setFullYear(date1.getFullYear());\n    _date2.setFullYear(date2.getFullYear());\n    return _date1 - _date2;\n  };\n\n  function getISO8601WeekNumber(date) {\n    var checkDate = new Date(date);\n    checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday\n    var time = checkDate.getTime();\n    checkDate.setMonth(0); // Compare with Jan 1\n    checkDate.setDate(1);\n    return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;\n  }\n\n  this.handleKeyDown = function(key, evt) {\n    var date = this.activeDate.getDate();\n\n    if (key === 'left') {\n      date = date - 1;\n    } else if (key === 'up') {\n      date = date - 7;\n    } else if (key === 'right') {\n      date = date + 1;\n    } else if (key === 'down') {\n      date = date + 7;\n    } else if (key === 'pageup' || key === 'pagedown') {\n      var month = this.activeDate.getMonth() + (key === 'pageup' ? - 1 : 1);\n      this.activeDate.setMonth(month, 1);\n      date = Math.min(getDaysInMonth(this.activeDate.getFullYear(), this.activeDate.getMonth()), date);\n    } else if (key === 'home') {\n      date = 1;\n    } else if (key === 'end') {\n      date = getDaysInMonth(this.activeDate.getFullYear(), this.activeDate.getMonth());\n    }\n    this.activeDate.setDate(date);\n  };\n}])\n\n.controller('UibMonthpickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {\n  this.step = { years: 1 };\n  this.element = $element;\n\n  this.init = function(ctrl) {\n    angular.extend(ctrl, this);\n    ctrl.refreshView();\n  };\n\n  this._refreshView = function() {\n    var months = new Array(12),\n        year = this.activeDate.getFullYear(),\n        date;\n\n    for (var i = 0; i < 12; i++) {\n      date = new Date(this.activeDate);\n      date.setFullYear(year, i, 1);\n      months[i] = angular.extend(this.createDateObject(date, this.formatMonth), {\n        uid: scope.uniqueId + '-' + i\n      });\n    }\n\n    scope.title = dateFilter(this.activeDate, this.formatMonthTitle);\n    scope.rows = this.split(months, this.monthColumns);\n    scope.yearHeaderColspan = this.monthColumns > 3 ? this.monthColumns - 2 : 1;\n  };\n\n  this.compare = function(date1, date2) {\n    var _date1 = new Date(date1.getFullYear(), date1.getMonth());\n    var _date2 = new Date(date2.getFullYear(), date2.getMonth());\n    _date1.setFullYear(date1.getFullYear());\n    _date2.setFullYear(date2.getFullYear());\n    return _date1 - _date2;\n  };\n\n  this.handleKeyDown = function(key, evt) {\n    var date = this.activeDate.getMonth();\n\n    if (key === 'left') {\n      date = date - 1;\n    } else if (key === 'up') {\n      date = date - this.monthColumns;\n    } else if (key === 'right') {\n      date = date + 1;\n    } else if (key === 'down') {\n      date = date + this.monthColumns;\n    } else if (key === 'pageup' || key === 'pagedown') {\n      var year = this.activeDate.getFullYear() + (key === 'pageup' ? - 1 : 1);\n      this.activeDate.setFullYear(year);\n    } else if (key === 'home') {\n      date = 0;\n    } else if (key === 'end') {\n      date = 11;\n    }\n    this.activeDate.setMonth(date);\n  };\n}])\n\n.controller('UibYearpickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {\n  var columns, range;\n  this.element = $element;\n\n  function getStartingYear(year) {\n    return parseInt((year - 1) / range, 10) * range + 1;\n  }\n\n  this.yearpickerInit = function() {\n    columns = this.yearColumns;\n    range = this.yearRows * columns;\n    this.step = { years: range };\n  };\n\n  this._refreshView = function() {\n    var years = new Array(range), date;\n\n    for (var i = 0, start = getStartingYear(this.activeDate.getFullYear()); i < range; i++) {\n      date = new Date(this.activeDate);\n      date.setFullYear(start + i, 0, 1);\n      years[i] = angular.extend(this.createDateObject(date, this.formatYear), {\n        uid: scope.uniqueId + '-' + i\n      });\n    }\n\n    scope.title = [years[0].label, years[range - 1].label].join(' - ');\n    scope.rows = this.split(years, columns);\n    scope.columns = columns;\n  };\n\n  this.compare = function(date1, date2) {\n    return date1.getFullYear() - date2.getFullYear();\n  };\n\n  this.handleKeyDown = function(key, evt) {\n    var date = this.activeDate.getFullYear();\n\n    if (key === 'left') {\n      date = date - 1;\n    } else if (key === 'up') {\n      date = date - columns;\n    } else if (key === 'right') {\n      date = date + 1;\n    } else if (key === 'down') {\n      date = date + columns;\n    } else if (key === 'pageup' || key === 'pagedown') {\n      date += (key === 'pageup' ? - 1 : 1) * range;\n    } else if (key === 'home') {\n      date = getStartingYear(this.activeDate.getFullYear());\n    } else if (key === 'end') {\n      date = getStartingYear(this.activeDate.getFullYear()) + range - 1;\n    }\n    this.activeDate.setFullYear(date);\n  };\n}])\n\n.directive('uibDatepicker', function() {\n  return {\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/datepicker/datepicker.html';\n    },\n    scope: {\n      datepickerOptions: '=?'\n    },\n    require: ['uibDatepicker', '^ngModel'],\n    restrict: 'A',\n    controller: 'UibDatepickerController',\n    controllerAs: 'datepicker',\n    link: function(scope, element, attrs, ctrls) {\n      var datepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n\n      datepickerCtrl.init(ngModelCtrl);\n    }\n  };\n})\n\n.directive('uibDaypicker', function() {\n  return {\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/datepicker/day.html';\n    },\n    require: ['^uibDatepicker', 'uibDaypicker'],\n    restrict: 'A',\n    controller: 'UibDaypickerController',\n    link: function(scope, element, attrs, ctrls) {\n      var datepickerCtrl = ctrls[0],\n        daypickerCtrl = ctrls[1];\n\n      daypickerCtrl.init(datepickerCtrl);\n    }\n  };\n})\n\n.directive('uibMonthpicker', function() {\n  return {\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/datepicker/month.html';\n    },\n    require: ['^uibDatepicker', 'uibMonthpicker'],\n    restrict: 'A',\n    controller: 'UibMonthpickerController',\n    link: function(scope, element, attrs, ctrls) {\n      var datepickerCtrl = ctrls[0],\n        monthpickerCtrl = ctrls[1];\n\n      monthpickerCtrl.init(datepickerCtrl);\n    }\n  };\n})\n\n.directive('uibYearpicker', function() {\n  return {\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/datepicker/year.html';\n    },\n    require: ['^uibDatepicker', 'uibYearpicker'],\n    restrict: 'A',\n    controller: 'UibYearpickerController',\n    link: function(scope, element, attrs, ctrls) {\n      var ctrl = ctrls[0];\n      angular.extend(ctrl, ctrls[1]);\n      ctrl.yearpickerInit();\n\n      ctrl.refreshView();\n    }\n  };\n});\n","src/position/position.js":"angular.module('ui.bootstrap.position', [])\n\n/**\n * A set of utility methods for working with the DOM.\n * It is meant to be used where we need to absolute-position elements in\n * relation to another element (this is the case for tooltips, popovers,\n * typeahead suggestions etc.).\n */\n  .factory('$uibPosition', ['$document', '$window', function($document, $window) {\n    /**\n     * Used by scrollbarWidth() function to cache scrollbar's width.\n     * Do not access this variable directly, use scrollbarWidth() instead.\n     */\n    var SCROLLBAR_WIDTH;\n    /**\n     * scrollbar on body and html element in IE and Edge overlay\n     * content and should be considered 0 width.\n     */\n    var BODY_SCROLLBAR_WIDTH;\n    var OVERFLOW_REGEX = {\n      normal: /(auto|scroll)/,\n      hidden: /(auto|scroll|hidden)/\n    };\n    var PLACEMENT_REGEX = {\n      auto: /\\s?auto?\\s?/i,\n      primary: /^(top|bottom|left|right)$/,\n      secondary: /^(top|bottom|left|right|center)$/,\n      vertical: /^(top|bottom)$/\n    };\n    var BODY_REGEX = /(HTML|BODY)/;\n\n    return {\n\n      /**\n       * Provides a raw DOM element from a jQuery/jQLite element.\n       *\n       * @param {element} elem - The element to convert.\n       *\n       * @returns {element} A HTML element.\n       */\n      getRawNode: function(elem) {\n        return elem.nodeName ? elem : elem[0] || elem;\n      },\n\n      /**\n       * Provides a parsed number for a style property.  Strips\n       * units and casts invalid numbers to 0.\n       *\n       * @param {string} value - The style value to parse.\n       *\n       * @returns {number} A valid number.\n       */\n      parseStyle: function(value) {\n        value = parseFloat(value);\n        return isFinite(value) ? value : 0;\n      },\n\n      /**\n       * Provides the closest positioned ancestor.\n       *\n       * @param {element} element - The element to get the offest parent for.\n       *\n       * @returns {element} The closest positioned ancestor.\n       */\n      offsetParent: function(elem) {\n        elem = this.getRawNode(elem);\n\n        var offsetParent = elem.offsetParent || $document[0].documentElement;\n\n        function isStaticPositioned(el) {\n          return ($window.getComputedStyle(el).position || 'static') === 'static';\n        }\n\n        while (offsetParent && offsetParent !== $document[0].documentElement && isStaticPositioned(offsetParent)) {\n          offsetParent = offsetParent.offsetParent;\n        }\n\n        return offsetParent || $document[0].documentElement;\n      },\n\n      /**\n       * Provides the scrollbar width, concept from TWBS measureScrollbar()\n       * function in https://github.com/twbs/bootstrap/blob/master/js/modal.js\n       * In IE and Edge, scollbar on body and html element overlay and should\n       * return a width of 0.\n       *\n       * @returns {number} The width of the browser scollbar.\n       */\n      scrollbarWidth: function(isBody) {\n        if (isBody) {\n          if (angular.isUndefined(BODY_SCROLLBAR_WIDTH)) {\n            var bodyElem = $document.find('body');\n            bodyElem.addClass('uib-position-body-scrollbar-measure');\n            BODY_SCROLLBAR_WIDTH = $window.innerWidth - bodyElem[0].clientWidth;\n            BODY_SCROLLBAR_WIDTH = isFinite(BODY_SCROLLBAR_WIDTH) ? BODY_SCROLLBAR_WIDTH : 0;\n            bodyElem.removeClass('uib-position-body-scrollbar-measure');\n          }\n          return BODY_SCROLLBAR_WIDTH;\n        }\n\n        if (angular.isUndefined(SCROLLBAR_WIDTH)) {\n          var scrollElem = angular.element('<div class=\"uib-position-scrollbar-measure\"></div>');\n          $document.find('body').append(scrollElem);\n          SCROLLBAR_WIDTH = scrollElem[0].offsetWidth - scrollElem[0].clientWidth;\n          SCROLLBAR_WIDTH = isFinite(SCROLLBAR_WIDTH) ? SCROLLBAR_WIDTH : 0;\n          scrollElem.remove();\n        }\n\n        return SCROLLBAR_WIDTH;\n      },\n\n      /**\n       * Provides the padding required on an element to replace the scrollbar.\n       *\n       * @returns {object} An object with the following properties:\n       *   <ul>\n       *     <li>**scrollbarWidth**: the width of the scrollbar</li>\n       *     <li>**widthOverflow**: whether the the width is overflowing</li>\n       *     <li>**right**: the amount of right padding on the element needed to replace the scrollbar</li>\n       *     <li>**rightOriginal**: the amount of right padding currently on the element</li>\n       *     <li>**heightOverflow**: whether the the height is overflowing</li>\n       *     <li>**bottom**: the amount of bottom padding on the element needed to replace the scrollbar</li>\n       *     <li>**bottomOriginal**: the amount of bottom padding currently on the element</li>\n       *   </ul>\n       */\n      scrollbarPadding: function(elem) {\n        elem = this.getRawNode(elem);\n\n        var elemStyle = $window.getComputedStyle(elem);\n        var paddingRight = this.parseStyle(elemStyle.paddingRight);\n        var paddingBottom = this.parseStyle(elemStyle.paddingBottom);\n        var scrollParent = this.scrollParent(elem, false, true);\n        var scrollbarWidth = this.scrollbarWidth(BODY_REGEX.test(scrollParent.tagName));\n\n        return {\n          scrollbarWidth: scrollbarWidth,\n          widthOverflow: scrollParent.scrollWidth > scrollParent.clientWidth,\n          right: paddingRight + scrollbarWidth,\n          originalRight: paddingRight,\n          heightOverflow: scrollParent.scrollHeight > scrollParent.clientHeight,\n          bottom: paddingBottom + scrollbarWidth,\n          originalBottom: paddingBottom\n         };\n      },\n\n      /**\n       * Checks to see if the element is scrollable.\n       *\n       * @param {element} elem - The element to check.\n       * @param {boolean=} [includeHidden=false] - Should scroll style of 'hidden' be considered,\n       *   default is false.\n       *\n       * @returns {boolean} Whether the element is scrollable.\n       */\n      isScrollable: function(elem, includeHidden) {\n        elem = this.getRawNode(elem);\n\n        var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal;\n        var elemStyle = $window.getComputedStyle(elem);\n        return overflowRegex.test(elemStyle.overflow + elemStyle.overflowY + elemStyle.overflowX);\n      },\n\n      /**\n       * Provides the closest scrollable ancestor.\n       * A port of the jQuery UI scrollParent method:\n       * https://github.com/jquery/jquery-ui/blob/master/ui/scroll-parent.js\n       *\n       * @param {element} elem - The element to find the scroll parent of.\n       * @param {boolean=} [includeHidden=false] - Should scroll style of 'hidden' be considered,\n       *   default is false.\n       * @param {boolean=} [includeSelf=false] - Should the element being passed be\n       * included in the scrollable llokup.\n       *\n       * @returns {element} A HTML element.\n       */\n      scrollParent: function(elem, includeHidden, includeSelf) {\n        elem = this.getRawNode(elem);\n\n        var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal;\n        var documentEl = $document[0].documentElement;\n        var elemStyle = $window.getComputedStyle(elem);\n        if (includeSelf && overflowRegex.test(elemStyle.overflow + elemStyle.overflowY + elemStyle.overflowX)) {\n          return elem;\n        }\n        var excludeStatic = elemStyle.position === 'absolute';\n        var scrollParent = elem.parentElement || documentEl;\n\n        if (scrollParent === documentEl || elemStyle.position === 'fixed') {\n          return documentEl;\n        }\n\n        while (scrollParent.parentElement && scrollParent !== documentEl) {\n          var spStyle = $window.getComputedStyle(scrollParent);\n          if (excludeStatic && spStyle.position !== 'static') {\n            excludeStatic = false;\n          }\n\n          if (!excludeStatic && overflowRegex.test(spStyle.overflow + spStyle.overflowY + spStyle.overflowX)) {\n            break;\n          }\n          scrollParent = scrollParent.parentElement;\n        }\n\n        return scrollParent;\n      },\n\n      /**\n       * Provides read-only equivalent of jQuery's position function:\n       * http://api.jquery.com/position/ - distance to closest positioned\n       * ancestor.  Does not account for margins by default like jQuery position.\n       *\n       * @param {element} elem - The element to caclulate the position on.\n       * @param {boolean=} [includeMargins=false] - Should margins be accounted\n       * for, default is false.\n       *\n       * @returns {object} An object with the following properties:\n       *   <ul>\n       *     <li>**width**: the width of the element</li>\n       *     <li>**height**: the height of the element</li>\n       *     <li>**top**: distance to top edge of offset parent</li>\n       *     <li>**left**: distance to left edge of offset parent</li>\n       *   </ul>\n       */\n      position: function(elem, includeMagins) {\n        elem = this.getRawNode(elem);\n\n        var elemOffset = this.offset(elem);\n        if (includeMagins) {\n          var elemStyle = $window.getComputedStyle(elem);\n          elemOffset.top -= this.parseStyle(elemStyle.marginTop);\n          elemOffset.left -= this.parseStyle(elemStyle.marginLeft);\n        }\n        var parent = this.offsetParent(elem);\n        var parentOffset = {top: 0, left: 0};\n\n        if (parent !== $document[0].documentElement) {\n          parentOffset = this.offset(parent);\n          parentOffset.top += parent.clientTop - parent.scrollTop;\n          parentOffset.left += parent.clientLeft - parent.scrollLeft;\n        }\n\n        return {\n          width: Math.round(angular.isNumber(elemOffset.width) ? elemOffset.width : elem.offsetWidth),\n          height: Math.round(angular.isNumber(elemOffset.height) ? elemOffset.height : elem.offsetHeight),\n          top: Math.round(elemOffset.top - parentOffset.top),\n          left: Math.round(elemOffset.left - parentOffset.left)\n        };\n      },\n\n      /**\n       * Provides read-only equivalent of jQuery's offset function:\n       * http://api.jquery.com/offset/ - distance to viewport.  Does\n       * not account for borders, margins, or padding on the body\n       * element.\n       *\n       * @param {element} elem - The element to calculate the offset on.\n       *\n       * @returns {object} An object with the following properties:\n       *   <ul>\n       *     <li>**width**: the width of the element</li>\n       *     <li>**height**: the height of the element</li>\n       *     <li>**top**: distance to top edge of viewport</li>\n       *     <li>**right**: distance to bottom edge of viewport</li>\n       *   </ul>\n       */\n      offset: function(elem) {\n        elem = this.getRawNode(elem);\n\n        var elemBCR = elem.getBoundingClientRect();\n        return {\n          width: Math.round(angular.isNumber(elemBCR.width) ? elemBCR.width : elem.offsetWidth),\n          height: Math.round(angular.isNumber(elemBCR.height) ? elemBCR.height : elem.offsetHeight),\n          top: Math.round(elemBCR.top + ($window.pageYOffset || $document[0].documentElement.scrollTop)),\n          left: Math.round(elemBCR.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft))\n        };\n      },\n\n      /**\n       * Provides offset distance to the closest scrollable ancestor\n       * or viewport.  Accounts for border and scrollbar width.\n       *\n       * Right and bottom dimensions represent the distance to the\n       * respective edge of the viewport element.  If the element\n       * edge extends beyond the viewport, a negative value will be\n       * reported.\n       *\n       * @param {element} elem - The element to get the viewport offset for.\n       * @param {boolean=} [useDocument=false] - Should the viewport be the document element instead\n       * of the first scrollable element, default is false.\n       * @param {boolean=} [includePadding=true] - Should the padding on the offset parent element\n       * be accounted for, default is true.\n       *\n       * @returns {object} An object with the following properties:\n       *   <ul>\n       *     <li>**top**: distance to the top content edge of viewport element</li>\n       *     <li>**bottom**: distance to the bottom content edge of viewport element</li>\n       *     <li>**left**: distance to the left content edge of viewport element</li>\n       *     <li>**right**: distance to the right content edge of viewport element</li>\n       *   </ul>\n       */\n      viewportOffset: function(elem, useDocument, includePadding) {\n        elem = this.getRawNode(elem);\n        includePadding = includePadding !== false ? true : false;\n\n        var elemBCR = elem.getBoundingClientRect();\n        var offsetBCR = {top: 0, left: 0, bottom: 0, right: 0};\n\n        var offsetParent = useDocument ? $document[0].documentElement : this.scrollParent(elem);\n        var offsetParentBCR = offsetParent.getBoundingClientRect();\n\n        offsetBCR.top = offsetParentBCR.top + offsetParent.clientTop;\n        offsetBCR.left = offsetParentBCR.left + offsetParent.clientLeft;\n        if (offsetParent === $document[0].documentElement) {\n          offsetBCR.top += $window.pageYOffset;\n          offsetBCR.left += $window.pageXOffset;\n        }\n        offsetBCR.bottom = offsetBCR.top + offsetParent.clientHeight;\n        offsetBCR.right = offsetBCR.left + offsetParent.clientWidth;\n\n        if (includePadding) {\n          var offsetParentStyle = $window.getComputedStyle(offsetParent);\n          offsetBCR.top += this.parseStyle(offsetParentStyle.paddingTop);\n          offsetBCR.bottom -= this.parseStyle(offsetParentStyle.paddingBottom);\n          offsetBCR.left += this.parseStyle(offsetParentStyle.paddingLeft);\n          offsetBCR.right -= this.parseStyle(offsetParentStyle.paddingRight);\n        }\n\n        return {\n          top: Math.round(elemBCR.top - offsetBCR.top),\n          bottom: Math.round(offsetBCR.bottom - elemBCR.bottom),\n          left: Math.round(elemBCR.left - offsetBCR.left),\n          right: Math.round(offsetBCR.right - elemBCR.right)\n        };\n      },\n\n      /**\n       * Provides an array of placement values parsed from a placement string.\n       * Along with the 'auto' indicator, supported placement strings are:\n       *   <ul>\n       *     <li>top: element on top, horizontally centered on host element.</li>\n       *     <li>top-left: element on top, left edge aligned with host element left edge.</li>\n       *     <li>top-right: element on top, lerightft edge aligned with host element right edge.</li>\n       *     <li>bottom: element on bottom, horizontally centered on host element.</li>\n       *     <li>bottom-left: element on bottom, left edge aligned with host element left edge.</li>\n       *     <li>bottom-right: element on bottom, right edge aligned with host element right edge.</li>\n       *     <li>left: element on left, vertically centered on host element.</li>\n       *     <li>left-top: element on left, top edge aligned with host element top edge.</li>\n       *     <li>left-bottom: element on left, bottom edge aligned with host element bottom edge.</li>\n       *     <li>right: element on right, vertically centered on host element.</li>\n       *     <li>right-top: element on right, top edge aligned with host element top edge.</li>\n       *     <li>right-bottom: element on right, bottom edge aligned with host element bottom edge.</li>\n       *   </ul>\n       * A placement string with an 'auto' indicator is expected to be\n       * space separated from the placement, i.e: 'auto bottom-left'  If\n       * the primary and secondary placement values do not match 'top,\n       * bottom, left, right' then 'top' will be the primary placement and\n       * 'center' will be the secondary placement.  If 'auto' is passed, true\n       * will be returned as the 3rd value of the array.\n       *\n       * @param {string} placement - The placement string to parse.\n       *\n       * @returns {array} An array with the following values\n       * <ul>\n       *   <li>**[0]**: The primary placement.</li>\n       *   <li>**[1]**: The secondary placement.</li>\n       *   <li>**[2]**: If auto is passed: true, else undefined.</li>\n       * </ul>\n       */\n      parsePlacement: function(placement) {\n        var autoPlace = PLACEMENT_REGEX.auto.test(placement);\n        if (autoPlace) {\n          placement = placement.replace(PLACEMENT_REGEX.auto, '');\n        }\n\n        placement = placement.split('-');\n\n        placement[0] = placement[0] || 'top';\n        if (!PLACEMENT_REGEX.primary.test(placement[0])) {\n          placement[0] = 'top';\n        }\n\n        placement[1] = placement[1] || 'center';\n        if (!PLACEMENT_REGEX.secondary.test(placement[1])) {\n          placement[1] = 'center';\n        }\n\n        if (autoPlace) {\n          placement[2] = true;\n        } else {\n          placement[2] = false;\n        }\n\n        return placement;\n      },\n\n      /**\n       * Provides coordinates for an element to be positioned relative to\n       * another element.  Passing 'auto' as part of the placement parameter\n       * will enable smart placement - where the element fits. i.e:\n       * 'auto left-top' will check to see if there is enough space to the left\n       * of the hostElem to fit the targetElem, if not place right (same for secondary\n       * top placement).  Available space is calculated using the viewportOffset\n       * function.\n       *\n       * @param {element} hostElem - The element to position against.\n       * @param {element} targetElem - The element to position.\n       * @param {string=} [placement=top] - The placement for the targetElem,\n       *   default is 'top'. 'center' is assumed as secondary placement for\n       *   'top', 'left', 'right', and 'bottom' placements.  Available placements are:\n       *   <ul>\n       *     <li>top</li>\n       *     <li>top-right</li>\n       *     <li>top-left</li>\n       *     <li>bottom</li>\n       *     <li>bottom-left</li>\n       *     <li>bottom-right</li>\n       *     <li>left</li>\n       *     <li>left-top</li>\n       *     <li>left-bottom</li>\n       *     <li>right</li>\n       *     <li>right-top</li>\n       *     <li>right-bottom</li>\n       *   </ul>\n       * @param {boolean=} [appendToBody=false] - Should the top and left values returned\n       *   be calculated from the body element, default is false.\n       *\n       * @returns {object} An object with the following properties:\n       *   <ul>\n       *     <li>**top**: Value for targetElem top.</li>\n       *     <li>**left**: Value for targetElem left.</li>\n       *     <li>**placement**: The resolved placement.</li>\n       *   </ul>\n       */\n      positionElements: function(hostElem, targetElem, placement, appendToBody) {\n        hostElem = this.getRawNode(hostElem);\n        targetElem = this.getRawNode(targetElem);\n\n        // need to read from prop to support tests.\n        var targetWidth = angular.isDefined(targetElem.offsetWidth) ? targetElem.offsetWidth : targetElem.prop('offsetWidth');\n        var targetHeight = angular.isDefined(targetElem.offsetHeight) ? targetElem.offsetHeight : targetElem.prop('offsetHeight');\n\n        placement = this.parsePlacement(placement);\n\n        var hostElemPos = appendToBody ? this.offset(hostElem) : this.position(hostElem);\n        var targetElemPos = {top: 0, left: 0, placement: ''};\n\n        if (placement[2]) {\n          var viewportOffset = this.viewportOffset(hostElem, appendToBody);\n\n          var targetElemStyle = $window.getComputedStyle(targetElem);\n          var adjustedSize = {\n            width: targetWidth + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginLeft) + this.parseStyle(targetElemStyle.marginRight))),\n            height: targetHeight + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginTop) + this.parseStyle(targetElemStyle.marginBottom)))\n          };\n\n          placement[0] = placement[0] === 'top' && adjustedSize.height > viewportOffset.top && adjustedSize.height <= viewportOffset.bottom ? 'bottom' :\n                         placement[0] === 'bottom' && adjustedSize.height > viewportOffset.bottom && adjustedSize.height <= viewportOffset.top ? 'top' :\n                         placement[0] === 'left' && adjustedSize.width > viewportOffset.left && adjustedSize.width <= viewportOffset.right ? 'right' :\n                         placement[0] === 'right' && adjustedSize.width > viewportOffset.right && adjustedSize.width <= viewportOffset.left ? 'left' :\n                         placement[0];\n\n          placement[1] = placement[1] === 'top' && adjustedSize.height - hostElemPos.height > viewportOffset.bottom && adjustedSize.height - hostElemPos.height <= viewportOffset.top ? 'bottom' :\n                         placement[1] === 'bottom' && adjustedSize.height - hostElemPos.height > viewportOffset.top && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom ? 'top' :\n                         placement[1] === 'left' && adjustedSize.width - hostElemPos.width > viewportOffset.right && adjustedSize.width - hostElemPos.width <= viewportOffset.left ? 'right' :\n                         placement[1] === 'right' && adjustedSize.width - hostElemPos.width > viewportOffset.left && adjustedSize.width - hostElemPos.width <= viewportOffset.right ? 'left' :\n                         placement[1];\n\n          if (placement[1] === 'center') {\n            if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n              var xOverflow = hostElemPos.width / 2 - targetWidth / 2;\n              if (viewportOffset.left + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.right) {\n                placement[1] = 'left';\n              } else if (viewportOffset.right + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.left) {\n                placement[1] = 'right';\n              }\n            } else {\n              var yOverflow = hostElemPos.height / 2 - adjustedSize.height / 2;\n              if (viewportOffset.top + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom) {\n                placement[1] = 'top';\n              } else if (viewportOffset.bottom + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.top) {\n                placement[1] = 'bottom';\n              }\n            }\n          }\n        }\n\n        switch (placement[0]) {\n          case 'top':\n            targetElemPos.top = hostElemPos.top - targetHeight;\n            break;\n          case 'bottom':\n            targetElemPos.top = hostElemPos.top + hostElemPos.height;\n            break;\n          case 'left':\n            targetElemPos.left = hostElemPos.left - targetWidth;\n            break;\n          case 'right':\n            targetElemPos.left = hostElemPos.left + hostElemPos.width;\n            break;\n        }\n\n        switch (placement[1]) {\n          case 'top':\n            targetElemPos.top = hostElemPos.top;\n            break;\n          case 'bottom':\n            targetElemPos.top = hostElemPos.top + hostElemPos.height - targetHeight;\n            break;\n          case 'left':\n            targetElemPos.left = hostElemPos.left;\n            break;\n          case 'right':\n            targetElemPos.left = hostElemPos.left + hostElemPos.width - targetWidth;\n            break;\n          case 'center':\n            if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n              targetElemPos.left = hostElemPos.left + hostElemPos.width / 2 - targetWidth / 2;\n            } else {\n              targetElemPos.top = hostElemPos.top + hostElemPos.height / 2 - targetHeight / 2;\n            }\n            break;\n        }\n\n        targetElemPos.top = Math.round(targetElemPos.top);\n        targetElemPos.left = Math.round(targetElemPos.left);\n        targetElemPos.placement = placement[1] === 'center' ? placement[0] : placement[0] + '-' + placement[1];\n\n        return targetElemPos;\n      },\n\n      /**\n       * Provides a way to adjust the top positioning after first\n       * render to correctly align element to top after content\n       * rendering causes resized element height\n       *\n       * @param {array} placementClasses - The array of strings of classes\n       * element should have.\n       * @param {object} containerPosition - The object with container\n       * position information\n       * @param {number} initialHeight - The initial height for the elem.\n       * @param {number} currentHeight - The current height for the elem.\n       */\n      adjustTop: function(placementClasses, containerPosition, initialHeight, currentHeight) {\n        if (placementClasses.indexOf('top') !== -1 && initialHeight !== currentHeight) {\n          return {\n            top: containerPosition.top - currentHeight + 'px'\n          };\n        }\n      },\n\n      /**\n       * Provides a way for positioning tooltip & dropdown\n       * arrows when using placement options beyond the standard\n       * left, right, top, or bottom.\n       *\n       * @param {element} elem - The tooltip/dropdown element.\n       * @param {string} placement - The placement for the elem.\n       */\n      positionArrow: function(elem, placement) {\n        elem = this.getRawNode(elem);\n\n        var innerElem = elem.querySelector('.tooltip-inner, .popover-inner');\n        if (!innerElem) {\n          return;\n        }\n\n        var isTooltip = angular.element(innerElem).hasClass('tooltip-inner');\n\n        var arrowElem = isTooltip ? elem.querySelector('.tooltip-arrow') : elem.querySelector('.arrow');\n        if (!arrowElem) {\n          return;\n        }\n\n        var arrowCss = {\n          top: '',\n          bottom: '',\n          left: '',\n          right: ''\n        };\n\n        placement = this.parsePlacement(placement);\n        if (placement[1] === 'center') {\n          // no adjustment necessary - just reset styles\n          angular.element(arrowElem).css(arrowCss);\n          return;\n        }\n\n        var borderProp = 'border-' + placement[0] + '-width';\n        var borderWidth = $window.getComputedStyle(arrowElem)[borderProp];\n\n        var borderRadiusProp = 'border-';\n        if (PLACEMENT_REGEX.vertical.test(placement[0])) {\n          borderRadiusProp += placement[0] + '-' + placement[1];\n        } else {\n          borderRadiusProp += placement[1] + '-' + placement[0];\n        }\n        borderRadiusProp += '-radius';\n        var borderRadius = $window.getComputedStyle(isTooltip ? innerElem : elem)[borderRadiusProp];\n\n        switch (placement[0]) {\n          case 'top':\n            arrowCss.bottom = isTooltip ? '0' : '-' + borderWidth;\n            break;\n          case 'bottom':\n            arrowCss.top = isTooltip ? '0' : '-' + borderWidth;\n            break;\n          case 'left':\n            arrowCss.right = isTooltip ? '0' : '-' + borderWidth;\n            break;\n          case 'right':\n            arrowCss.left = isTooltip ? '0' : '-' + borderWidth;\n            break;\n        }\n\n        arrowCss[placement[1]] = borderRadius;\n\n        angular.element(arrowElem).css(arrowCss);\n      }\n    };\n  }]);\n","src/datepickerPopup/popup.js":"angular.module('ui.bootstrap.datepickerPopup', ['ui.bootstrap.datepicker', 'ui.bootstrap.position'])\n\n.value('$datepickerPopupLiteralWarning', true)\n\n.constant('uibDatepickerPopupConfig', {\n  altInputFormats: [],\n  appendToBody: false,\n  clearText: 'Clear',\n  closeOnDateSelection: true,\n  closeText: 'Done',\n  currentText: 'Today',\n  datepickerPopup: 'yyyy-MM-dd',\n  datepickerPopupTemplateUrl: 'uib/template/datepickerPopup/popup.html',\n  datepickerTemplateUrl: 'uib/template/datepicker/datepicker.html',\n  html5Types: {\n    date: 'yyyy-MM-dd',\n    'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss',\n    'month': 'yyyy-MM'\n  },\n  onOpenFocus: true,\n  showButtonBar: true,\n  placement: 'auto bottom-left'\n})\n\n.controller('UibDatepickerPopupController', ['$scope', '$element', '$attrs', '$compile', '$log', '$parse', '$window', '$document', '$rootScope', '$uibPosition', 'dateFilter', 'uibDateParser', 'uibDatepickerPopupConfig', '$timeout', 'uibDatepickerConfig', '$datepickerPopupLiteralWarning',\nfunction($scope, $element, $attrs, $compile, $log, $parse, $window, $document, $rootScope, $position, dateFilter, dateParser, datepickerPopupConfig, $timeout, datepickerConfig, $datepickerPopupLiteralWarning) {\n  var cache = {},\n    isHtml5DateInput = false;\n  var dateFormat, closeOnDateSelection, appendToBody, onOpenFocus,\n    datepickerPopupTemplateUrl, datepickerTemplateUrl, popupEl, datepickerEl, scrollParentEl,\n    ngModel, ngModelOptions, $popup, altInputFormats, watchListeners = [];\n\n  this.init = function(_ngModel_) {\n    ngModel = _ngModel_;\n    ngModelOptions = extractOptions(ngModel);\n    closeOnDateSelection = angular.isDefined($attrs.closeOnDateSelection) ?\n      $scope.$parent.$eval($attrs.closeOnDateSelection) :\n      datepickerPopupConfig.closeOnDateSelection;\n    appendToBody = angular.isDefined($attrs.datepickerAppendToBody) ?\n      $scope.$parent.$eval($attrs.datepickerAppendToBody) :\n      datepickerPopupConfig.appendToBody;\n    onOpenFocus = angular.isDefined($attrs.onOpenFocus) ?\n      $scope.$parent.$eval($attrs.onOpenFocus) : datepickerPopupConfig.onOpenFocus;\n    datepickerPopupTemplateUrl = angular.isDefined($attrs.datepickerPopupTemplateUrl) ?\n      $attrs.datepickerPopupTemplateUrl :\n      datepickerPopupConfig.datepickerPopupTemplateUrl;\n    datepickerTemplateUrl = angular.isDefined($attrs.datepickerTemplateUrl) ?\n      $attrs.datepickerTemplateUrl : datepickerPopupConfig.datepickerTemplateUrl;\n    altInputFormats = angular.isDefined($attrs.altInputFormats) ?\n      $scope.$parent.$eval($attrs.altInputFormats) :\n      datepickerPopupConfig.altInputFormats;\n\n    $scope.showButtonBar = angular.isDefined($attrs.showButtonBar) ?\n      $scope.$parent.$eval($attrs.showButtonBar) :\n      datepickerPopupConfig.showButtonBar;\n\n    if (datepickerPopupConfig.html5Types[$attrs.type]) {\n      dateFormat = datepickerPopupConfig.html5Types[$attrs.type];\n      isHtml5DateInput = true;\n    } else {\n      dateFormat = $attrs.uibDatepickerPopup || datepickerPopupConfig.datepickerPopup;\n      $attrs.$observe('uibDatepickerPopup', function(value, oldValue) {\n        var newDateFormat = value || datepickerPopupConfig.datepickerPopup;\n        // Invalidate the $modelValue to ensure that formatters re-run\n        // FIXME: Refactor when PR is merged: https://github.com/angular/angular.js/pull/10764\n        if (newDateFormat !== dateFormat) {\n          dateFormat = newDateFormat;\n          ngModel.$modelValue = null;\n\n          if (!dateFormat) {\n            throw new Error('uibDatepickerPopup must have a date format specified.');\n          }\n        }\n      });\n    }\n\n    if (!dateFormat) {\n      throw new Error('uibDatepickerPopup must have a date format specified.');\n    }\n\n    if (isHtml5DateInput && $attrs.uibDatepickerPopup) {\n      throw new Error('HTML5 date input types do not support custom formats.');\n    }\n\n    // popup element used to display calendar\n    popupEl = angular.element('<div uib-datepicker-popup-wrap><div uib-datepicker></div></div>');\n\n    popupEl.attr({\n      'ng-model': 'date',\n      'ng-change': 'dateSelection(date)',\n      'template-url': datepickerPopupTemplateUrl\n    });\n\n    // datepicker element\n    datepickerEl = angular.element(popupEl.children()[0]);\n    datepickerEl.attr('template-url', datepickerTemplateUrl);\n\n    if (!$scope.datepickerOptions) {\n      $scope.datepickerOptions = {};\n    }\n\n    if (isHtml5DateInput) {\n      if ($attrs.type === 'month') {\n        $scope.datepickerOptions.datepickerMode = 'month';\n        $scope.datepickerOptions.minMode = 'month';\n      }\n    }\n\n    datepickerEl.attr('datepicker-options', 'datepickerOptions');\n\n    if (!isHtml5DateInput) {\n      // Internal API to maintain the correct ng-invalid-[key] class\n      ngModel.$$parserName = 'date';\n      ngModel.$validators.date = validator;\n      ngModel.$parsers.unshift(parseDate);\n      ngModel.$formatters.push(function(value) {\n        if (ngModel.$isEmpty(value)) {\n          $scope.date = value;\n          return value;\n        }\n\n        if (angular.isNumber(value)) {\n          value = new Date(value);\n        }\n\n        $scope.date = dateParser.fromTimezone(value, ngModelOptions.getOption('timezone'));\n\n        return dateParser.filter($scope.date, dateFormat);\n      });\n    } else {\n      ngModel.$formatters.push(function(value) {\n        $scope.date = dateParser.fromTimezone(value, ngModelOptions.getOption('timezone'));\n        return value;\n      });\n    }\n\n    // Detect changes in the view from the text box\n    ngModel.$viewChangeListeners.push(function() {\n      $scope.date = parseDateString(ngModel.$viewValue);\n    });\n\n    $element.on('keydown', inputKeydownBind);\n\n    $popup = $compile(popupEl)($scope);\n    // Prevent jQuery cache memory leak (template is now redundant after linking)\n    popupEl.remove();\n\n    if (appendToBody) {\n      $document.find('body').append($popup);\n    } else {\n      $element.after($popup);\n    }\n\n    $scope.$on('$destroy', function() {\n      if ($scope.isOpen === true) {\n        if (!$rootScope.$$phase) {\n          $scope.$apply(function() {\n            $scope.isOpen = false;\n          });\n        }\n      }\n\n      $popup.remove();\n      $element.off('keydown', inputKeydownBind);\n      $document.off('click', documentClickBind);\n      if (scrollParentEl) {\n        scrollParentEl.off('scroll', positionPopup);\n      }\n      angular.element($window).off('resize', positionPopup);\n\n      //Clear all watch listeners on destroy\n      while (watchListeners.length) {\n        watchListeners.shift()();\n      }\n    });\n  };\n\n  $scope.getText = function(key) {\n    return $scope[key + 'Text'] || datepickerPopupConfig[key + 'Text'];\n  };\n\n  $scope.isDisabled = function(date) {\n    if (date === 'today') {\n      date = dateParser.fromTimezone(new Date(), ngModelOptions.getOption('timezone'));\n    }\n\n    var dates = {};\n    angular.forEach(['minDate', 'maxDate'], function(key) {\n      if (!$scope.datepickerOptions[key]) {\n        dates[key] = null;\n      } else if (angular.isDate($scope.datepickerOptions[key])) {\n        dates[key] = new Date($scope.datepickerOptions[key]);\n      } else {\n        if ($datepickerPopupLiteralWarning) {\n          $log.warn('Literal date support has been deprecated, please switch to date object usage');\n        }\n\n        dates[key] = new Date(dateFilter($scope.datepickerOptions[key], 'medium'));\n      }\n    });\n\n    return $scope.datepickerOptions &&\n      dates.minDate && $scope.compare(date, dates.minDate) < 0 ||\n      dates.maxDate && $scope.compare(date, dates.maxDate) > 0;\n  };\n\n  $scope.compare = function(date1, date2) {\n    return new Date(date1.getFullYear(), date1.getMonth(), date1.getDate()) - new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());\n  };\n\n  // Inner change\n  $scope.dateSelection = function(dt) {\n    $scope.date = dt;\n    var date = $scope.date ? dateParser.filter($scope.date, dateFormat) : null; // Setting to NULL is necessary for form validators to function\n    $element.val(date);\n    ngModel.$setViewValue(date);\n\n    if (closeOnDateSelection) {\n      $scope.isOpen = false;\n      $element[0].focus();\n    }\n  };\n\n  $scope.keydown = function(evt) {\n    if (evt.which === 27) {\n      evt.stopPropagation();\n      $scope.isOpen = false;\n      $element[0].focus();\n    }\n  };\n\n  $scope.select = function(date, evt) {\n    evt.stopPropagation();\n\n    if (date === 'today') {\n      var today = new Date();\n      if (angular.isDate($scope.date)) {\n        date = new Date($scope.date);\n        date.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());\n      } else {\n        date = dateParser.fromTimezone(today, ngModelOptions.getOption('timezone'));\n        date.setHours(0, 0, 0, 0);\n      }\n    }\n    $scope.dateSelection(date);\n  };\n\n  $scope.close = function(evt) {\n    evt.stopPropagation();\n\n    $scope.isOpen = false;\n    $element[0].focus();\n  };\n\n  $scope.disabled = angular.isDefined($attrs.disabled) || false;\n  if ($attrs.ngDisabled) {\n    watchListeners.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(disabled) {\n      $scope.disabled = disabled;\n    }));\n  }\n\n  $scope.$watch('isOpen', function(value) {\n    if (value) {\n      if (!$scope.disabled) {\n        $timeout(function() {\n          positionPopup();\n\n          if (onOpenFocus) {\n            $scope.$broadcast('uib:datepicker.focus');\n          }\n\n          $document.on('click', documentClickBind);\n\n          var placement = $attrs.popupPlacement ? $attrs.popupPlacement : datepickerPopupConfig.placement;\n          if (appendToBody || $position.parsePlacement(placement)[2]) {\n            scrollParentEl = scrollParentEl || angular.element($position.scrollParent($element));\n            if (scrollParentEl) {\n              scrollParentEl.on('scroll', positionPopup);\n            }\n          } else {\n            scrollParentEl = null;\n          }\n\n          angular.element($window).on('resize', positionPopup);\n        }, 0, false);\n      } else {\n        $scope.isOpen = false;\n      }\n    } else {\n      $document.off('click', documentClickBind);\n      if (scrollParentEl) {\n        scrollParentEl.off('scroll', positionPopup);\n      }\n      angular.element($window).off('resize', positionPopup);\n    }\n  });\n\n  function cameltoDash(string) {\n    return string.replace(/([A-Z])/g, function($1) { return '-' + $1.toLowerCase(); });\n  }\n\n  function parseDateString(viewValue) {\n    var date = dateParser.parse(viewValue, dateFormat, $scope.date);\n    if (isNaN(date)) {\n      for (var i = 0; i < altInputFormats.length; i++) {\n        date = dateParser.parse(viewValue, altInputFormats[i], $scope.date);\n        if (!isNaN(date)) {\n          return date;\n        }\n      }\n    }\n    return date;\n  }\n\n  function parseDate(viewValue) {\n    if (angular.isNumber(viewValue)) {\n      // presumably timestamp to date object\n      viewValue = new Date(viewValue);\n    }\n\n    if (!viewValue) {\n      return null;\n    }\n\n    if (angular.isDate(viewValue) && !isNaN(viewValue)) {\n      return viewValue;\n    }\n\n    if (angular.isString(viewValue)) {\n      var date = parseDateString(viewValue);\n      if (!isNaN(date)) {\n        return dateParser.toTimezone(date, ngModelOptions.getOption('timezone'));\n      }\n    }\n\n    return ngModelOptions.getOption('allowInvalid') ? viewValue : undefined;\n  }\n\n  function validator(modelValue, viewValue) {\n    var value = modelValue || viewValue;\n\n    if (!$attrs.ngRequired && !value) {\n      return true;\n    }\n\n    if (angular.isNumber(value)) {\n      value = new Date(value);\n    }\n\n    if (!value) {\n      return true;\n    }\n\n    if (angular.isDate(value) && !isNaN(value)) {\n      return true;\n    }\n\n    if (angular.isString(value)) {\n      return !isNaN(parseDateString(value));\n    }\n\n    return false;\n  }\n\n  function documentClickBind(event) {\n    if (!$scope.isOpen && $scope.disabled) {\n      return;\n    }\n\n    var popup = $popup[0];\n    var dpContainsTarget = $element[0].contains(event.target);\n    // The popup node may not be an element node\n    // In some browsers (IE) only element nodes have the 'contains' function\n    var popupContainsTarget = popup.contains !== undefined && popup.contains(event.target);\n    if ($scope.isOpen && !(dpContainsTarget || popupContainsTarget)) {\n      $scope.$apply(function() {\n        $scope.isOpen = false;\n      });\n    }\n  }\n\n  function inputKeydownBind(evt) {\n    if (evt.which === 27 && $scope.isOpen) {\n      evt.preventDefault();\n      evt.stopPropagation();\n      $scope.$apply(function() {\n        $scope.isOpen = false;\n      });\n      $element[0].focus();\n    } else if (evt.which === 40 && !$scope.isOpen) {\n      evt.preventDefault();\n      evt.stopPropagation();\n      $scope.$apply(function() {\n        $scope.isOpen = true;\n      });\n    }\n  }\n\n  function positionPopup() {\n    if ($scope.isOpen) {\n      var dpElement = angular.element($popup[0].querySelector('.uib-datepicker-popup'));\n      var placement = $attrs.popupPlacement ? $attrs.popupPlacement : datepickerPopupConfig.placement;\n      var position = $position.positionElements($element, dpElement, placement, appendToBody);\n      dpElement.css({top: position.top + 'px', left: position.left + 'px'});\n      if (dpElement.hasClass('uib-position-measure')) {\n        dpElement.removeClass('uib-position-measure');\n      }\n    }\n  }\n\n  function extractOptions(ngModelCtrl) {\n    var ngModelOptions;\n\n    if (angular.version.minor < 6) { // in angular < 1.6 $options could be missing\n      // guarantee a value\n      ngModelOptions = angular.isObject(ngModelCtrl.$options) ?\n        ngModelCtrl.$options :\n        {\n          timezone: null\n        };\n\n      // mimic 1.6+ api\n      ngModelOptions.getOption = function (key) {\n        return ngModelOptions[key];\n      };\n    } else { // in angular >=1.6 $options is always present\n      ngModelOptions = ngModelCtrl.$options;\n    }\n\n    return ngModelOptions;\n  }\n\n  $scope.$on('uib:datepicker.mode', function() {\n    $timeout(positionPopup, 0, false);\n  });\n}])\n\n.directive('uibDatepickerPopup', function() {\n  return {\n    require: ['ngModel', 'uibDatepickerPopup'],\n    controller: 'UibDatepickerPopupController',\n    scope: {\n      datepickerOptions: '=?',\n      isOpen: '=?',\n      currentText: '@',\n      clearText: '@',\n      closeText: '@'\n    },\n    link: function(scope, element, attrs, ctrls) {\n      var ngModel = ctrls[0],\n        ctrl = ctrls[1];\n\n      ctrl.init(ngModel);\n    }\n  };\n})\n\n.directive('uibDatepickerPopupWrap', function() {\n  return {\n    restrict: 'A',\n    transclude: true,\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/datepickerPopup/popup.html';\n    }\n  };\n});\n","src/debounce/debounce.js":"angular.module('ui.bootstrap.debounce', [])\n/**\n * A helper, internal service that debounces a function\n */\n  .factory('$$debounce', ['$timeout', function($timeout) {\n    return function(callback, debounceTime) {\n      var timeoutPromise;\n\n      return function() {\n        var self = this;\n        var args = Array.prototype.slice.call(arguments);\n        if (timeoutPromise) {\n          $timeout.cancel(timeoutPromise);\n        }\n\n        timeoutPromise = $timeout(function() {\n          callback.apply(self, args);\n        }, debounceTime);\n      };\n    };\n  }]);\n","src/multiMap/multiMap.js":"angular.module('ui.bootstrap.multiMap', [])\n/**\n * A helper, internal data structure that stores all references attached to key\n */\n  .factory('$$multiMap', function() {\n    return {\n      createNew: function() {\n        var map = {};\n\n        return {\n          entries: function() {\n            return Object.keys(map).map(function(key) {\n              return {\n                key: key,\n                value: map[key]\n              };\n            });\n          },\n          get: function(key) {\n            return map[key];\n          },\n          hasKey: function(key) {\n            return !!map[key];\n          },\n          keys: function() {\n            return Object.keys(map);\n          },\n          put: function(key, value) {\n            if (!map[key]) {\n              map[key] = [];\n            }\n\n            map[key].push(value);\n          },\n          remove: function(key, value) {\n            var values = map[key];\n\n            if (!values) {\n              return;\n            }\n\n            var idx = values.indexOf(value);\n\n            if (idx !== -1) {\n              values.splice(idx, 1);\n            }\n\n            if (!values.length) {\n              delete map[key];\n            }\n          }\n        };\n      }\n    };\n  });\n","src/dropdown/dropdown.js":"angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.multiMap', 'ui.bootstrap.position'])\n\n.constant('uibDropdownConfig', {\n  appendToOpenClass: 'uib-dropdown-open',\n  openClass: 'open'\n})\n\n.service('uibDropdownService', ['$document', '$rootScope', '$$multiMap', function($document, $rootScope, $$multiMap) {\n  var openScope = null;\n  var openedContainers = $$multiMap.createNew();\n\n  this.isOnlyOpen = function(dropdownScope, appendTo) {\n    var openedDropdowns = openedContainers.get(appendTo);\n    if (openedDropdowns) {\n      var openDropdown = openedDropdowns.reduce(function(toClose, dropdown) {\n        if (dropdown.scope === dropdownScope) {\n          return dropdown;\n        }\n\n        return toClose;\n      }, {});\n      if (openDropdown) {\n        return openedDropdowns.length === 1;\n      }\n    }\n\n    return false;\n  };\n\n  this.open = function(dropdownScope, element, appendTo) {\n    if (!openScope) {\n      $document.on('click', closeDropdown);\n    }\n\n    if (openScope && openScope !== dropdownScope) {\n      openScope.isOpen = false;\n    }\n\n    openScope = dropdownScope;\n\n    if (!appendTo) {\n      return;\n    }\n\n    var openedDropdowns = openedContainers.get(appendTo);\n    if (openedDropdowns) {\n      var openedScopes = openedDropdowns.map(function(dropdown) {\n        return dropdown.scope;\n      });\n      if (openedScopes.indexOf(dropdownScope) === -1) {\n        openedContainers.put(appendTo, {\n          scope: dropdownScope\n        });\n      }\n    } else {\n      openedContainers.put(appendTo, {\n        scope: dropdownScope\n      });\n    }\n  };\n\n  this.close = function(dropdownScope, element, appendTo) {\n    if (openScope === dropdownScope) {\n      $document.off('click', closeDropdown);\n      $document.off('keydown', this.keybindFilter);\n      openScope = null;\n    }\n\n    if (!appendTo) {\n      return;\n    }\n\n    var openedDropdowns = openedContainers.get(appendTo);\n    if (openedDropdowns) {\n      var dropdownToClose = openedDropdowns.reduce(function(toClose, dropdown) {\n        if (dropdown.scope === dropdownScope) {\n          return dropdown;\n        }\n\n        return toClose;\n      }, {});\n      if (dropdownToClose) {\n        openedContainers.remove(appendTo, dropdownToClose);\n      }\n    }\n  };\n\n  var closeDropdown = function(evt) {\n    // This method may still be called during the same mouse event that\n    // unbound this event handler. So check openScope before proceeding.\n    if (!openScope || !openScope.isOpen) { return; }\n\n    if (evt && openScope.getAutoClose() === 'disabled') { return; }\n\n    if (evt && evt.which === 3) { return; }\n\n    var toggleElement = openScope.getToggleElement();\n    if (evt && toggleElement && toggleElement[0].contains(evt.target)) {\n      return;\n    }\n\n    var dropdownElement = openScope.getDropdownElement();\n    if (evt && openScope.getAutoClose() === 'outsideClick' &&\n      dropdownElement && dropdownElement[0].contains(evt.target)) {\n      return;\n    }\n\n    openScope.focusToggleElement();\n    openScope.isOpen = false;\n\n    if (!$rootScope.$$phase) {\n      openScope.$apply();\n    }\n  };\n\n  this.keybindFilter = function(evt) {\n    if (!openScope) {\n      // see this.close as ESC could have been pressed which kills the scope so we can not proceed\n      return;\n    }\n\n    var dropdownElement = openScope.getDropdownElement();\n    var toggleElement = openScope.getToggleElement();\n    var dropdownElementTargeted = dropdownElement && dropdownElement[0].contains(evt.target);\n    var toggleElementTargeted = toggleElement && toggleElement[0].contains(evt.target);\n    if (evt.which === 27) {\n      evt.stopPropagation();\n      openScope.focusToggleElement();\n      closeDropdown();\n    } else if (openScope.isKeynavEnabled() && [38, 40].indexOf(evt.which) !== -1 && openScope.isOpen && (dropdownElementTargeted || toggleElementTargeted)) {\n      evt.preventDefault();\n      evt.stopPropagation();\n      openScope.focusDropdownEntry(evt.which);\n    }\n  };\n}])\n\n.controller('UibDropdownController', ['$scope', '$element', '$attrs', '$parse', 'uibDropdownConfig', 'uibDropdownService', '$animate', '$uibPosition', '$document', '$compile', '$templateRequest', function($scope, $element, $attrs, $parse, dropdownConfig, uibDropdownService, $animate, $position, $document, $compile, $templateRequest) {\n  var self = this,\n    scope = $scope.$new(), // create a child scope so we are not polluting original one\n    templateScope,\n    appendToOpenClass = dropdownConfig.appendToOpenClass,\n    openClass = dropdownConfig.openClass,\n    getIsOpen,\n    setIsOpen = angular.noop,\n    toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop,\n    keynavEnabled = false,\n    selectedOption = null,\n    body = $document.find('body');\n\n  $element.addClass('dropdown');\n\n  this.init = function() {\n    if ($attrs.isOpen) {\n      getIsOpen = $parse($attrs.isOpen);\n      setIsOpen = getIsOpen.assign;\n\n      $scope.$watch(getIsOpen, function(value) {\n        scope.isOpen = !!value;\n      });\n    }\n\n    keynavEnabled = angular.isDefined($attrs.keyboardNav);\n  };\n\n  this.toggle = function(open) {\n    scope.isOpen = arguments.length ? !!open : !scope.isOpen;\n    if (angular.isFunction(setIsOpen)) {\n      setIsOpen(scope, scope.isOpen);\n    }\n\n    return scope.isOpen;\n  };\n\n  // Allow other directives to watch status\n  this.isOpen = function() {\n    return scope.isOpen;\n  };\n\n  scope.getToggleElement = function() {\n    return self.toggleElement;\n  };\n\n  scope.getAutoClose = function() {\n    return $attrs.autoClose || 'always'; //or 'outsideClick' or 'disabled'\n  };\n\n  scope.getElement = function() {\n    return $element;\n  };\n\n  scope.isKeynavEnabled = function() {\n    return keynavEnabled;\n  };\n\n  scope.focusDropdownEntry = function(keyCode) {\n    var elems = self.dropdownMenu ? //If append to body is used.\n      angular.element(self.dropdownMenu).find('a') :\n      $element.find('ul').eq(0).find('a');\n\n    switch (keyCode) {\n      case 40: {\n        if (!angular.isNumber(self.selectedOption)) {\n          self.selectedOption = 0;\n        } else {\n          self.selectedOption = self.selectedOption === elems.length - 1 ?\n            self.selectedOption :\n            self.selectedOption + 1;\n        }\n        break;\n      }\n      case 38: {\n        if (!angular.isNumber(self.selectedOption)) {\n          self.selectedOption = elems.length - 1;\n        } else {\n          self.selectedOption = self.selectedOption === 0 ?\n            0 : self.selectedOption - 1;\n        }\n        break;\n      }\n    }\n    elems[self.selectedOption].focus();\n  };\n\n  scope.getDropdownElement = function() {\n    return self.dropdownMenu;\n  };\n\n  scope.focusToggleElement = function() {\n    if (self.toggleElement) {\n      self.toggleElement[0].focus();\n    }\n  };\n\n  function removeDropdownMenu() {\n    $element.append(self.dropdownMenu);\n  }\n\n  scope.$watch('isOpen', function(isOpen, wasOpen) {\n    var appendTo = null,\n      appendToBody = false;\n\n    if (angular.isDefined($attrs.dropdownAppendTo)) {\n      var appendToEl = $parse($attrs.dropdownAppendTo)(scope);\n      if (appendToEl) {\n        appendTo = angular.element(appendToEl);\n      }\n    }\n\n    if (angular.isDefined($attrs.dropdownAppendToBody)) {\n      var appendToBodyValue = $parse($attrs.dropdownAppendToBody)(scope);\n      if (appendToBodyValue !== false) {\n        appendToBody = true;\n      }\n    }\n\n    if (appendToBody && !appendTo) {\n      appendTo = body;\n    }\n\n    if (appendTo && self.dropdownMenu) {\n      if (isOpen) {\n        appendTo.append(self.dropdownMenu);\n        $element.on('$destroy', removeDropdownMenu);\n      } else {\n        $element.off('$destroy', removeDropdownMenu);\n        removeDropdownMenu();\n      }\n    }\n\n    if (appendTo && self.dropdownMenu) {\n      var pos = $position.positionElements($element, self.dropdownMenu, 'bottom-left', true),\n        css,\n        rightalign,\n        scrollbarPadding,\n        scrollbarWidth = 0;\n\n      css = {\n        top: pos.top + 'px',\n        display: isOpen ? 'block' : 'none'\n      };\n\n      rightalign = self.dropdownMenu.hasClass('dropdown-menu-right');\n      if (!rightalign) {\n        css.left = pos.left + 'px';\n        css.right = 'auto';\n      } else {\n        css.left = 'auto';\n        scrollbarPadding = $position.scrollbarPadding(appendTo);\n\n        if (scrollbarPadding.heightOverflow && scrollbarPadding.scrollbarWidth) {\n          scrollbarWidth = scrollbarPadding.scrollbarWidth;\n        }\n\n        css.right = window.innerWidth - scrollbarWidth -\n          (pos.left + $element.prop('offsetWidth')) + 'px';\n      }\n\n      // Need to adjust our positioning to be relative to the appendTo container\n      // if it's not the body element\n      if (!appendToBody) {\n        var appendOffset = $position.offset(appendTo);\n\n        css.top = pos.top - appendOffset.top + 'px';\n\n        if (!rightalign) {\n          css.left = pos.left - appendOffset.left + 'px';\n        } else {\n          css.right = window.innerWidth -\n            (pos.left - appendOffset.left + $element.prop('offsetWidth')) + 'px';\n        }\n      }\n\n      self.dropdownMenu.css(css);\n    }\n\n    var openContainer = appendTo ? appendTo : $element;\n    var dropdownOpenClass = appendTo ? appendToOpenClass : openClass;\n    var hasOpenClass = openContainer.hasClass(dropdownOpenClass);\n    var isOnlyOpen = uibDropdownService.isOnlyOpen($scope, appendTo);\n\n    if (hasOpenClass === !isOpen) {\n      var toggleClass;\n      if (appendTo) {\n        toggleClass = !isOnlyOpen ? 'addClass' : 'removeClass';\n      } else {\n        toggleClass = isOpen ? 'addClass' : 'removeClass';\n      }\n      $animate[toggleClass](openContainer, dropdownOpenClass).then(function() {\n        if (angular.isDefined(isOpen) && isOpen !== wasOpen) {\n          toggleInvoker($scope, { open: !!isOpen });\n        }\n      });\n    }\n\n    if (isOpen) {\n      if (self.dropdownMenuTemplateUrl) {\n        $templateRequest(self.dropdownMenuTemplateUrl).then(function(tplContent) {\n          templateScope = scope.$new();\n          $compile(tplContent.trim())(templateScope, function(dropdownElement) {\n            var newEl = dropdownElement;\n            self.dropdownMenu.replaceWith(newEl);\n            self.dropdownMenu = newEl;\n            $document.on('keydown', uibDropdownService.keybindFilter);\n          });\n        });\n      } else {\n        $document.on('keydown', uibDropdownService.keybindFilter);\n      }\n\n      scope.focusToggleElement();\n      uibDropdownService.open(scope, $element, appendTo);\n    } else {\n      uibDropdownService.close(scope, $element, appendTo);\n      if (self.dropdownMenuTemplateUrl) {\n        if (templateScope) {\n          templateScope.$destroy();\n        }\n        var newEl = angular.element('<ul class=\"dropdown-menu\"></ul>');\n        self.dropdownMenu.replaceWith(newEl);\n        self.dropdownMenu = newEl;\n      }\n\n      self.selectedOption = null;\n    }\n\n    if (angular.isFunction(setIsOpen)) {\n      setIsOpen($scope, isOpen);\n    }\n  });\n}])\n\n.directive('uibDropdown', function() {\n  return {\n    controller: 'UibDropdownController',\n    link: function(scope, element, attrs, dropdownCtrl) {\n      dropdownCtrl.init();\n    }\n  };\n})\n\n.directive('uibDropdownMenu', function() {\n  return {\n    restrict: 'A',\n    require: '?^uibDropdown',\n    link: function(scope, element, attrs, dropdownCtrl) {\n      if (!dropdownCtrl || angular.isDefined(attrs.dropdownNested)) {\n        return;\n      }\n\n      element.addClass('dropdown-menu');\n\n      var tplUrl = attrs.templateUrl;\n      if (tplUrl) {\n        dropdownCtrl.dropdownMenuTemplateUrl = tplUrl;\n      }\n\n      if (!dropdownCtrl.dropdownMenu) {\n        dropdownCtrl.dropdownMenu = element;\n      }\n    }\n  };\n})\n\n.directive('uibDropdownToggle', function() {\n  return {\n    require: '?^uibDropdown',\n    link: function(scope, element, attrs, dropdownCtrl) {\n      if (!dropdownCtrl) {\n        return;\n      }\n\n      element.addClass('dropdown-toggle');\n\n      dropdownCtrl.toggleElement = element;\n\n      var toggleDropdown = function(event) {\n        event.preventDefault();\n\n        if (!element.hasClass('disabled') && !attrs.disabled) {\n          scope.$apply(function() {\n            dropdownCtrl.toggle();\n          });\n        }\n      };\n\n      element.on('click', toggleDropdown);\n\n      // WAI-ARIA\n      element.attr({ 'aria-haspopup': true, 'aria-expanded': false });\n      scope.$watch(dropdownCtrl.isOpen, function(isOpen) {\n        element.attr('aria-expanded', !!isOpen);\n      });\n\n      scope.$on('$destroy', function() {\n        element.off('click', toggleDropdown);\n      });\n    }\n  };\n});\n","src/stackedMap/stackedMap.js":"angular.module('ui.bootstrap.stackedMap', [])\n/**\n * A helper, internal data structure that acts as a map but also allows getting / removing\n * elements in the LIFO order\n */\n  .factory('$$stackedMap', function() {\n    return {\n      createNew: function() {\n        var stack = [];\n\n        return {\n          add: function(key, value) {\n            stack.push({\n              key: key,\n              value: value\n            });\n          },\n          get: function(key) {\n            for (var i = 0; i < stack.length; i++) {\n              if (key === stack[i].key) {\n                return stack[i];\n              }\n            }\n          },\n          keys: function() {\n            var keys = [];\n            for (var i = 0; i < stack.length; i++) {\n              keys.push(stack[i].key);\n            }\n            return keys;\n          },\n          top: function() {\n            return stack[stack.length - 1];\n          },\n          remove: function(key) {\n            var idx = -1;\n            for (var i = 0; i < stack.length; i++) {\n              if (key === stack[i].key) {\n                idx = i;\n                break;\n              }\n            }\n            return stack.splice(idx, 1)[0];\n          },\n          removeTop: function() {\n            return stack.pop();\n          },\n          length: function() {\n            return stack.length;\n          }\n        };\n      }\n    };\n  });","src/modal/modal.js":"angular.module('ui.bootstrap.modal', ['ui.bootstrap.multiMap', 'ui.bootstrap.stackedMap', 'ui.bootstrap.position'])\n/**\n * Pluggable resolve mechanism for the modal resolve resolution\n * Supports UI Router's $resolve service\n */\n  .provider('$uibResolve', function() {\n    var resolve = this;\n    this.resolver = null;\n\n    this.setResolver = function(resolver) {\n      this.resolver = resolver;\n    };\n\n    this.$get = ['$injector', '$q', function($injector, $q) {\n      var resolver = resolve.resolver ? $injector.get(resolve.resolver) : null;\n      return {\n        resolve: function(invocables, locals, parent, self) {\n          if (resolver) {\n            return resolver.resolve(invocables, locals, parent, self);\n          }\n\n          var promises = [];\n\n          angular.forEach(invocables, function(value) {\n            if (angular.isFunction(value) || angular.isArray(value)) {\n              promises.push($q.resolve($injector.invoke(value)));\n            } else if (angular.isString(value)) {\n              promises.push($q.resolve($injector.get(value)));\n            } else {\n              promises.push($q.resolve(value));\n            }\n          });\n\n          return $q.all(promises).then(function(resolves) {\n            var resolveObj = {};\n            var resolveIter = 0;\n            angular.forEach(invocables, function(value, key) {\n              resolveObj[key] = resolves[resolveIter++];\n            });\n\n            return resolveObj;\n          });\n        }\n      };\n    }];\n  })\n\n/**\n * A helper directive for the $modal service. It creates a backdrop element.\n */\n  .directive('uibModalBackdrop', ['$animate', '$injector', '$uibModalStack',\n  function($animate, $injector, $modalStack) {\n    return {\n      restrict: 'A',\n      compile: function(tElement, tAttrs) {\n        tElement.addClass(tAttrs.backdropClass);\n        return linkFn;\n      }\n    };\n\n    function linkFn(scope, element, attrs) {\n      if (attrs.modalInClass) {\n        $animate.addClass(element, attrs.modalInClass);\n\n        scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {\n          var done = setIsAsync();\n          if (scope.modalOptions.animation) {\n            $animate.removeClass(element, attrs.modalInClass).then(done);\n          } else {\n            done();\n          }\n        });\n      }\n    }\n  }])\n\n  .directive('uibModalWindow', ['$uibModalStack', '$q', '$animateCss', '$document',\n  function($modalStack, $q, $animateCss, $document) {\n    return {\n      scope: {\n        index: '@'\n      },\n      restrict: 'A',\n      transclude: true,\n      templateUrl: function(tElement, tAttrs) {\n        return tAttrs.templateUrl || 'uib/template/modal/window.html';\n      },\n      link: function(scope, element, attrs) {\n        element.addClass(attrs.windowTopClass || '');\n        scope.size = attrs.size;\n\n        scope.close = function(evt) {\n          var modal = $modalStack.getTop();\n          if (modal && modal.value.backdrop &&\n            modal.value.backdrop !== 'static' &&\n            evt.target === evt.currentTarget) {\n            evt.preventDefault();\n            evt.stopPropagation();\n            $modalStack.dismiss(modal.key, 'backdrop click');\n          }\n        };\n\n        // moved from template to fix issue #2280\n        element.on('click', scope.close);\n\n        // This property is only added to the scope for the purpose of detecting when this directive is rendered.\n        // We can detect that by using this property in the template associated with this directive and then use\n        // {@link Attribute#$observe} on it. For more details please see {@link TableColumnResize}.\n        scope.$isRendered = true;\n\n        // Deferred object that will be resolved when this modal is rendered.\n        var modalRenderDeferObj = $q.defer();\n        // Resolve render promise post-digest\n        scope.$$postDigest(function() {\n          modalRenderDeferObj.resolve();\n        });\n\n        modalRenderDeferObj.promise.then(function() {\n          var animationPromise = null;\n\n          if (attrs.modalInClass) {\n            animationPromise = $animateCss(element, {\n              addClass: attrs.modalInClass\n            }).start();\n\n            scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {\n              var done = setIsAsync();\n              $animateCss(element, {\n                removeClass: attrs.modalInClass\n              }).start().then(done);\n            });\n          }\n\n\n          $q.when(animationPromise).then(function() {\n            // Notify {@link $modalStack} that modal is rendered.\n            var modal = $modalStack.getTop();\n            if (modal) {\n              $modalStack.modalRendered(modal.key);\n            }\n\n            /**\n             * If something within the freshly-opened modal already has focus (perhaps via a\n             * directive that causes focus) then there's no need to try to focus anything.\n             */\n            if (!($document[0].activeElement && element[0].contains($document[0].activeElement))) {\n              var inputWithAutofocus = element[0].querySelector('[autofocus]');\n              /**\n               * Auto-focusing of a freshly-opened modal element causes any child elements\n               * with the autofocus attribute to lose focus. This is an issue on touch\n               * based devices which will show and then hide the onscreen keyboard.\n               * Attempts to refocus the autofocus element via JavaScript will not reopen\n               * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus\n               * the modal element if the modal does not contain an autofocus element.\n               */\n              if (inputWithAutofocus) {\n                inputWithAutofocus.focus();\n              } else {\n                element[0].focus();\n              }\n            }\n          });\n        });\n      }\n    };\n  }])\n\n  .directive('uibModalAnimationClass', function() {\n    return {\n      compile: function(tElement, tAttrs) {\n        if (tAttrs.modalAnimation) {\n          tElement.addClass(tAttrs.uibModalAnimationClass);\n        }\n      }\n    };\n  })\n\n  .directive('uibModalTransclude', ['$animate', function($animate) {\n    return {\n      link: function(scope, element, attrs, controller, transclude) {\n        transclude(scope.$parent, function(clone) {\n          element.empty();\n          $animate.enter(clone, element);\n        });\n      }\n    };\n  }])\n\n  .factory('$uibModalStack', ['$animate', '$animateCss', '$document',\n    '$compile', '$rootScope', '$q', '$$multiMap', '$$stackedMap', '$uibPosition',\n    function($animate, $animateCss, $document, $compile, $rootScope, $q, $$multiMap, $$stackedMap, $uibPosition) {\n      var OPENED_MODAL_CLASS = 'modal-open';\n\n      var backdropDomEl, backdropScope;\n      var openedWindows = $$stackedMap.createNew();\n      var openedClasses = $$multiMap.createNew();\n      var $modalStack = {\n        NOW_CLOSING_EVENT: 'modal.stack.now-closing'\n      };\n      var topModalIndex = 0;\n      var previousTopOpenedModal = null;\n      var ARIA_HIDDEN_ATTRIBUTE_NAME = 'data-bootstrap-modal-aria-hidden-count';\n\n      //Modal focus behavior\n      var tabbableSelector = 'a[href], area[href], input:not([disabled]):not([tabindex=\\'-1\\']), ' +\n        'button:not([disabled]):not([tabindex=\\'-1\\']),select:not([disabled]):not([tabindex=\\'-1\\']), textarea:not([disabled]):not([tabindex=\\'-1\\']), ' +\n        'iframe, object, embed, *[tabindex]:not([tabindex=\\'-1\\']), *[contenteditable=true]';\n      var scrollbarPadding;\n      var SNAKE_CASE_REGEXP = /[A-Z]/g;\n\n      // TODO: extract into common dependency with tooltip\n      function snake_case(name) {\n        var separator = '-';\n        return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n          return (pos ? separator : '') + letter.toLowerCase();\n        });\n      }\n\n      function isVisible(element) {\n        return !!(element.offsetWidth ||\n          element.offsetHeight ||\n          element.getClientRects().length);\n      }\n\n      function backdropIndex() {\n        var topBackdropIndex = -1;\n        var opened = openedWindows.keys();\n        for (var i = 0; i < opened.length; i++) {\n          if (openedWindows.get(opened[i]).value.backdrop) {\n            topBackdropIndex = i;\n          }\n        }\n\n        // If any backdrop exist, ensure that it's index is always\n        // right below the top modal\n        if (topBackdropIndex > -1 && topBackdropIndex < topModalIndex) {\n          topBackdropIndex = topModalIndex;\n        }\n        return topBackdropIndex;\n      }\n\n      $rootScope.$watch(backdropIndex, function(newBackdropIndex) {\n        if (backdropScope) {\n          backdropScope.index = newBackdropIndex;\n        }\n      });\n\n      function removeModalWindow(modalInstance, elementToReceiveFocus) {\n        var modalWindow = openedWindows.get(modalInstance).value;\n        var appendToElement = modalWindow.appendTo;\n\n        //clean up the stack\n        openedWindows.remove(modalInstance);\n        previousTopOpenedModal = openedWindows.top();\n        if (previousTopOpenedModal) {\n          topModalIndex = parseInt(previousTopOpenedModal.value.modalDomEl.attr('index'), 10);\n        }\n\n        removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, function() {\n          var modalBodyClass = modalWindow.openedClass || OPENED_MODAL_CLASS;\n          openedClasses.remove(modalBodyClass, modalInstance);\n          var areAnyOpen = openedClasses.hasKey(modalBodyClass);\n          appendToElement.toggleClass(modalBodyClass, areAnyOpen);\n          if (!areAnyOpen && scrollbarPadding && scrollbarPadding.heightOverflow && scrollbarPadding.scrollbarWidth) {\n            if (scrollbarPadding.originalRight) {\n              appendToElement.css({paddingRight: scrollbarPadding.originalRight + 'px'});\n            } else {\n              appendToElement.css({paddingRight: ''});\n            }\n            scrollbarPadding = null;\n          }\n          toggleTopWindowClass(true);\n        }, modalWindow.closedDeferred);\n        checkRemoveBackdrop();\n\n        //move focus to specified element if available, or else to body\n        if (elementToReceiveFocus && elementToReceiveFocus.focus) {\n          elementToReceiveFocus.focus();\n        } else if (appendToElement.focus) {\n          appendToElement.focus();\n        }\n      }\n\n      // Add or remove \"windowTopClass\" from the top window in the stack\n      function toggleTopWindowClass(toggleSwitch) {\n        var modalWindow;\n\n        if (openedWindows.length() > 0) {\n          modalWindow = openedWindows.top().value;\n          modalWindow.modalDomEl.toggleClass(modalWindow.windowTopClass || '', toggleSwitch);\n        }\n      }\n\n      function checkRemoveBackdrop() {\n        //remove backdrop if no longer needed\n        if (backdropDomEl && backdropIndex() === -1) {\n          var backdropScopeRef = backdropScope;\n          removeAfterAnimate(backdropDomEl, backdropScope, function() {\n            backdropScopeRef = null;\n          });\n          backdropDomEl = undefined;\n          backdropScope = undefined;\n        }\n      }\n\n      function removeAfterAnimate(domEl, scope, done, closedDeferred) {\n        var asyncDeferred;\n        var asyncPromise = null;\n        var setIsAsync = function() {\n          if (!asyncDeferred) {\n            asyncDeferred = $q.defer();\n            asyncPromise = asyncDeferred.promise;\n          }\n\n          return function asyncDone() {\n            asyncDeferred.resolve();\n          };\n        };\n        scope.$broadcast($modalStack.NOW_CLOSING_EVENT, setIsAsync);\n\n        // Note that it's intentional that asyncPromise might be null.\n        // That's when setIsAsync has not been called during the\n        // NOW_CLOSING_EVENT broadcast.\n        return $q.when(asyncPromise).then(afterAnimating);\n\n        function afterAnimating() {\n          if (afterAnimating.done) {\n            return;\n          }\n          afterAnimating.done = true;\n\n          $animate.leave(domEl).then(function() {\n            if (done) {\n              done();\n            }\n\n            domEl.remove();\n            if (closedDeferred) {\n              closedDeferred.resolve();\n            }\n          });\n\n          scope.$destroy();\n        }\n      }\n\n      $document.on('keydown', keydownListener);\n\n      $rootScope.$on('$destroy', function() {\n        $document.off('keydown', keydownListener);\n      });\n\n      function keydownListener(evt) {\n        if (evt.isDefaultPrevented()) {\n          return evt;\n        }\n\n        var modal = openedWindows.top();\n        if (modal) {\n          switch (evt.which) {\n            case 27: {\n              if (modal.value.keyboard) {\n                evt.preventDefault();\n                $rootScope.$apply(function() {\n                  $modalStack.dismiss(modal.key, 'escape key press');\n                });\n              }\n              break;\n            }\n            case 9: {\n              var list = $modalStack.loadFocusElementList(modal);\n              var focusChanged = false;\n              if (evt.shiftKey) {\n                if ($modalStack.isFocusInFirstItem(evt, list) || $modalStack.isModalFocused(evt, modal)) {\n                  focusChanged = $modalStack.focusLastFocusableElement(list);\n                }\n              } else {\n                if ($modalStack.isFocusInLastItem(evt, list)) {\n                  focusChanged = $modalStack.focusFirstFocusableElement(list);\n                }\n              }\n\n              if (focusChanged) {\n                evt.preventDefault();\n                evt.stopPropagation();\n              }\n\n              break;\n            }\n          }\n        }\n      }\n\n      $modalStack.open = function(modalInstance, modal) {\n        var modalOpener = $document[0].activeElement,\n          modalBodyClass = modal.openedClass || OPENED_MODAL_CLASS;\n\n        toggleTopWindowClass(false);\n\n        // Store the current top first, to determine what index we ought to use\n        // for the current top modal\n        previousTopOpenedModal = openedWindows.top();\n\n        openedWindows.add(modalInstance, {\n          deferred: modal.deferred,\n          renderDeferred: modal.renderDeferred,\n          closedDeferred: modal.closedDeferred,\n          modalScope: modal.scope,\n          backdrop: modal.backdrop,\n          keyboard: modal.keyboard,\n          openedClass: modal.openedClass,\n          windowTopClass: modal.windowTopClass,\n          animation: modal.animation,\n          appendTo: modal.appendTo\n        });\n\n        openedClasses.put(modalBodyClass, modalInstance);\n\n        var appendToElement = modal.appendTo,\n            currBackdropIndex = backdropIndex();\n\n        if (currBackdropIndex >= 0 && !backdropDomEl) {\n          backdropScope = $rootScope.$new(true);\n          backdropScope.modalOptions = modal;\n          backdropScope.index = currBackdropIndex;\n          backdropDomEl = angular.element('<div uib-modal-backdrop=\"modal-backdrop\"></div>');\n          backdropDomEl.attr({\n            'class': 'modal-backdrop',\n            'ng-style': '{\\'z-index\\': 1040 + (index && 1 || 0) + index*10}',\n            'uib-modal-animation-class': 'fade',\n            'modal-in-class': 'in'\n          });\n          if (modal.backdropClass) {\n            backdropDomEl.addClass(modal.backdropClass);\n          }\n\n          if (modal.animation) {\n            backdropDomEl.attr('modal-animation', 'true');\n          }\n          $compile(backdropDomEl)(backdropScope);\n          $animate.enter(backdropDomEl, appendToElement);\n          if ($uibPosition.isScrollable(appendToElement)) {\n            scrollbarPadding = $uibPosition.scrollbarPadding(appendToElement);\n            if (scrollbarPadding.heightOverflow && scrollbarPadding.scrollbarWidth) {\n              appendToElement.css({paddingRight: scrollbarPadding.right + 'px'});\n            }\n          }\n        }\n\n        var content;\n        if (modal.component) {\n          content = document.createElement(snake_case(modal.component.name));\n          content = angular.element(content);\n          content.attr({\n            resolve: '$resolve',\n            'modal-instance': '$uibModalInstance',\n            close: '$close($value)',\n            dismiss: '$dismiss($value)'\n          });\n        } else {\n          content = modal.content;\n        }\n\n        // Set the top modal index based on the index of the previous top modal\n        topModalIndex = previousTopOpenedModal ? parseInt(previousTopOpenedModal.value.modalDomEl.attr('index'), 10) + 1 : 0;\n        var angularDomEl = angular.element('<div uib-modal-window=\"modal-window\"></div>');\n        angularDomEl.attr({\n          'class': 'modal',\n          'template-url': modal.windowTemplateUrl,\n          'window-top-class': modal.windowTopClass,\n          'role': 'dialog',\n          'aria-labelledby': modal.ariaLabelledBy,\n          'aria-describedby': modal.ariaDescribedBy,\n          'size': modal.size,\n          'index': topModalIndex,\n          'animate': 'animate',\n          'ng-style': '{\\'z-index\\': 1050 + $$topModalIndex*10, display: \\'block\\'}',\n          'tabindex': -1,\n          'uib-modal-animation-class': 'fade',\n          'modal-in-class': 'in'\n        }).append(content);\n        if (modal.windowClass) {\n          angularDomEl.addClass(modal.windowClass);\n        }\n\n        if (modal.animation) {\n          angularDomEl.attr('modal-animation', 'true');\n        }\n\n        appendToElement.addClass(modalBodyClass);\n        if (modal.scope) {\n          // we need to explicitly add the modal index to the modal scope\n          // because it is needed by ngStyle to compute the zIndex property.\n          modal.scope.$$topModalIndex = topModalIndex;\n        }\n        $animate.enter($compile(angularDomEl)(modal.scope), appendToElement);\n\n        openedWindows.top().value.modalDomEl = angularDomEl;\n        openedWindows.top().value.modalOpener = modalOpener;\n\n        // applyAriaHidden(angularDomEl);\n\n        function applyAriaHidden(el) {\n          if (!el || el[0].tagName === 'BODY') {\n            return;\n          }\n\n          getSiblings(el).forEach(function(sibling) {\n            var elemIsAlreadyHidden = sibling.getAttribute('aria-hidden') === 'true',\n              ariaHiddenCount = parseInt(sibling.getAttribute(ARIA_HIDDEN_ATTRIBUTE_NAME), 10);\n\n            if (!ariaHiddenCount) {\n              ariaHiddenCount = elemIsAlreadyHidden ? 1 : 0;\n            }\n\n            sibling.setAttribute(ARIA_HIDDEN_ATTRIBUTE_NAME, ariaHiddenCount + 1);\n            sibling.setAttribute('aria-hidden', 'true');\n          });\n\n          return applyAriaHidden(el.parent());\n\n          function getSiblings(el) {\n            var children = el.parent() ? el.parent().children() : [];\n\n            return Array.prototype.filter.call(children, function(child) {\n              return child !== el[0];\n            });\n          }\n        }\n      };\n\n      function broadcastClosing(modalWindow, resultOrReason, closing) {\n        return !modalWindow.value.modalScope.$broadcast('modal.closing', resultOrReason, closing).defaultPrevented;\n      }\n\n      function unhideBackgroundElements() {\n        Array.prototype.forEach.call(\n          document.querySelectorAll('[' + ARIA_HIDDEN_ATTRIBUTE_NAME + ']'),\n          function(hiddenEl) {\n            var ariaHiddenCount = parseInt(hiddenEl.getAttribute(ARIA_HIDDEN_ATTRIBUTE_NAME), 10),\n              newHiddenCount = ariaHiddenCount - 1;\n            hiddenEl.setAttribute(ARIA_HIDDEN_ATTRIBUTE_NAME, newHiddenCount);\n\n            if (!newHiddenCount) {\n              hiddenEl.removeAttribute(ARIA_HIDDEN_ATTRIBUTE_NAME);\n              hiddenEl.removeAttribute('aria-hidden');\n            }\n          }\n        );\n      }\n\n      $modalStack.close = function(modalInstance, result) {\n        var modalWindow = openedWindows.get(modalInstance);\n        unhideBackgroundElements();\n        if (modalWindow && broadcastClosing(modalWindow, result, true)) {\n          modalWindow.value.modalScope.$$uibDestructionScheduled = true;\n          modalWindow.value.deferred.resolve(result);\n          removeModalWindow(modalInstance, modalWindow.value.modalOpener);\n          return true;\n        }\n\n        return !modalWindow;\n      };\n\n      $modalStack.dismiss = function(modalInstance, reason) {\n        var modalWindow = openedWindows.get(modalInstance);\n        unhideBackgroundElements();\n        if (modalWindow && broadcastClosing(modalWindow, reason, false)) {\n          modalWindow.value.modalScope.$$uibDestructionScheduled = true;\n          modalWindow.value.deferred.reject(reason);\n          removeModalWindow(modalInstance, modalWindow.value.modalOpener);\n          return true;\n        }\n        return !modalWindow;\n      };\n\n      $modalStack.dismissAll = function(reason) {\n        var topModal = this.getTop();\n        while (topModal && this.dismiss(topModal.key, reason)) {\n          topModal = this.getTop();\n        }\n      };\n\n      $modalStack.getTop = function() {\n        return openedWindows.top();\n      };\n\n      $modalStack.modalRendered = function(modalInstance) {\n        var modalWindow = openedWindows.get(modalInstance);\n        if (modalWindow) {\n          modalWindow.value.renderDeferred.resolve();\n        }\n      };\n\n      $modalStack.focusFirstFocusableElement = function(list) {\n        if (list.length > 0) {\n          list[0].focus();\n          return true;\n        }\n        return false;\n      };\n\n      $modalStack.focusLastFocusableElement = function(list) {\n        if (list.length > 0) {\n          list[list.length - 1].focus();\n          return true;\n        }\n        return false;\n      };\n\n      $modalStack.isModalFocused = function(evt, modalWindow) {\n        if (evt && modalWindow) {\n          var modalDomEl = modalWindow.value.modalDomEl;\n          if (modalDomEl && modalDomEl.length) {\n            return (evt.target || evt.srcElement) === modalDomEl[0];\n          }\n        }\n        return false;\n      };\n\n      $modalStack.isFocusInFirstItem = function(evt, list) {\n        if (list.length > 0) {\n          return (evt.target || evt.srcElement) === list[0];\n        }\n        return false;\n      };\n\n      $modalStack.isFocusInLastItem = function(evt, list) {\n        if (list.length > 0) {\n          return (evt.target || evt.srcElement) === list[list.length - 1];\n        }\n        return false;\n      };\n\n      $modalStack.loadFocusElementList = function(modalWindow) {\n        if (modalWindow) {\n          var modalDomE1 = modalWindow.value.modalDomEl;\n          if (modalDomE1 && modalDomE1.length) {\n            var elements = modalDomE1[0].querySelectorAll(tabbableSelector);\n            return elements ?\n              Array.prototype.filter.call(elements, function(element) {\n                return isVisible(element);\n              }) : elements;\n          }\n        }\n      };\n\n      return $modalStack;\n    }])\n\n  .provider('$uibModal', function() {\n    var $modalProvider = {\n      options: {\n        animation: true,\n        backdrop: true, //can also be false or 'static'\n        keyboard: true\n      },\n      $get: ['$rootScope', '$q', '$document', '$templateRequest', '$controller', '$uibResolve', '$uibModalStack',\n        function ($rootScope, $q, $document, $templateRequest, $controller, $uibResolve, $modalStack) {\n          var $modal = {};\n\n          function getTemplatePromise(options) {\n            return options.template ? $q.when(options.template) :\n              $templateRequest(angular.isFunction(options.templateUrl) ?\n                options.templateUrl() : options.templateUrl);\n          }\n\n          var promiseChain = null;\n          $modal.getPromiseChain = function() {\n            return promiseChain;\n          };\n\n          $modal.open = function(modalOptions) {\n            var modalResultDeferred = $q.defer();\n            var modalOpenedDeferred = $q.defer();\n            var modalClosedDeferred = $q.defer();\n            var modalRenderDeferred = $q.defer();\n\n            //prepare an instance of a modal to be injected into controllers and returned to a caller\n            var modalInstance = {\n              result: modalResultDeferred.promise,\n              opened: modalOpenedDeferred.promise,\n              closed: modalClosedDeferred.promise,\n              rendered: modalRenderDeferred.promise,\n              close: function (result) {\n                return $modalStack.close(modalInstance, result);\n              },\n              dismiss: function (reason) {\n                return $modalStack.dismiss(modalInstance, reason);\n              }\n            };\n\n            //merge and clean up options\n            modalOptions = angular.extend({}, $modalProvider.options, modalOptions);\n            modalOptions.resolve = modalOptions.resolve || {};\n            modalOptions.appendTo = modalOptions.appendTo || $document.find('body').eq(0);\n\n            if (!modalOptions.appendTo.length) {\n              throw new Error('appendTo element not found. Make sure that the element passed is in DOM.');\n            }\n\n            //verify options\n            if (!modalOptions.component && !modalOptions.template && !modalOptions.templateUrl) {\n              throw new Error('One of component or template or templateUrl options is required.');\n            }\n\n            var templateAndResolvePromise;\n            if (modalOptions.component) {\n              templateAndResolvePromise = $q.when($uibResolve.resolve(modalOptions.resolve, {}, null, null));\n            } else {\n              templateAndResolvePromise =\n                $q.all([getTemplatePromise(modalOptions), $uibResolve.resolve(modalOptions.resolve, {}, null, null)]);\n            }\n\n            function resolveWithTemplate() {\n              return templateAndResolvePromise;\n            }\n\n            // Wait for the resolution of the existing promise chain.\n            // Then switch to our own combined promise dependency (regardless of how the previous modal fared).\n            // Then add to $modalStack and resolve opened.\n            // Finally clean up the chain variable if no subsequent modal has overwritten it.\n            var samePromise;\n            samePromise = promiseChain = $q.all([promiseChain])\n              .then(resolveWithTemplate, resolveWithTemplate)\n              .then(function resolveSuccess(tplAndVars) {\n                var providedScope = modalOptions.scope || $rootScope;\n\n                var modalScope = providedScope.$new();\n                modalScope.$close = modalInstance.close;\n                modalScope.$dismiss = modalInstance.dismiss;\n\n                modalScope.$on('$destroy', function() {\n                  if (!modalScope.$$uibDestructionScheduled) {\n                    modalScope.$dismiss('$uibUnscheduledDestruction');\n                  }\n                });\n\n                var modal = {\n                  scope: modalScope,\n                  deferred: modalResultDeferred,\n                  renderDeferred: modalRenderDeferred,\n                  closedDeferred: modalClosedDeferred,\n                  animation: modalOptions.animation,\n                  backdrop: modalOptions.backdrop,\n                  keyboard: modalOptions.keyboard,\n                  backdropClass: modalOptions.backdropClass,\n                  windowTopClass: modalOptions.windowTopClass,\n                  windowClass: modalOptions.windowClass,\n                  windowTemplateUrl: modalOptions.windowTemplateUrl,\n                  ariaLabelledBy: modalOptions.ariaLabelledBy,\n                  ariaDescribedBy: modalOptions.ariaDescribedBy,\n                  size: modalOptions.size,\n                  openedClass: modalOptions.openedClass,\n                  appendTo: modalOptions.appendTo\n                };\n\n                var component = {};\n                var ctrlInstance, ctrlInstantiate, ctrlLocals = {};\n\n                if (modalOptions.component) {\n                  constructLocals(component, false, true, false);\n                  component.name = modalOptions.component;\n                  modal.component = component;\n                } else if (modalOptions.controller) {\n                  constructLocals(ctrlLocals, true, false, true);\n\n                  // the third param will make the controller instantiate later,private api\n                  // @see https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L126\n                  ctrlInstantiate = $controller(modalOptions.controller, ctrlLocals, true, modalOptions.controllerAs);\n                  if (modalOptions.controllerAs && modalOptions.bindToController) {\n                    ctrlInstance = ctrlInstantiate.instance;\n                    ctrlInstance.$close = modalScope.$close;\n                    ctrlInstance.$dismiss = modalScope.$dismiss;\n                    angular.extend(ctrlInstance, {\n                      $resolve: ctrlLocals.$scope.$resolve\n                    }, providedScope);\n                  }\n\n                  ctrlInstance = ctrlInstantiate();\n\n                  if (angular.isFunction(ctrlInstance.$onInit)) {\n                    ctrlInstance.$onInit();\n                  }\n                }\n\n                if (!modalOptions.component) {\n                  modal.content = tplAndVars[0];\n                }\n\n                $modalStack.open(modalInstance, modal);\n                modalOpenedDeferred.resolve(true);\n\n                function constructLocals(obj, template, instanceOnScope, injectable) {\n                  obj.$scope = modalScope;\n                  obj.$scope.$resolve = {};\n                  if (instanceOnScope) {\n                    obj.$scope.$uibModalInstance = modalInstance;\n                  } else {\n                    obj.$uibModalInstance = modalInstance;\n                  }\n\n                  var resolves = template ? tplAndVars[1] : tplAndVars;\n                  angular.forEach(resolves, function(value, key) {\n                    if (injectable) {\n                      obj[key] = value;\n                    }\n\n                    obj.$scope.$resolve[key] = value;\n                  });\n                }\n            }, function resolveError(reason) {\n              modalOpenedDeferred.reject(reason);\n              modalResultDeferred.reject(reason);\n            })['finally'](function() {\n              if (promiseChain === samePromise) {\n                promiseChain = null;\n              }\n            });\n\n            return modalInstance;\n          };\n\n          return $modal;\n        }\n      ]\n    };\n\n    return $modalProvider;\n  });\n","src/paging/paging.js":"angular.module('ui.bootstrap.paging', [])\n/**\n * Helper internal service for generating common controller code between the\n * pager and pagination components\n */\n.factory('uibPaging', ['$parse', function($parse) {\n  return {\n    create: function(ctrl, $scope, $attrs) {\n      ctrl.setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;\n      ctrl.ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl\n      ctrl._watchers = [];\n\n      ctrl.init = function(ngModelCtrl, config) {\n        ctrl.ngModelCtrl = ngModelCtrl;\n        ctrl.config = config;\n\n        ngModelCtrl.$render = function() {\n          ctrl.render();\n        };\n\n        if ($attrs.itemsPerPage) {\n          ctrl._watchers.push($scope.$parent.$watch($attrs.itemsPerPage, function(value) {\n            ctrl.itemsPerPage = parseInt(value, 10);\n            $scope.totalPages = ctrl.calculateTotalPages();\n            ctrl.updatePage();\n          }));\n        } else {\n          ctrl.itemsPerPage = config.itemsPerPage;\n        }\n\n        $scope.$watch('totalItems', function(newTotal, oldTotal) {\n          if (angular.isDefined(newTotal) || newTotal !== oldTotal) {\n            $scope.totalPages = ctrl.calculateTotalPages();\n            ctrl.updatePage();\n          }\n        });\n      };\n\n      ctrl.calculateTotalPages = function() {\n        var totalPages = ctrl.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / ctrl.itemsPerPage);\n        return Math.max(totalPages || 0, 1);\n      };\n\n      ctrl.render = function() {\n        $scope.page = parseInt(ctrl.ngModelCtrl.$viewValue, 10) || 1;\n      };\n\n      $scope.selectPage = function(page, evt) {\n        if (evt) {\n          evt.preventDefault();\n        }\n\n        var clickAllowed = !$scope.ngDisabled || !evt;\n        if (clickAllowed && $scope.page !== page && page > 0 && page <= $scope.totalPages) {\n          if (evt && evt.target) {\n            evt.target.blur();\n          }\n          ctrl.ngModelCtrl.$setViewValue(page);\n          ctrl.ngModelCtrl.$render();\n        }\n      };\n\n      $scope.getText = function(key) {\n        return $scope[key + 'Text'] || ctrl.config[key + 'Text'];\n      };\n\n      $scope.noPrevious = function() {\n        return $scope.page === 1;\n      };\n\n      $scope.noNext = function() {\n        return $scope.page === $scope.totalPages;\n      };\n\n      ctrl.updatePage = function() {\n        ctrl.setNumPages($scope.$parent, $scope.totalPages); // Readonly variable\n\n        if ($scope.page > $scope.totalPages) {\n          $scope.selectPage($scope.totalPages);\n        } else {\n          ctrl.ngModelCtrl.$render();\n        }\n      };\n\n      $scope.$on('$destroy', function() {\n        while (ctrl._watchers.length) {\n          ctrl._watchers.shift()();\n        }\n      });\n    }\n  };\n}]);\n","src/pager/pager.js":"angular.module('ui.bootstrap.pager', ['ui.bootstrap.paging', 'ui.bootstrap.tabindex'])\n\n.controller('UibPagerController', ['$scope', '$attrs', 'uibPaging', 'uibPagerConfig', function($scope, $attrs, uibPaging, uibPagerConfig) {\n  $scope.align = angular.isDefined($attrs.align) ? $scope.$parent.$eval($attrs.align) : uibPagerConfig.align;\n\n  uibPaging.create(this, $scope, $attrs);\n}])\n\n.constant('uibPagerConfig', {\n  itemsPerPage: 10,\n  previousText: '« Previous',\n  nextText: 'Next »',\n  align: true\n})\n\n.directive('uibPager', ['uibPagerConfig', function(uibPagerConfig) {\n  return {\n    scope: {\n      totalItems: '=',\n      previousText: '@',\n      nextText: '@',\n      ngDisabled: '='\n    },\n    require: ['uibPager', '?ngModel'],\n    restrict: 'A',\n    controller: 'UibPagerController',\n    controllerAs: 'pager',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/pager/pager.html';\n    },\n    link: function(scope, element, attrs, ctrls) {\n      element.addClass('pager');\n      var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n\n      if (!ngModelCtrl) {\n        return; // do nothing if no ng-model\n      }\n\n      paginationCtrl.init(ngModelCtrl, uibPagerConfig);\n    }\n  };\n}]);\n","src/pagination/pagination.js":"angular.module('ui.bootstrap.pagination', ['ui.bootstrap.paging', 'ui.bootstrap.tabindex'])\n.controller('UibPaginationController', ['$scope', '$attrs', '$parse', 'uibPaging', 'uibPaginationConfig', function($scope, $attrs, $parse, uibPaging, uibPaginationConfig) {\n  var ctrl = this;\n  // Setup configuration parameters\n  var maxSize = angular.isDefined($attrs.maxSize) ? $scope.$parent.$eval($attrs.maxSize) : uibPaginationConfig.maxSize,\n    rotate = angular.isDefined($attrs.rotate) ? $scope.$parent.$eval($attrs.rotate) : uibPaginationConfig.rotate,\n    forceEllipses = angular.isDefined($attrs.forceEllipses) ? $scope.$parent.$eval($attrs.forceEllipses) : uibPaginationConfig.forceEllipses,\n    boundaryLinkNumbers = angular.isDefined($attrs.boundaryLinkNumbers) ? $scope.$parent.$eval($attrs.boundaryLinkNumbers) : uibPaginationConfig.boundaryLinkNumbers,\n    pageLabel = angular.isDefined($attrs.pageLabel) ? function(idx) { return $scope.$parent.$eval($attrs.pageLabel, {$page: idx}); } : angular.identity;\n  $scope.boundaryLinks = angular.isDefined($attrs.boundaryLinks) ? $scope.$parent.$eval($attrs.boundaryLinks) : uibPaginationConfig.boundaryLinks;\n  $scope.directionLinks = angular.isDefined($attrs.directionLinks) ? $scope.$parent.$eval($attrs.directionLinks) : uibPaginationConfig.directionLinks;\n  $attrs.$set('role', 'menu');\n\n  uibPaging.create(this, $scope, $attrs);\n\n  if ($attrs.maxSize) {\n    ctrl._watchers.push($scope.$parent.$watch($parse($attrs.maxSize), function(value) {\n      maxSize = parseInt(value, 10);\n      ctrl.render();\n    }));\n  }\n\n  // Create page object used in template\n  function makePage(number, text, isActive) {\n    return {\n      number: number,\n      text: text,\n      active: isActive\n    };\n  }\n\n  function getPages(currentPage, totalPages) {\n    var pages = [];\n\n    // Default page limits\n    var startPage = 1, endPage = totalPages;\n    var isMaxSized = angular.isDefined(maxSize) && maxSize < totalPages;\n\n    // recompute if maxSize\n    if (isMaxSized) {\n      if (rotate) {\n        // Current page is displayed in the middle of the visible ones\n        startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1);\n        endPage = startPage + maxSize - 1;\n\n        // Adjust if limit is exceeded\n        if (endPage > totalPages) {\n          endPage = totalPages;\n          startPage = endPage - maxSize + 1;\n        }\n      } else {\n        // Visible pages are paginated with maxSize\n        startPage = (Math.ceil(currentPage / maxSize) - 1) * maxSize + 1;\n\n        // Adjust last page if limit is exceeded\n        endPage = Math.min(startPage + maxSize - 1, totalPages);\n      }\n    }\n\n    // Add page number links\n    for (var number = startPage; number <= endPage; number++) {\n      var page = makePage(number, pageLabel(number), number === currentPage);\n      pages.push(page);\n    }\n\n    // Add links to move between page sets\n    if (isMaxSized && maxSize > 0 && (!rotate || forceEllipses || boundaryLinkNumbers)) {\n      if (startPage > 1) {\n        if (!boundaryLinkNumbers || startPage > 3) { //need ellipsis for all options unless range is too close to beginning\n        var previousPageSet = makePage(startPage - 1, '...', false);\n        pages.unshift(previousPageSet);\n      }\n        if (boundaryLinkNumbers) {\n          if (startPage === 3) { //need to replace ellipsis when the buttons would be sequential\n            var secondPageLink = makePage(2, '2', false);\n            pages.unshift(secondPageLink);\n          }\n          //add the first page\n          var firstPageLink = makePage(1, '1', false);\n          pages.unshift(firstPageLink);\n        }\n      }\n\n      if (endPage < totalPages) {\n        if (!boundaryLinkNumbers || endPage < totalPages - 2) { //need ellipsis for all options unless range is too close to end\n        var nextPageSet = makePage(endPage + 1, '...', false);\n        pages.push(nextPageSet);\n      }\n        if (boundaryLinkNumbers) {\n          if (endPage === totalPages - 2) { //need to replace ellipsis when the buttons would be sequential\n            var secondToLastPageLink = makePage(totalPages - 1, totalPages - 1, false);\n            pages.push(secondToLastPageLink);\n          }\n          //add the last page\n          var lastPageLink = makePage(totalPages, totalPages, false);\n          pages.push(lastPageLink);\n        }\n      }\n    }\n    return pages;\n  }\n\n  var originalRender = this.render;\n  this.render = function() {\n    originalRender();\n    if ($scope.page > 0 && $scope.page <= $scope.totalPages) {\n      $scope.pages = getPages($scope.page, $scope.totalPages);\n    }\n  };\n}])\n\n.constant('uibPaginationConfig', {\n  itemsPerPage: 10,\n  boundaryLinks: false,\n  boundaryLinkNumbers: false,\n  directionLinks: true,\n  firstText: 'First',\n  previousText: 'Previous',\n  nextText: 'Next',\n  lastText: 'Last',\n  rotate: true,\n  forceEllipses: false\n})\n\n.directive('uibPagination', ['$parse', 'uibPaginationConfig', function($parse, uibPaginationConfig) {\n  return {\n    scope: {\n      totalItems: '=',\n      firstText: '@',\n      previousText: '@',\n      nextText: '@',\n      lastText: '@',\n      ngDisabled:'='\n    },\n    require: ['uibPagination', '?ngModel'],\n    restrict: 'A',\n    controller: 'UibPaginationController',\n    controllerAs: 'pagination',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/pagination/pagination.html';\n    },\n    link: function(scope, element, attrs, ctrls) {\n      element.addClass('pagination');\n      var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n\n      if (!ngModelCtrl) {\n         return; // do nothing if no ng-model\n      }\n\n      paginationCtrl.init(ngModelCtrl, uibPaginationConfig);\n    }\n  };\n}]);\n","src/tooltip/tooltip.js":"/**\n * The following features are still outstanding: animation as a\n * function, placement as a function, inside, support for more triggers than\n * just mouse enter/leave, html tooltips, and selector delegation.\n */\nangular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.stackedMap'])\n\n/**\n * The $tooltip service creates tooltip- and popover-like directives as well as\n * houses global options for them.\n */\n.provider('$uibTooltip', function() {\n  // The default options tooltip and popover.\n  var defaultOptions = {\n    placement: 'top',\n    placementClassPrefix: '',\n    animation: true,\n    popupDelay: 0,\n    popupCloseDelay: 0,\n    useContentExp: false\n  };\n\n  // Default hide triggers for each show trigger\n  var triggerMap = {\n    'mouseenter': 'mouseleave',\n    'click': 'click',\n    'outsideClick': 'outsideClick',\n    'focus': 'blur',\n    'none': ''\n  };\n\n  // The options specified to the provider globally.\n  var globalOptions = {};\n\n  /**\n   * `options({})` allows global configuration of all tooltips in the\n   * application.\n   *\n   *   var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {\n   *     // place tooltips left instead of top by default\n   *     $tooltipProvider.options( { placement: 'left' } );\n   *   });\n   */\n\tthis.options = function(value) {\n\t\tangular.extend(globalOptions, value);\n\t};\n\n  /**\n   * This allows you to extend the set of trigger mappings available. E.g.:\n   *\n   *   $tooltipProvider.setTriggers( { 'openTrigger': 'closeTrigger' } );\n   */\n  this.setTriggers = function setTriggers(triggers) {\n    angular.extend(triggerMap, triggers);\n  };\n\n  /**\n   * This is a helper function for translating camel-case to snake_case.\n   */\n  function snake_case(name) {\n    var regexp = /[A-Z]/g;\n    var separator = '-';\n    return name.replace(regexp, function(letter, pos) {\n      return (pos ? separator : '') + letter.toLowerCase();\n    });\n  }\n\n  /**\n   * Returns the actual instance of the $tooltip service.\n   * TODO support multiple triggers\n   */\n  this.$get = ['$window', '$compile', '$timeout', '$document', '$uibPosition', '$interpolate', '$rootScope', '$parse', '$$stackedMap', function($window, $compile, $timeout, $document, $position, $interpolate, $rootScope, $parse, $$stackedMap) {\n    var openedTooltips = $$stackedMap.createNew();\n    $document.on('keyup', keypressListener);\n\n    $rootScope.$on('$destroy', function() {\n      $document.off('keyup', keypressListener);\n    });\n\n    function keypressListener(e) {\n      if (e.which === 27) {\n        var last = openedTooltips.top();\n        if (last) {\n          last.value.close();\n          last = null;\n        }\n      }\n    }\n\n    return function $tooltip(ttType, prefix, defaultTriggerShow, options) {\n      options = angular.extend({}, defaultOptions, globalOptions, options);\n\n      /**\n       * Returns an object of show and hide triggers.\n       *\n       * If a trigger is supplied,\n       * it is used to show the tooltip; otherwise, it will use the `trigger`\n       * option passed to the `$tooltipProvider.options` method; else it will\n       * default to the trigger supplied to this directive factory.\n       *\n       * The hide trigger is based on the show trigger. If the `trigger` option\n       * was passed to the `$tooltipProvider.options` method, it will use the\n       * mapped trigger from `triggerMap` or the passed trigger if the map is\n       * undefined; otherwise, it uses the `triggerMap` value of the show\n       * trigger; else it will just use the show trigger.\n       */\n      function getTriggers(trigger) {\n        var show = (trigger || options.trigger || defaultTriggerShow).split(' ');\n        var hide = show.map(function(trigger) {\n          return triggerMap[trigger] || trigger;\n        });\n        return {\n          show: show,\n          hide: hide\n        };\n      }\n\n      var directiveName = snake_case(ttType);\n\n      var startSym = $interpolate.startSymbol();\n      var endSym = $interpolate.endSymbol();\n      var template =\n        '<div '+ directiveName + '-popup ' +\n          'uib-title=\"' + startSym + 'title' + endSym + '\" ' +\n          (options.useContentExp ?\n            'content-exp=\"contentExp()\" ' :\n            'content=\"' + startSym + 'content' + endSym + '\" ') +\n          'origin-scope=\"origScope\" ' +\n          'class=\"uib-position-measure ' + prefix + '\" ' +\n          'tooltip-animation-class=\"fade\"' +\n          'uib-tooltip-classes ' +\n          'ng-class=\"{ in: isOpen }\" ' +\n          '>' +\n        '</div>';\n\n      return {\n        compile: function(tElem, tAttrs) {\n          var tooltipLinker = $compile(template);\n\n          return function link(scope, element, attrs, tooltipCtrl) {\n            var tooltip;\n            var tooltipLinkedScope;\n            var transitionTimeout;\n            var showTimeout;\n            var hideTimeout;\n            var positionTimeout;\n            var adjustmentTimeout;\n            var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;\n            var triggers = getTriggers(undefined);\n            var hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);\n            var ttScope = scope.$new(true);\n            var repositionScheduled = false;\n            var isOpenParse = angular.isDefined(attrs[prefix + 'IsOpen']) ? $parse(attrs[prefix + 'IsOpen']) : false;\n            var contentParse = options.useContentExp ? $parse(attrs[ttType]) : false;\n            var observers = [];\n            var lastPlacement;\n\n            var positionTooltip = function() {\n              // check if tooltip exists and is not empty\n              if (!tooltip || !tooltip.html()) { return; }\n\n              if (!positionTimeout) {\n                positionTimeout = $timeout(function() {\n                  var ttPosition = $position.positionElements(element, tooltip, ttScope.placement, appendToBody);\n                  var initialHeight = angular.isDefined(tooltip.offsetHeight) ? tooltip.offsetHeight : tooltip.prop('offsetHeight');\n                  var elementPos = appendToBody ? $position.offset(element) : $position.position(element);\n                  tooltip.css({ top: ttPosition.top + 'px', left: ttPosition.left + 'px' });\n                  var placementClasses = ttPosition.placement.split('-');\n\n                  if (!tooltip.hasClass(placementClasses[0])) {\n                    tooltip.removeClass(lastPlacement.split('-')[0]);\n                    tooltip.addClass(placementClasses[0]);\n                  }\n\n                  if (!tooltip.hasClass(options.placementClassPrefix + ttPosition.placement)) {\n                    tooltip.removeClass(options.placementClassPrefix + lastPlacement);\n                    tooltip.addClass(options.placementClassPrefix + ttPosition.placement);\n                  }\n\n                  adjustmentTimeout = $timeout(function() {\n                    var currentHeight = angular.isDefined(tooltip.offsetHeight) ? tooltip.offsetHeight : tooltip.prop('offsetHeight');\n                    var adjustment = $position.adjustTop(placementClasses, elementPos, initialHeight, currentHeight);\n                    if (adjustment) {\n                      tooltip.css(adjustment);\n                    }\n                    adjustmentTimeout = null;\n                  }, 0, false);\n\n                  // first time through tt element will have the\n                  // uib-position-measure class or if the placement\n                  // has changed we need to position the arrow.\n                  if (tooltip.hasClass('uib-position-measure')) {\n                    $position.positionArrow(tooltip, ttPosition.placement);\n                    tooltip.removeClass('uib-position-measure');\n                  } else if (lastPlacement !== ttPosition.placement) {\n                    $position.positionArrow(tooltip, ttPosition.placement);\n                  }\n                  lastPlacement = ttPosition.placement;\n\n                  positionTimeout = null;\n                }, 0, false);\n              }\n            };\n\n            // Set up the correct scope to allow transclusion later\n            ttScope.origScope = scope;\n\n            // By default, the tooltip is not open.\n            // TODO add ability to start tooltip opened\n            ttScope.isOpen = false;\n\n            function toggleTooltipBind() {\n              if (!ttScope.isOpen) {\n                showTooltipBind();\n              } else {\n                hideTooltipBind();\n              }\n            }\n\n            // Show the tooltip with delay if specified, otherwise show it immediately\n            function showTooltipBind() {\n              if (hasEnableExp && !scope.$eval(attrs[prefix + 'Enable'])) {\n                return;\n              }\n\n              cancelHide();\n              prepareTooltip();\n\n              if (ttScope.popupDelay) {\n                // Do nothing if the tooltip was already scheduled to pop-up.\n                // This happens if show is triggered multiple times before any hide is triggered.\n                if (!showTimeout) {\n                  showTimeout = $timeout(show, ttScope.popupDelay, false);\n                }\n              } else {\n                show();\n              }\n            }\n\n            function hideTooltipBind() {\n              cancelShow();\n\n              if (ttScope.popupCloseDelay) {\n                if (!hideTimeout) {\n                  hideTimeout = $timeout(hide, ttScope.popupCloseDelay, false);\n                }\n              } else {\n                hide();\n              }\n            }\n\n            // Show the tooltip popup element.\n            function show() {\n              cancelShow();\n              cancelHide();\n\n              // Don't show empty tooltips.\n              if (!ttScope.content) {\n                return angular.noop;\n              }\n\n              createTooltip();\n\n              // And show the tooltip.\n              ttScope.$evalAsync(function() {\n                ttScope.isOpen = true;\n                assignIsOpen(true);\n                positionTooltip();\n              });\n            }\n\n            function cancelShow() {\n              if (showTimeout) {\n                $timeout.cancel(showTimeout);\n                showTimeout = null;\n              }\n\n              if (positionTimeout) {\n                $timeout.cancel(positionTimeout);\n                positionTimeout = null;\n              }\n            }\n\n            // Hide the tooltip popup element.\n            function hide() {\n              if (!ttScope) {\n                return;\n              }\n\n              // First things first: we don't show it anymore.\n              ttScope.$evalAsync(function() {\n                if (ttScope) {\n                  ttScope.isOpen = false;\n                  assignIsOpen(false);\n                  // And now we remove it from the DOM. However, if we have animation, we\n                  // need to wait for it to expire beforehand.\n                  // FIXME: this is a placeholder for a port of the transitions library.\n                  // The fade transition in TWBS is 150ms.\n                  if (ttScope.animation) {\n                    if (!transitionTimeout) {\n                      transitionTimeout = $timeout(removeTooltip, 150, false);\n                    }\n                  } else {\n                    removeTooltip();\n                  }\n                }\n              });\n            }\n\n            function cancelHide() {\n              if (hideTimeout) {\n                $timeout.cancel(hideTimeout);\n                hideTimeout = null;\n              }\n\n              if (transitionTimeout) {\n                $timeout.cancel(transitionTimeout);\n                transitionTimeout = null;\n              }\n            }\n\n            function createTooltip() {\n              // There can only be one tooltip element per directive shown at once.\n              if (tooltip) {\n                return;\n              }\n\n              tooltipLinkedScope = ttScope.$new();\n              tooltip = tooltipLinker(tooltipLinkedScope, function(tooltip) {\n                if (appendToBody) {\n                  $document.find('body').append(tooltip);\n                } else {\n                  element.after(tooltip);\n                }\n              });\n\n              openedTooltips.add(ttScope, {\n                close: hide\n              });\n\n              prepObservers();\n            }\n\n            function removeTooltip() {\n              cancelShow();\n              cancelHide();\n              unregisterObservers();\n\n              if (tooltip) {\n                tooltip.remove();\n                \n                tooltip = null;\n                if (adjustmentTimeout) {\n                  $timeout.cancel(adjustmentTimeout);\n                }\n              }\n\n              openedTooltips.remove(ttScope);\n              \n              if (tooltipLinkedScope) {\n                tooltipLinkedScope.$destroy();\n                tooltipLinkedScope = null;\n              }\n            }\n\n            /**\n             * Set the initial scope values. Once\n             * the tooltip is created, the observers\n             * will be added to keep things in sync.\n             */\n            function prepareTooltip() {\n              ttScope.title = attrs[prefix + 'Title'];\n              if (contentParse) {\n                ttScope.content = contentParse(scope);\n              } else {\n                ttScope.content = attrs[ttType];\n              }\n\n              ttScope.popupClass = attrs[prefix + 'Class'];\n              ttScope.placement = angular.isDefined(attrs[prefix + 'Placement']) ? attrs[prefix + 'Placement'] : options.placement;\n              var placement = $position.parsePlacement(ttScope.placement);\n              lastPlacement = placement[1] ? placement[0] + '-' + placement[1] : placement[0];\n\n              var delay = parseInt(attrs[prefix + 'PopupDelay'], 10);\n              var closeDelay = parseInt(attrs[prefix + 'PopupCloseDelay'], 10);\n              ttScope.popupDelay = !isNaN(delay) ? delay : options.popupDelay;\n              ttScope.popupCloseDelay = !isNaN(closeDelay) ? closeDelay : options.popupCloseDelay;\n            }\n\n            function assignIsOpen(isOpen) {\n              if (isOpenParse && angular.isFunction(isOpenParse.assign)) {\n                isOpenParse.assign(scope, isOpen);\n              }\n            }\n\n            ttScope.contentExp = function() {\n              return ttScope.content;\n            };\n\n            /**\n             * Observe the relevant attributes.\n             */\n            attrs.$observe('disabled', function(val) {\n              if (val) {\n                cancelShow();\n              }\n\n              if (val && ttScope.isOpen) {\n                hide();\n              }\n            });\n\n            if (isOpenParse) {\n              scope.$watch(isOpenParse, function(val) {\n                if (ttScope && !val === ttScope.isOpen) {\n                  toggleTooltipBind();\n                }\n              });\n            }\n\n            function prepObservers() {\n              observers.length = 0;\n\n              if (contentParse) {\n                observers.push(\n                  scope.$watch(contentParse, function(val) {\n                    ttScope.content = val;\n                    if (!val && ttScope.isOpen) {\n                      hide();\n                    }\n                  })\n                );\n\n                observers.push(\n                  tooltipLinkedScope.$watch(function() {\n                    if (!repositionScheduled) {\n                      repositionScheduled = true;\n                      tooltipLinkedScope.$$postDigest(function() {\n                        repositionScheduled = false;\n                        if (ttScope && ttScope.isOpen) {\n                          positionTooltip();\n                        }\n                      });\n                    }\n                  })\n                );\n              } else {\n                observers.push(\n                  attrs.$observe(ttType, function(val) {\n                    ttScope.content = val;\n                    if (!val && ttScope.isOpen) {\n                      hide();\n                    } else {\n                      positionTooltip();\n                    }\n                  })\n                );\n              }\n\n              observers.push(\n                attrs.$observe(prefix + 'Title', function(val) {\n                  ttScope.title = val;\n                  if (ttScope.isOpen) {\n                    positionTooltip();\n                  }\n                })\n              );\n\n              observers.push(\n                attrs.$observe(prefix + 'Placement', function(val) {\n                  ttScope.placement = val ? val : options.placement;\n                  if (ttScope.isOpen) {\n                    positionTooltip();\n                  }\n                })\n              );\n            }\n\n            function unregisterObservers() {\n              if (observers.length) {\n                angular.forEach(observers, function(observer) {\n                  observer();\n                });\n                observers.length = 0;\n              }\n            }\n\n            // hide tooltips/popovers for outsideClick trigger\n            function bodyHideTooltipBind(e) {\n              if (!ttScope || !ttScope.isOpen || !tooltip) {\n                return;\n              }\n              // make sure the tooltip/popover link or tool tooltip/popover itself were not clicked\n              if (!element[0].contains(e.target) && !tooltip[0].contains(e.target)) {\n                hideTooltipBind();\n              }\n            }\n\n            // KeyboardEvent handler to hide the tooltip on Escape key press\n            function hideOnEscapeKey(e) {\n              if (e.which === 27) {\n                hideTooltipBind();\n              }\n            }\n\n            var unregisterTriggers = function() {\n              triggers.show.forEach(function(trigger) {\n                if (trigger === 'outsideClick') {\n                  element.off('click', toggleTooltipBind);\n                } else {\n                  element.off(trigger, showTooltipBind);\n                  element.off(trigger, toggleTooltipBind);\n                }\n                element.off('keypress', hideOnEscapeKey);\n              });\n              triggers.hide.forEach(function(trigger) {\n                if (trigger === 'outsideClick') {\n                  $document.off('click', bodyHideTooltipBind);\n                } else {\n                  element.off(trigger, hideTooltipBind);\n                }\n              });\n            };\n\n            function prepTriggers() {\n              var showTriggers = [], hideTriggers = [];\n              var val = scope.$eval(attrs[prefix + 'Trigger']);\n              unregisterTriggers();\n\n              if (angular.isObject(val)) {\n                Object.keys(val).forEach(function(key) {\n                  showTriggers.push(key);\n                  hideTriggers.push(val[key]);\n                });\n                triggers = {\n                  show: showTriggers,\n                  hide: hideTriggers\n                };\n              } else {\n                triggers = getTriggers(val);\n              }\n\n              if (triggers.show !== 'none') {\n                triggers.show.forEach(function(trigger, idx) {\n                  if (trigger === 'outsideClick') {\n                    element.on('click', toggleTooltipBind);\n                    $document.on('click', bodyHideTooltipBind);\n                  } else if (trigger === triggers.hide[idx]) {\n                    element.on(trigger, toggleTooltipBind);\n                  } else if (trigger) {\n                    element.on(trigger, showTooltipBind);\n                    element.on(triggers.hide[idx], hideTooltipBind);\n                  }\n                  element.on('keypress', hideOnEscapeKey);\n                });\n              }\n            }\n\n            prepTriggers();\n\n            var animation = scope.$eval(attrs[prefix + 'Animation']);\n            ttScope.animation = angular.isDefined(animation) ? !!animation : options.animation;\n\n            var appendToBodyVal;\n            var appendKey = prefix + 'AppendToBody';\n            if (appendKey in attrs && attrs[appendKey] === undefined) {\n              appendToBodyVal = true;\n            } else {\n              appendToBodyVal = scope.$eval(attrs[appendKey]);\n            }\n\n            appendToBody = angular.isDefined(appendToBodyVal) ? appendToBodyVal : appendToBody;\n\n            // Make sure tooltip is destroyed and removed.\n            scope.$on('$destroy', function onDestroyTooltip() {\n              unregisterTriggers();\n              removeTooltip();\n              ttScope = null;\n            });\n          };\n        }\n      };\n    };\n  }];\n})\n\n// This is mostly ngInclude code but with a custom scope\n.directive('uibTooltipTemplateTransclude', [\n         '$animate', '$sce', '$compile', '$templateRequest',\nfunction ($animate, $sce, $compile, $templateRequest) {\n  return {\n    link: function(scope, elem, attrs) {\n      var origScope = scope.$eval(attrs.tooltipTemplateTranscludeScope);\n\n      var changeCounter = 0,\n        currentScope,\n        previousElement,\n        currentElement;\n\n      var cleanupLastIncludeContent = function() {\n        if (previousElement) {\n          previousElement.remove();\n          previousElement = null;\n        }\n\n        if (currentScope) {\n          currentScope.$destroy();\n          currentScope = null;\n        }\n\n        if (currentElement) {\n          $animate.leave(currentElement).then(function() {\n            previousElement = null;\n          });\n          previousElement = currentElement;\n          currentElement = null;\n        }\n      };\n\n      scope.$watch($sce.parseAsResourceUrl(attrs.uibTooltipTemplateTransclude), function(src) {\n        var thisChangeId = ++changeCounter;\n\n        if (src) {\n          //set the 2nd param to true to ignore the template request error so that the inner\n          //contents and scope can be cleaned up.\n          $templateRequest(src, true).then(function(response) {\n            if (thisChangeId !== changeCounter) { return; }\n            var newScope = origScope.$new();\n            var template = response;\n\n            var clone = $compile(template)(newScope, function(clone) {\n              cleanupLastIncludeContent();\n              $animate.enter(clone, elem);\n            });\n\n            currentScope = newScope;\n            currentElement = clone;\n\n            currentScope.$emit('$includeContentLoaded', src);\n          }, function() {\n            if (thisChangeId === changeCounter) {\n              cleanupLastIncludeContent();\n              scope.$emit('$includeContentError', src);\n            }\n          });\n          scope.$emit('$includeContentRequested', src);\n        } else {\n          cleanupLastIncludeContent();\n        }\n      });\n\n      scope.$on('$destroy', cleanupLastIncludeContent);\n    }\n  };\n}])\n\n/**\n * Note that it's intentional that these classes are *not* applied through $animate.\n * They must not be animated as they're expected to be present on the tooltip on\n * initialization.\n */\n.directive('uibTooltipClasses', ['$uibPosition', function($uibPosition) {\n  return {\n    restrict: 'A',\n    link: function(scope, element, attrs) {\n      // need to set the primary position so the\n      // arrow has space during position measure.\n      // tooltip.positionTooltip()\n      if (scope.placement) {\n        // // There are no top-left etc... classes\n        // // in TWBS, so we need the primary position.\n        var position = $uibPosition.parsePlacement(scope.placement);\n        element.addClass(position[0]);\n      }\n\n      if (scope.popupClass) {\n        element.addClass(scope.popupClass);\n      }\n\n      if (scope.animation) {\n        element.addClass(attrs.tooltipAnimationClass);\n      }\n    }\n  };\n}])\n\n.directive('uibTooltipPopup', function() {\n  return {\n    restrict: 'A',\n    scope: { content: '@' },\n    templateUrl: 'uib/template/tooltip/tooltip-popup.html'\n  };\n})\n\n.directive('uibTooltip', [ '$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibTooltip', 'tooltip', 'mouseenter');\n}])\n\n.directive('uibTooltipTemplatePopup', function() {\n  return {\n    restrict: 'A',\n    scope: { contentExp: '&', originScope: '&' },\n    templateUrl: 'uib/template/tooltip/tooltip-template-popup.html'\n  };\n})\n\n.directive('uibTooltipTemplate', ['$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibTooltipTemplate', 'tooltip', 'mouseenter', {\n    useContentExp: true\n  });\n}])\n\n.directive('uibTooltipHtmlPopup', function() {\n  return {\n    restrict: 'A',\n    scope: { contentExp: '&' },\n    templateUrl: 'uib/template/tooltip/tooltip-html-popup.html'\n  };\n})\n\n.directive('uibTooltipHtml', ['$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibTooltipHtml', 'tooltip', 'mouseenter', {\n    useContentExp: true\n  });\n}]);\n","src/popover/popover.js":"/**\n * The following features are still outstanding: popup delay, animation as a\n * function, placement as a function, inside, support for more triggers than\n * just mouse enter/leave, and selector delegatation.\n */\nangular.module('ui.bootstrap.popover', ['ui.bootstrap.tooltip'])\n\n.directive('uibPopoverTemplatePopup', function() {\n  return {\n    restrict: 'A',\n    scope: { uibTitle: '@', contentExp: '&', originScope: '&' },\n    templateUrl: 'uib/template/popover/popover-template.html'\n  };\n})\n\n.directive('uibPopoverTemplate', ['$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibPopoverTemplate', 'popover', 'click', {\n    useContentExp: true\n  });\n}])\n\n.directive('uibPopoverHtmlPopup', function() {\n  return {\n    restrict: 'A',\n    scope: { contentExp: '&', uibTitle: '@' },\n    templateUrl: 'uib/template/popover/popover-html.html'\n  };\n})\n\n.directive('uibPopoverHtml', ['$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibPopoverHtml', 'popover', 'click', {\n    useContentExp: true\n  });\n}])\n\n.directive('uibPopoverPopup', function() {\n  return {\n    restrict: 'A',\n    scope: { uibTitle: '@', content: '@' },\n    templateUrl: 'uib/template/popover/popover.html'\n  };\n})\n\n.directive('uibPopover', ['$uibTooltip', function($uibTooltip) {\n  return $uibTooltip('uibPopover', 'popover', 'click');\n}]);\n","src/progressbar/progressbar.js":"angular.module('ui.bootstrap.progressbar', [])\n\n.constant('uibProgressConfig', {\n  animate: true,\n  max: 100\n})\n\n.controller('UibProgressController', ['$scope', '$attrs', 'uibProgressConfig', function($scope, $attrs, progressConfig) {\n  var self = this,\n      animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;\n\n  this.bars = [];\n  $scope.max = getMaxOrDefault();\n\n  this.addBar = function(bar, element, attrs) {\n    if (!animate) {\n      element.css({'transition': 'none'});\n    }\n\n    this.bars.push(bar);\n\n    bar.max = getMaxOrDefault();\n    bar.title = attrs && angular.isDefined(attrs.title) ? attrs.title : 'progressbar';\n\n    bar.$watch('value', function(value) {\n      bar.recalculatePercentage();\n    });\n\n    bar.recalculatePercentage = function() {\n      var totalPercentage = self.bars.reduce(function(total, bar) {\n        bar.percent = +(100 * bar.value / bar.max).toFixed(2);\n        return total + bar.percent;\n      }, 0);\n\n      if (totalPercentage > 100) {\n        bar.percent -= totalPercentage - 100;\n      }\n    };\n\n    bar.$on('$destroy', function() {\n      element = null;\n      self.removeBar(bar);\n    });\n  };\n\n  this.removeBar = function(bar) {\n    this.bars.splice(this.bars.indexOf(bar), 1);\n    this.bars.forEach(function (bar) {\n      bar.recalculatePercentage();\n    });\n  };\n\n  //$attrs.$observe('maxParam', function(maxParam) {\n  $scope.$watch('maxParam', function(maxParam) {\n    self.bars.forEach(function(bar) {\n      bar.max = getMaxOrDefault();\n      bar.recalculatePercentage();\n    });\n  });\n\n  function getMaxOrDefault () {\n    return angular.isDefined($scope.maxParam) ? $scope.maxParam : progressConfig.max;\n  }\n}])\n\n.directive('uibProgress', function() {\n  return {\n    replace: true,\n    transclude: true,\n    controller: 'UibProgressController',\n    require: 'uibProgress',\n    scope: {\n      maxParam: '=?max'\n    },\n    templateUrl: 'uib/template/progressbar/progress.html'\n  };\n})\n\n.directive('uibBar', function() {\n  return {\n    replace: true,\n    transclude: true,\n    require: '^uibProgress',\n    scope: {\n      value: '=',\n      type: '@'\n    },\n    templateUrl: 'uib/template/progressbar/bar.html',\n    link: function(scope, element, attrs, progressCtrl) {\n      progressCtrl.addBar(scope, element, attrs);\n    }\n  };\n})\n\n.directive('uibProgressbar', function() {\n  return {\n    replace: true,\n    transclude: true,\n    controller: 'UibProgressController',\n    scope: {\n      value: '=',\n      maxParam: '=?max',\n      type: '@'\n    },\n    templateUrl: 'uib/template/progressbar/progressbar.html',\n    link: function(scope, element, attrs, progressCtrl) {\n      progressCtrl.addBar(scope, angular.element(element.children()[0]), {title: attrs.title});\n    }\n  };\n});\n","src/rating/rating.js":"angular.module('ui.bootstrap.rating', [])\n\n.constant('uibRatingConfig', {\n  max: 5,\n  stateOn: null,\n  stateOff: null,\n  enableReset: true,\n  titles: ['one', 'two', 'three', 'four', 'five']\n})\n\n.controller('UibRatingController', ['$scope', '$attrs', 'uibRatingConfig', function($scope, $attrs, ratingConfig) {\n  var ngModelCtrl = { $setViewValue: angular.noop },\n    self = this;\n\n  this.init = function(ngModelCtrl_) {\n    ngModelCtrl = ngModelCtrl_;\n    ngModelCtrl.$render = this.render;\n\n    ngModelCtrl.$formatters.push(function(value) {\n      if (angular.isNumber(value) && value << 0 !== value) {\n        value = Math.round(value);\n      }\n\n      return value;\n    });\n\n    this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;\n    this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;\n    this.enableReset = angular.isDefined($attrs.enableReset) ?\n      $scope.$parent.$eval($attrs.enableReset) : ratingConfig.enableReset;\n    var tmpTitles = angular.isDefined($attrs.titles) ? $scope.$parent.$eval($attrs.titles) : ratingConfig.titles;\n    this.titles = angular.isArray(tmpTitles) && tmpTitles.length > 0 ?\n      tmpTitles : ratingConfig.titles;\n\n    var ratingStates = angular.isDefined($attrs.ratingStates) ?\n      $scope.$parent.$eval($attrs.ratingStates) :\n      new Array(angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max);\n    $scope.range = this.buildTemplateObjects(ratingStates);\n  };\n\n  this.buildTemplateObjects = function(states) {\n    for (var i = 0, n = states.length; i < n; i++) {\n      states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff, title: this.getTitle(i) }, states[i]);\n    }\n    return states;\n  };\n\n  this.getTitle = function(index) {\n    if (index >= this.titles.length) {\n      return index + 1;\n    }\n\n    return this.titles[index];\n  };\n\n  $scope.rate = function(value) {\n    if (!$scope.readonly && value >= 0 && value <= $scope.range.length) {\n      var newViewValue = self.enableReset && ngModelCtrl.$viewValue === value ? 0 : value;\n      ngModelCtrl.$setViewValue(newViewValue);\n      ngModelCtrl.$render();\n    }\n  };\n\n  $scope.enter = function(value) {\n    if (!$scope.readonly) {\n      $scope.value = value;\n    }\n    $scope.onHover({value: value});\n  };\n\n  $scope.reset = function() {\n    $scope.value = ngModelCtrl.$viewValue;\n    $scope.onLeave();\n  };\n\n  $scope.onKeydown = function(evt) {\n    if (/(37|38|39|40)/.test(evt.which)) {\n      evt.preventDefault();\n      evt.stopPropagation();\n      $scope.rate($scope.value + (evt.which === 38 || evt.which === 39 ? 1 : -1));\n    }\n  };\n\n  this.render = function() {\n    $scope.value = ngModelCtrl.$viewValue;\n    $scope.title = self.getTitle($scope.value - 1);\n  };\n}])\n\n.directive('uibRating', function() {\n  return {\n    require: ['uibRating', 'ngModel'],\n    restrict: 'A',\n    scope: {\n      readonly: '=?readOnly',\n      onHover: '&',\n      onLeave: '&'\n    },\n    controller: 'UibRatingController',\n    templateUrl: 'uib/template/rating/rating.html',\n    link: function(scope, element, attrs, ctrls) {\n      var ratingCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n      ratingCtrl.init(ngModelCtrl);\n    }\n  };\n});\n","src/tabs/tabs.js":"angular.module('ui.bootstrap.tabs', [])\n\n.controller('UibTabsetController', ['$scope', function ($scope) {\n  var ctrl = this,\n    oldIndex;\n  ctrl.tabs = [];\n\n  ctrl.select = function(index, evt) {\n    if (!destroyed) {\n      var previousIndex = findTabIndex(oldIndex);\n      var previousSelected = ctrl.tabs[previousIndex];\n      if (previousSelected) {\n        previousSelected.tab.onDeselect({\n          $event: evt,\n          $selectedIndex: index\n        });\n        if (evt && evt.isDefaultPrevented()) {\n          return;\n        }\n        previousSelected.tab.active = false;\n      }\n\n      var selected = ctrl.tabs[index];\n      if (selected) {\n        selected.tab.onSelect({\n          $event: evt\n        });\n        selected.tab.active = true;\n        ctrl.active = selected.index;\n        oldIndex = selected.index;\n      } else if (!selected && angular.isDefined(oldIndex)) {\n        ctrl.active = null;\n        oldIndex = null;\n      }\n    }\n  };\n\n  ctrl.addTab = function addTab(tab) {\n    ctrl.tabs.push({\n      tab: tab,\n      index: tab.index\n    });\n    ctrl.tabs.sort(function(t1, t2) {\n      if (t1.index > t2.index) {\n        return 1;\n      }\n\n      if (t1.index < t2.index) {\n        return -1;\n      }\n\n      return 0;\n    });\n\n    if (tab.index === ctrl.active || !angular.isDefined(ctrl.active) && ctrl.tabs.length === 1) {\n      var newActiveIndex = findTabIndex(tab.index);\n      ctrl.select(newActiveIndex);\n    }\n  };\n\n  ctrl.removeTab = function removeTab(tab) {\n    var index;\n    for (var i = 0; i < ctrl.tabs.length; i++) {\n      if (ctrl.tabs[i].tab === tab) {\n        index = i;\n        break;\n      }\n    }\n\n    if (ctrl.tabs[index].index === ctrl.active) {\n      var newActiveTabIndex = index === ctrl.tabs.length - 1 ?\n        index - 1 : index + 1 % ctrl.tabs.length;\n      ctrl.select(newActiveTabIndex);\n    }\n\n    ctrl.tabs.splice(index, 1);\n  };\n\n  $scope.$watch('tabset.active', function(val) {\n    if (angular.isDefined(val) && val !== oldIndex) {\n      ctrl.select(findTabIndex(val));\n    }\n  });\n\n  var destroyed;\n  $scope.$on('$destroy', function() {\n    destroyed = true;\n  });\n\n  function findTabIndex(index) {\n    for (var i = 0; i < ctrl.tabs.length; i++) {\n      if (ctrl.tabs[i].index === index) {\n        return i;\n      }\n    }\n  }\n}])\n\n.directive('uibTabset', function() {\n  return {\n    transclude: true,\n    replace: true,\n    scope: {},\n    bindToController: {\n      active: '=?',\n      type: '@'\n    },\n    controller: 'UibTabsetController',\n    controllerAs: 'tabset',\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/tabs/tabset.html';\n    },\n    link: function(scope, element, attrs) {\n      scope.vertical = angular.isDefined(attrs.vertical) ?\n        scope.$parent.$eval(attrs.vertical) : false;\n      scope.justified = angular.isDefined(attrs.justified) ?\n        scope.$parent.$eval(attrs.justified) : false;\n    }\n  };\n})\n\n.directive('uibTab', ['$parse', function($parse) {\n  return {\n    require: '^uibTabset',\n    replace: true,\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || 'uib/template/tabs/tab.html';\n    },\n    transclude: true,\n    scope: {\n      heading: '@',\n      index: '=?',\n      classes: '@?',\n      onSelect: '&select', //This callback is called in contentHeadingTransclude\n                          //once it inserts the tab's content into the dom\n      onDeselect: '&deselect'\n    },\n    controller: function() {\n      //Empty controller so other directives can require being 'under' a tab\n    },\n    controllerAs: 'tab',\n    link: function(scope, elm, attrs, tabsetCtrl, transclude) {\n      scope.disabled = false;\n      if (attrs.disable) {\n        scope.$parent.$watch($parse(attrs.disable), function(value) {\n          scope.disabled = !! value;\n        });\n      }\n\n      if (angular.isUndefined(attrs.index)) {\n        if (tabsetCtrl.tabs && tabsetCtrl.tabs.length) {\n          scope.index = Math.max.apply(null, tabsetCtrl.tabs.map(function(t) { return t.index; })) + 1;\n        } else {\n          scope.index = 0;\n        }\n      }\n\n      if (angular.isUndefined(attrs.classes)) {\n        scope.classes = '';\n      }\n\n      scope.select = function(evt) {\n        if (!scope.disabled) {\n          var index;\n          for (var i = 0; i < tabsetCtrl.tabs.length; i++) {\n            if (tabsetCtrl.tabs[i].tab === scope) {\n              index = i;\n              break;\n            }\n          }\n\n          tabsetCtrl.select(index, evt);\n        }\n      };\n\n      tabsetCtrl.addTab(scope);\n      scope.$on('$destroy', function() {\n        tabsetCtrl.removeTab(scope);\n      });\n\n      //We need to transclude later, once the content container is ready.\n      //when this link happens, we're inside a tab heading.\n      scope.$transcludeFn = transclude;\n    }\n  };\n}])\n\n.directive('uibTabHeadingTransclude', function() {\n  return {\n    restrict: 'A',\n    require: '^uibTab',\n    link: function(scope, elm) {\n      scope.$watch('headingElement', function updateHeadingElement(heading) {\n        if (heading) {\n          elm.html('');\n          elm.append(heading);\n        }\n      });\n    }\n  };\n})\n\n.directive('uibTabContentTransclude', function() {\n  return {\n    restrict: 'A',\n    require: '^uibTabset',\n    link: function(scope, elm, attrs) {\n      var tab = scope.$eval(attrs.uibTabContentTransclude).tab;\n\n      //Now our tab is ready to be transcluded: both the tab heading area\n      //and the tab content area are loaded.  Transclude 'em both.\n      tab.$transcludeFn(tab.$parent, function(contents) {\n        angular.forEach(contents, function(node) {\n          if (isTabHeading(node)) {\n            //Let tabHeadingTransclude know.\n            tab.headingElement = node;\n          } else {\n            elm.append(node);\n          }\n        });\n      });\n    }\n  };\n\n  function isTabHeading(node) {\n    return node.tagName && (\n      node.hasAttribute('uib-tab-heading') ||\n      node.hasAttribute('data-uib-tab-heading') ||\n      node.hasAttribute('x-uib-tab-heading') ||\n      node.tagName.toLowerCase() === 'uib-tab-heading' ||\n      node.tagName.toLowerCase() === 'data-uib-tab-heading' ||\n      node.tagName.toLowerCase() === 'x-uib-tab-heading' ||\n      node.tagName.toLowerCase() === 'uib:tab-heading'\n    );\n  }\n});\n","src/timepicker/timepicker.js":"angular.module('ui.bootstrap.timepicker', [])\n\n.constant('uibTimepickerConfig', {\n  hourStep: 1,\n  minuteStep: 1,\n  secondStep: 1,\n  showMeridian: true,\n  showSeconds: false,\n  meridians: null,\n  readonlyInput: false,\n  mousewheel: true,\n  arrowkeys: true,\n  showSpinners: true,\n  templateUrl: 'uib/template/timepicker/timepicker.html'\n})\n\n.controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) {\n  var hoursModelCtrl, minutesModelCtrl, secondsModelCtrl;\n  var selected = new Date(),\n    watchers = [],\n    ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl\n    meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS,\n    padHours = angular.isDefined($attrs.padHours) ? $scope.$parent.$eval($attrs.padHours) : true;\n\n  $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0;\n  $element.removeAttr('tabindex');\n\n  this.init = function(ngModelCtrl_, inputs) {\n    ngModelCtrl = ngModelCtrl_;\n    ngModelCtrl.$render = this.render;\n\n    ngModelCtrl.$formatters.unshift(function(modelValue) {\n      return modelValue ? new Date(modelValue) : null;\n    });\n\n    var hoursInputEl = inputs.eq(0),\n        minutesInputEl = inputs.eq(1),\n        secondsInputEl = inputs.eq(2);\n\n    hoursModelCtrl = hoursInputEl.controller('ngModel');\n    minutesModelCtrl = minutesInputEl.controller('ngModel');\n    secondsModelCtrl = secondsInputEl.controller('ngModel');\n\n    var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel;\n\n    if (mousewheel) {\n      this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl);\n    }\n\n    var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;\n    if (arrowkeys) {\n      this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl);\n    }\n\n    $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;\n    this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl);\n  };\n\n  var hourStep = timepickerConfig.hourStep;\n  if ($attrs.hourStep) {\n    watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) {\n      hourStep = +value;\n    }));\n  }\n\n  var minuteStep = timepickerConfig.minuteStep;\n  if ($attrs.minuteStep) {\n    watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) {\n      minuteStep = +value;\n    }));\n  }\n\n  var min;\n  watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) {\n    var dt = new Date(value);\n    min = isNaN(dt) ? undefined : dt;\n  }));\n\n  var max;\n  watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) {\n    var dt = new Date(value);\n    max = isNaN(dt) ? undefined : dt;\n  }));\n\n  var disabled = false;\n  if ($attrs.ngDisabled) {\n    watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) {\n      disabled = value;\n    }));\n  }\n\n  $scope.noIncrementHours = function() {\n    var incrementedSelected = addMinutes(selected, hourStep * 60);\n    return disabled || incrementedSelected > max ||\n      incrementedSelected < selected && incrementedSelected < min;\n  };\n\n  $scope.noDecrementHours = function() {\n    var decrementedSelected = addMinutes(selected, -hourStep * 60);\n    return disabled || decrementedSelected < min ||\n      decrementedSelected > selected && decrementedSelected > max;\n  };\n\n  $scope.noIncrementMinutes = function() {\n    var incrementedSelected = addMinutes(selected, minuteStep);\n    return disabled || incrementedSelected > max ||\n      incrementedSelected < selected && incrementedSelected < min;\n  };\n\n  $scope.noDecrementMinutes = function() {\n    var decrementedSelected = addMinutes(selected, -minuteStep);\n    return disabled || decrementedSelected < min ||\n      decrementedSelected > selected && decrementedSelected > max;\n  };\n\n  $scope.noIncrementSeconds = function() {\n    var incrementedSelected = addSeconds(selected, secondStep);\n    return disabled || incrementedSelected > max ||\n      incrementedSelected < selected && incrementedSelected < min;\n  };\n\n  $scope.noDecrementSeconds = function() {\n    var decrementedSelected = addSeconds(selected, -secondStep);\n    return disabled || decrementedSelected < min ||\n      decrementedSelected > selected && decrementedSelected > max;\n  };\n\n  $scope.noToggleMeridian = function() {\n    if (selected.getHours() < 12) {\n      return disabled || addMinutes(selected, 12 * 60) > max;\n    }\n\n    return disabled || addMinutes(selected, -12 * 60) < min;\n  };\n\n  var secondStep = timepickerConfig.secondStep;\n  if ($attrs.secondStep) {\n    watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) {\n      secondStep = +value;\n    }));\n  }\n\n  $scope.showSeconds = timepickerConfig.showSeconds;\n  if ($attrs.showSeconds) {\n    watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) {\n      $scope.showSeconds = !!value;\n    }));\n  }\n\n  // 12H / 24H mode\n  $scope.showMeridian = timepickerConfig.showMeridian;\n  if ($attrs.showMeridian) {\n    watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) {\n      $scope.showMeridian = !!value;\n\n      if (ngModelCtrl.$error.time) {\n        // Evaluate from template\n        var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();\n        if (angular.isDefined(hours) && angular.isDefined(minutes)) {\n          selected.setHours(hours);\n          refresh();\n        }\n      } else {\n        updateTemplate();\n      }\n    }));\n  }\n\n  // Get $scope.hours in 24H mode if valid\n  function getHoursFromTemplate() {\n    var hours = +$scope.hours;\n    var valid = $scope.showMeridian ? hours > 0 && hours < 13 :\n      hours >= 0 && hours < 24;\n    if (!valid || $scope.hours === '') {\n      return undefined;\n    }\n\n    if ($scope.showMeridian) {\n      if (hours === 12) {\n        hours = 0;\n      }\n      if ($scope.meridian === meridians[1]) {\n        hours = hours + 12;\n      }\n    }\n    return hours;\n  }\n\n  function getMinutesFromTemplate() {\n    var minutes = +$scope.minutes;\n    var valid = minutes >= 0 && minutes < 60;\n    if (!valid || $scope.minutes === '') {\n      return undefined;\n    }\n    return minutes;\n  }\n\n  function getSecondsFromTemplate() {\n    var seconds = +$scope.seconds;\n    return seconds >= 0 && seconds < 60 ? seconds : undefined;\n  }\n\n  function pad(value, noPad) {\n    if (value === null) {\n      return '';\n    }\n\n    return angular.isDefined(value) && value.toString().length < 2 && !noPad ?\n      '0' + value : value.toString();\n  }\n\n  // Respond on mousewheel spin\n  this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {\n    var isScrollingUp = function(e) {\n      if (e.originalEvent) {\n        e = e.originalEvent;\n      }\n      //pick correct delta variable depending on event\n      var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY;\n      return e.detail || delta > 0;\n    };\n\n    hoursInputEl.on('mousewheel wheel', function(e) {\n      if (!disabled) {\n        $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours());\n      }\n      e.preventDefault();\n    });\n\n    minutesInputEl.on('mousewheel wheel', function(e) {\n      if (!disabled) {\n        $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes());\n      }\n      e.preventDefault();\n    });\n\n     secondsInputEl.on('mousewheel wheel', function(e) {\n      if (!disabled) {\n        $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds());\n      }\n      e.preventDefault();\n    });\n  };\n\n  // Respond on up/down arrowkeys\n  this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {\n    hoursInputEl.on('keydown', function(e) {\n      if (!disabled) {\n        if (e.which === 38) { // up\n          e.preventDefault();\n          $scope.incrementHours();\n          $scope.$apply();\n        } else if (e.which === 40) { // down\n          e.preventDefault();\n          $scope.decrementHours();\n          $scope.$apply();\n        }\n      }\n    });\n\n    minutesInputEl.on('keydown', function(e) {\n      if (!disabled) {\n        if (e.which === 38) { // up\n          e.preventDefault();\n          $scope.incrementMinutes();\n          $scope.$apply();\n        } else if (e.which === 40) { // down\n          e.preventDefault();\n          $scope.decrementMinutes();\n          $scope.$apply();\n        }\n      }\n    });\n\n    secondsInputEl.on('keydown', function(e) {\n      if (!disabled) {\n        if (e.which === 38) { // up\n          e.preventDefault();\n          $scope.incrementSeconds();\n          $scope.$apply();\n        } else if (e.which === 40) { // down\n          e.preventDefault();\n          $scope.decrementSeconds();\n          $scope.$apply();\n        }\n      }\n    });\n  };\n\n  this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {\n    if ($scope.readonlyInput) {\n      $scope.updateHours = angular.noop;\n      $scope.updateMinutes = angular.noop;\n      $scope.updateSeconds = angular.noop;\n      return;\n    }\n\n    var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) {\n      ngModelCtrl.$setViewValue(null);\n      ngModelCtrl.$setValidity('time', false);\n      if (angular.isDefined(invalidHours)) {\n        $scope.invalidHours = invalidHours;\n        if (hoursModelCtrl) {\n          hoursModelCtrl.$setValidity('hours', false);\n        }\n      }\n\n      if (angular.isDefined(invalidMinutes)) {\n        $scope.invalidMinutes = invalidMinutes;\n        if (minutesModelCtrl) {\n          minutesModelCtrl.$setValidity('minutes', false);\n        }\n      }\n\n      if (angular.isDefined(invalidSeconds)) {\n        $scope.invalidSeconds = invalidSeconds;\n        if (secondsModelCtrl) {\n          secondsModelCtrl.$setValidity('seconds', false);\n        }\n      }\n    };\n\n    $scope.updateHours = function() {\n      var hours = getHoursFromTemplate(),\n        minutes = getMinutesFromTemplate();\n\n      ngModelCtrl.$setDirty();\n\n      if (angular.isDefined(hours) && angular.isDefined(minutes)) {\n        selected.setHours(hours);\n        selected.setMinutes(minutes);\n        if (selected < min || selected > max) {\n          invalidate(true);\n        } else {\n          refresh('h');\n        }\n      } else {\n        invalidate(true);\n      }\n    };\n\n    hoursInputEl.on('blur', function(e) {\n      ngModelCtrl.$setTouched();\n      if (modelIsEmpty()) {\n        makeValid();\n      } else if ($scope.hours === null || $scope.hours === '') {\n        invalidate(true);\n      } else if (!$scope.invalidHours && $scope.hours < 10) {\n        $scope.$apply(function() {\n          $scope.hours = pad($scope.hours, !padHours);\n        });\n      }\n    });\n\n    $scope.updateMinutes = function() {\n      var minutes = getMinutesFromTemplate(),\n        hours = getHoursFromTemplate();\n\n      ngModelCtrl.$setDirty();\n\n      if (angular.isDefined(minutes) && angular.isDefined(hours)) {\n        selected.setHours(hours);\n        selected.setMinutes(minutes);\n        if (selected < min || selected > max) {\n          invalidate(undefined, true);\n        } else {\n          refresh('m');\n        }\n      } else {\n        invalidate(undefined, true);\n      }\n    };\n\n    minutesInputEl.on('blur', function(e) {\n      ngModelCtrl.$setTouched();\n      if (modelIsEmpty()) {\n        makeValid();\n      } else if ($scope.minutes === null) {\n        invalidate(undefined, true);\n      } else if (!$scope.invalidMinutes && $scope.minutes < 10) {\n        $scope.$apply(function() {\n          $scope.minutes = pad($scope.minutes);\n        });\n      }\n    });\n\n    $scope.updateSeconds = function() {\n      var seconds = getSecondsFromTemplate();\n\n      ngModelCtrl.$setDirty();\n\n      if (angular.isDefined(seconds)) {\n        selected.setSeconds(seconds);\n        refresh('s');\n      } else {\n        invalidate(undefined, undefined, true);\n      }\n    };\n\n    secondsInputEl.on('blur', function(e) {\n      if (modelIsEmpty()) {\n        makeValid();\n      } else if (!$scope.invalidSeconds && $scope.seconds < 10) {\n        $scope.$apply( function() {\n          $scope.seconds = pad($scope.seconds);\n        });\n      }\n    });\n\n  };\n\n  this.render = function() {\n    var date = ngModelCtrl.$viewValue;\n\n    if (isNaN(date)) {\n      ngModelCtrl.$setValidity('time', false);\n      $log.error('Timepicker directive: \"ng-model\" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');\n    } else {\n      if (date) {\n        selected = date;\n      }\n\n      if (selected < min || selected > max) {\n        ngModelCtrl.$setValidity('time', false);\n        $scope.invalidHours = true;\n        $scope.invalidMinutes = true;\n      } else {\n        makeValid();\n      }\n      updateTemplate();\n    }\n  };\n\n  // Call internally when we know that model is valid.\n  function refresh(keyboardChange) {\n    makeValid();\n    ngModelCtrl.$setViewValue(new Date(selected));\n    updateTemplate(keyboardChange);\n  }\n\n  function makeValid() {\n    if (hoursModelCtrl) {\n      hoursModelCtrl.$setValidity('hours', true);\n    }\n\n    if (minutesModelCtrl) {\n      minutesModelCtrl.$setValidity('minutes', true);\n    }\n\n    if (secondsModelCtrl) {\n      secondsModelCtrl.$setValidity('seconds', true);\n    }\n\n    ngModelCtrl.$setValidity('time', true);\n    $scope.invalidHours = false;\n    $scope.invalidMinutes = false;\n    $scope.invalidSeconds = false;\n  }\n\n  function updateTemplate(keyboardChange) {\n    if (!ngModelCtrl.$modelValue) {\n      $scope.hours = null;\n      $scope.minutes = null;\n      $scope.seconds = null;\n      $scope.meridian = meridians[0];\n    } else {\n      var hours = selected.getHours(),\n        minutes = selected.getMinutes(),\n        seconds = selected.getSeconds();\n\n      if ($scope.showMeridian) {\n        hours = hours === 0 || hours === 12 ? 12 : hours % 12; // Convert 24 to 12 hour system\n      }\n\n      $scope.hours = keyboardChange === 'h' ? hours : pad(hours, !padHours);\n      if (keyboardChange !== 'm') {\n        $scope.minutes = pad(minutes);\n      }\n      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];\n\n      if (keyboardChange !== 's') {\n        $scope.seconds = pad(seconds);\n      }\n      $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];\n    }\n  }\n\n  function addSecondsToSelected(seconds) {\n    selected = addSeconds(selected, seconds);\n    refresh();\n  }\n\n  function addMinutes(selected, minutes) {\n    return addSeconds(selected, minutes*60);\n  }\n\n  function addSeconds(date, seconds) {\n    var dt = new Date(date.getTime() + seconds * 1000);\n    var newDate = new Date(date);\n    newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds());\n    return newDate;\n  }\n\n  function modelIsEmpty() {\n    return ($scope.hours === null || $scope.hours === '') &&\n      ($scope.minutes === null || $scope.minutes === '') &&\n      (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === ''));\n  }\n\n  $scope.showSpinners = angular.isDefined($attrs.showSpinners) ?\n    $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;\n\n  $scope.incrementHours = function() {\n    if (!$scope.noIncrementHours()) {\n      addSecondsToSelected(hourStep * 60 * 60);\n    }\n  };\n\n  $scope.decrementHours = function() {\n    if (!$scope.noDecrementHours()) {\n      addSecondsToSelected(-hourStep * 60 * 60);\n    }\n  };\n\n  $scope.incrementMinutes = function() {\n    if (!$scope.noIncrementMinutes()) {\n      addSecondsToSelected(minuteStep * 60);\n    }\n  };\n\n  $scope.decrementMinutes = function() {\n    if (!$scope.noDecrementMinutes()) {\n      addSecondsToSelected(-minuteStep * 60);\n    }\n  };\n\n  $scope.incrementSeconds = function() {\n    if (!$scope.noIncrementSeconds()) {\n      addSecondsToSelected(secondStep);\n    }\n  };\n\n  $scope.decrementSeconds = function() {\n    if (!$scope.noDecrementSeconds()) {\n      addSecondsToSelected(-secondStep);\n    }\n  };\n\n  $scope.toggleMeridian = function() {\n    var minutes = getMinutesFromTemplate(),\n        hours = getHoursFromTemplate();\n\n    if (!$scope.noToggleMeridian()) {\n      if (angular.isDefined(minutes) && angular.isDefined(hours)) {\n        addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60));\n      } else {\n        $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0];\n      }\n    }\n  };\n\n  $scope.blur = function() {\n    ngModelCtrl.$setTouched();\n  };\n\n  $scope.$on('$destroy', function() {\n    while (watchers.length) {\n      watchers.shift()();\n    }\n  });\n}])\n\n.directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) {\n  return {\n    require: ['uibTimepicker', '?^ngModel'],\n    restrict: 'A',\n    controller: 'UibTimepickerController',\n    controllerAs: 'timepicker',\n    scope: {},\n    templateUrl: function(element, attrs) {\n      return attrs.templateUrl || uibTimepickerConfig.templateUrl;\n    },\n    link: function(scope, element, attrs, ctrls) {\n      var timepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];\n\n      if (ngModelCtrl) {\n        timepickerCtrl.init(ngModelCtrl, element.find('input'));\n      }\n    }\n  };\n}]);\n","src/typeahead/typeahead.js":"angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap.position'])\n\n/**\n * A helper service that can parse typeahead's syntax (string provided by users)\n * Extracted to a separate service for ease of unit testing\n */\n  .factory('uibTypeaheadParser', ['$parse', function($parse) {\n    //                      000001111111100000000000002222222200000000000000003333333333333330000000000044444444000\n    var TYPEAHEAD_REGEXP = /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?\\s+for\\s+(?:([\\$\\w][\\$\\w\\d]*))\\s+in\\s+([\\s\\S]+?)$/;\n    return {\n      parse: function(input) {\n        var match = input.match(TYPEAHEAD_REGEXP);\n        if (!match) {\n          throw new Error(\n            'Expected typeahead specification in form of \"_modelValue_ (as _label_)? for _item_ in _collection_\"' +\n              ' but got \"' + input + '\".');\n        }\n\n        return {\n          itemName: match[3],\n          source: $parse(match[4]),\n          viewMapper: $parse(match[2] || match[1]),\n          modelMapper: $parse(match[1])\n        };\n      }\n    };\n  }])\n\n  .controller('UibTypeaheadController', ['$scope', '$element', '$attrs', '$compile', '$parse', '$q', '$timeout', '$document', '$window', '$rootScope', '$$debounce', '$uibPosition', 'uibTypeaheadParser',\n    function(originalScope, element, attrs, $compile, $parse, $q, $timeout, $document, $window, $rootScope, $$debounce, $position, typeaheadParser) {\n    var HOT_KEYS = [9, 13, 27, 38, 40];\n    var eventDebounceTime = 200;\n    var modelCtrl, ngModelOptions;\n    //SUPPORTED ATTRIBUTES (OPTIONS)\n\n    //minimal no of characters that needs to be entered before typeahead kicks-in\n    var minLength = originalScope.$eval(attrs.typeaheadMinLength);\n    if (!minLength && minLength !== 0) {\n      minLength = 1;\n    }\n\n    originalScope.$watch(attrs.typeaheadMinLength, function (newVal) {\n        minLength = !newVal && newVal !== 0 ? 1 : newVal;\n    });\n\n    //minimal wait time after last character typed before typeahead kicks-in\n    var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;\n\n    //should it restrict model values to the ones selected from the popup only?\n    var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;\n    originalScope.$watch(attrs.typeaheadEditable, function (newVal) {\n      isEditable = newVal !== false;\n    });\n\n    //binding to a variable that indicates if matches are being retrieved asynchronously\n    var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;\n\n    //a function to determine if an event should cause selection\n    var isSelectEvent = attrs.typeaheadShouldSelect ? $parse(attrs.typeaheadShouldSelect) : function(scope, vals) {\n      var evt = vals.$event;\n      return evt.which === 13 || evt.which === 9;\n    };\n\n    //a callback executed when a match is selected\n    var onSelectCallback = $parse(attrs.typeaheadOnSelect);\n\n    //should it select highlighted popup value when losing focus?\n    var isSelectOnBlur = angular.isDefined(attrs.typeaheadSelectOnBlur) ? originalScope.$eval(attrs.typeaheadSelectOnBlur) : false;\n\n    //binding to a variable that indicates if there were no results after the query is completed\n    var isNoResultsSetter = $parse(attrs.typeaheadNoResults).assign || angular.noop;\n\n    var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;\n\n    var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false;\n\n    var appendTo = attrs.typeaheadAppendTo ?\n      originalScope.$eval(attrs.typeaheadAppendTo) : null;\n\n    var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false;\n\n    //If input matches an item of the list exactly, select it automatically\n    var selectOnExact = attrs.typeaheadSelectOnExact ? originalScope.$eval(attrs.typeaheadSelectOnExact) : false;\n\n    //binding to a variable that indicates if dropdown is open\n    var isOpenSetter = $parse(attrs.typeaheadIsOpen).assign || angular.noop;\n\n    var showHint = originalScope.$eval(attrs.typeaheadShowHint) || false;\n\n    //INTERNAL VARIABLES\n\n    //model setter executed upon match selection\n    var parsedModel = $parse(attrs.ngModel);\n    var invokeModelSetter = $parse(attrs.ngModel + '($$$p)');\n    var $setModelValue = function(scope, newValue) {\n      if (angular.isFunction(parsedModel(originalScope)) &&\n        ngModelOptions.getOption('getterSetter')) {\n        return invokeModelSetter(scope, {$$$p: newValue});\n      }\n\n      return parsedModel.assign(scope, newValue);\n    };\n\n    //expressions used by typeahead\n    var parserResult = typeaheadParser.parse(attrs.uibTypeahead);\n\n    var hasFocus;\n\n    //Used to avoid bug in iOS webview where iOS keyboard does not fire\n    //mousedown & mouseup events\n    //Issue #3699\n    var selected;\n\n    //create a child scope for the typeahead directive so we are not polluting original scope\n    //with typeahead-specific data (matches, query etc.)\n    var scope = originalScope.$new();\n    var offDestroy = originalScope.$on('$destroy', function() {\n      scope.$destroy();\n    });\n    scope.$on('$destroy', offDestroy);\n\n    // WAI-ARIA\n    var popupId = 'typeahead-' + scope.$id + '-' + Math.floor(Math.random() * 10000);\n    element.attr({\n      'aria-autocomplete': 'list',\n      'aria-expanded': false,\n      'aria-owns': popupId\n    });\n\n    var inputsContainer, hintInputElem;\n    //add read-only input to show hint\n    if (showHint) {\n      inputsContainer = angular.element('<div></div>');\n      inputsContainer.css('position', 'relative');\n      element.after(inputsContainer);\n      hintInputElem = element.clone();\n      hintInputElem.attr('placeholder', '');\n      hintInputElem.attr('tabindex', '-1');\n      hintInputElem.val('');\n      hintInputElem.css({\n        'position': 'absolute',\n        'top': '0px',\n        'left': '0px',\n        'border-color': 'transparent',\n        'box-shadow': 'none',\n        'opacity': 1,\n        'background': 'none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255)',\n        'color': '#999'\n      });\n      element.css({\n        'position': 'relative',\n        'vertical-align': 'top',\n        'background-color': 'transparent'\n      });\n\n      if (hintInputElem.attr('id')) {\n        hintInputElem.removeAttr('id'); // remove duplicate id if present.\n      }\n      inputsContainer.append(hintInputElem);\n      hintInputElem.after(element);\n    }\n\n    //pop-up element used to display matches\n    var popUpEl = angular.element('<div uib-typeahead-popup></div>');\n    popUpEl.attr({\n      id: popupId,\n      matches: 'matches',\n      active: 'activeIdx',\n      select: 'select(activeIdx, evt)',\n      'move-in-progress': 'moveInProgress',\n      query: 'query',\n      position: 'position',\n      'assign-is-open': 'assignIsOpen(isOpen)',\n      debounce: 'debounceUpdate'\n    });\n    //custom item template\n    if (angular.isDefined(attrs.typeaheadTemplateUrl)) {\n      popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);\n    }\n\n    if (angular.isDefined(attrs.typeaheadPopupTemplateUrl)) {\n      popUpEl.attr('popup-template-url', attrs.typeaheadPopupTemplateUrl);\n    }\n\n    var resetHint = function() {\n      if (showHint) {\n        hintInputElem.val('');\n      }\n    };\n\n    var resetMatches = function() {\n      scope.matches = [];\n      scope.activeIdx = -1;\n      element.attr('aria-expanded', false);\n      resetHint();\n    };\n\n    var getMatchId = function(index) {\n      return popupId + '-option-' + index;\n    };\n\n    // Indicate that the specified match is the active (pre-selected) item in the list owned by this typeahead.\n    // This attribute is added or removed automatically when the `activeIdx` changes.\n    scope.$watch('activeIdx', function(index) {\n      if (index < 0) {\n        element.removeAttr('aria-activedescendant');\n      } else {\n        element.attr('aria-activedescendant', getMatchId(index));\n      }\n    });\n\n    var inputIsExactMatch = function(inputValue, index) {\n      if (scope.matches.length > index && inputValue) {\n        return inputValue.toUpperCase() === scope.matches[index].label.toUpperCase();\n      }\n\n      return false;\n    };\n\n    var getMatchesAsync = function(inputValue, evt) {\n      var locals = {$viewValue: inputValue};\n      isLoadingSetter(originalScope, true);\n      isNoResultsSetter(originalScope, false);\n      $q.when(parserResult.source(originalScope, locals)).then(function(matches) {\n        //it might happen that several async queries were in progress if a user were typing fast\n        //but we are interested only in responses that correspond to the current view value\n        var onCurrentRequest = inputValue === modelCtrl.$viewValue;\n        if (onCurrentRequest && hasFocus) {\n          if (matches && matches.length > 0) {\n            scope.activeIdx = focusFirst ? 0 : -1;\n            isNoResultsSetter(originalScope, false);\n            scope.matches.length = 0;\n\n            //transform labels\n            for (var i = 0; i < matches.length; i++) {\n              locals[parserResult.itemName] = matches[i];\n              scope.matches.push({\n                id: getMatchId(i),\n                label: parserResult.viewMapper(scope, locals),\n                model: matches[i]\n              });\n            }\n\n            scope.query = inputValue;\n            //position pop-up with matches - we need to re-calculate its position each time we are opening a window\n            //with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page\n            //due to other elements being rendered\n            recalculatePosition();\n\n            element.attr('aria-expanded', true);\n\n            //Select the single remaining option if user input matches\n            if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) {\n              if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {\n                $$debounce(function() {\n                  scope.select(0, evt);\n                }, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);\n              } else {\n                scope.select(0, evt);\n              }\n            }\n\n            if (showHint) {\n              var firstLabel = scope.matches[0].label;\n              if (angular.isString(inputValue) &&\n                inputValue.length > 0 &&\n                firstLabel.slice(0, inputValue.length).toUpperCase() === inputValue.toUpperCase()) {\n                hintInputElem.val(inputValue + firstLabel.slice(inputValue.length));\n              } else {\n                hintInputElem.val('');\n              }\n            }\n          } else {\n            resetMatches();\n            isNoResultsSetter(originalScope, true);\n          }\n        }\n        if (onCurrentRequest) {\n          isLoadingSetter(originalScope, false);\n        }\n      }, function() {\n        resetMatches();\n        isLoadingSetter(originalScope, false);\n        isNoResultsSetter(originalScope, true);\n      });\n    };\n\n    // bind events only if appendToBody params exist - performance feature\n    if (appendToBody) {\n      angular.element($window).on('resize', fireRecalculating);\n      $document.find('body').on('scroll', fireRecalculating);\n    }\n\n    // Declare the debounced function outside recalculating for\n    // proper debouncing\n    var debouncedRecalculate = $$debounce(function() {\n      // if popup is visible\n      if (scope.matches.length) {\n        recalculatePosition();\n      }\n\n      scope.moveInProgress = false;\n    }, eventDebounceTime);\n\n    // Default progress type\n    scope.moveInProgress = false;\n\n    function fireRecalculating() {\n      if (!scope.moveInProgress) {\n        scope.moveInProgress = true;\n        scope.$digest();\n      }\n\n      debouncedRecalculate();\n    }\n\n    // recalculate actual position and set new values to scope\n    // after digest loop is popup in right position\n    function recalculatePosition() {\n      scope.position = appendToBody ? $position.offset(element) : $position.position(element);\n      scope.position.top += element.prop('offsetHeight');\n    }\n\n    //we need to propagate user's query so we can higlight matches\n    scope.query = undefined;\n\n    //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later\n    var timeoutPromise;\n\n    var scheduleSearchWithTimeout = function(inputValue) {\n      timeoutPromise = $timeout(function() {\n        getMatchesAsync(inputValue);\n      }, waitTime);\n    };\n\n    var cancelPreviousTimeout = function() {\n      if (timeoutPromise) {\n        $timeout.cancel(timeoutPromise);\n      }\n    };\n\n    resetMatches();\n\n    scope.assignIsOpen = function (isOpen) {\n      isOpenSetter(originalScope, isOpen);\n    };\n\n    scope.select = function(activeIdx, evt) {\n      //called from within the $digest() cycle\n      var locals = {};\n      var model, item;\n\n      selected = true;\n      locals[parserResult.itemName] = item = scope.matches[activeIdx].model;\n      model = parserResult.modelMapper(originalScope, locals);\n      $setModelValue(originalScope, model);\n      modelCtrl.$setValidity('editable', true);\n      modelCtrl.$setValidity('parse', true);\n\n      onSelectCallback(originalScope, {\n        $item: item,\n        $model: model,\n        $label: parserResult.viewMapper(originalScope, locals),\n        $event: evt\n      });\n\n      resetMatches();\n\n      //return focus to the input element if a match was selected via a mouse click event\n      // use timeout to avoid $rootScope:inprog error\n      if (scope.$eval(attrs.typeaheadFocusOnSelect) !== false) {\n        $timeout(function() { element[0].focus(); }, 0, false);\n      }\n    };\n\n    //bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)\n    element.on('keydown', function(evt) {\n      //typeahead is open and an \"interesting\" key was pressed\n      if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {\n        return;\n      }\n\n      var shouldSelect = isSelectEvent(originalScope, {$event: evt});\n\n      /**\n       * if there's nothing selected (i.e. focusFirst) and enter or tab is hit\n       * or\n       * shift + tab is pressed to bring focus to the previous element\n       * then clear the results\n       */\n      if (scope.activeIdx === -1 && shouldSelect || evt.which === 9 && !!evt.shiftKey) {\n        resetMatches();\n        scope.$digest();\n        return;\n      }\n\n      evt.preventDefault();\n      var target;\n      switch (evt.which) {\n        case 27: // escape\n          evt.stopPropagation();\n\n          resetMatches();\n          originalScope.$digest();\n          break;\n        case 38: // up arrow\n          scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;\n          scope.$digest();\n          target = popUpEl[0].querySelectorAll('.uib-typeahead-match')[scope.activeIdx];\n          target.parentNode.scrollTop = target.offsetTop;\n          break;\n        case 40: // down arrow\n          scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;\n          scope.$digest();\n          target = popUpEl[0].querySelectorAll('.uib-typeahead-match')[scope.activeIdx];\n          target.parentNode.scrollTop = target.offsetTop;\n          break;\n        default:\n          if (shouldSelect) {\n            scope.$apply(function() {\n              if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {\n                $$debounce(function() {\n                  scope.select(scope.activeIdx, evt);\n                }, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);\n              } else {\n                scope.select(scope.activeIdx, evt);\n              }\n            });\n          }\n      }\n    });\n\n    element.on('focus', function (evt) {\n      hasFocus = true;\n      if (minLength === 0 && !modelCtrl.$viewValue) {\n        $timeout(function() {\n          getMatchesAsync(modelCtrl.$viewValue, evt);\n        }, 0);\n      }\n    });\n\n    element.on('blur', function(evt) {\n      if (isSelectOnBlur && scope.matches.length && scope.activeIdx !== -1 && !selected) {\n        selected = true;\n        scope.$apply(function() {\n          if (angular.isObject(scope.debounceUpdate) && angular.isNumber(scope.debounceUpdate.blur)) {\n            $$debounce(function() {\n              scope.select(scope.activeIdx, evt);\n            }, scope.debounceUpdate.blur);\n          } else {\n            scope.select(scope.activeIdx, evt);\n          }\n        });\n      }\n      if (!isEditable && modelCtrl.$error.editable) {\n        modelCtrl.$setViewValue();\n        scope.$apply(function() {\n          // Reset validity as we are clearing\n          modelCtrl.$setValidity('editable', true);\n          modelCtrl.$setValidity('parse', true);\n        });\n        element.val('');\n      }\n      hasFocus = false;\n      selected = false;\n    });\n\n    // Keep reference to click handler to unbind it.\n    var dismissClickHandler = function(evt) {\n      // Issue #3973\n      // Firefox treats right click as a click on document\n      if (element[0] !== evt.target && evt.which !== 3 && scope.matches.length !== 0) {\n        resetMatches();\n        if (!$rootScope.$$phase) {\n          originalScope.$digest();\n        }\n      }\n    };\n\n    $document.on('click', dismissClickHandler);\n\n    originalScope.$on('$destroy', function() {\n      $document.off('click', dismissClickHandler);\n      if (appendToBody || appendTo) {\n        $popup.remove();\n      }\n\n      if (appendToBody) {\n        angular.element($window).off('resize', fireRecalculating);\n        $document.find('body').off('scroll', fireRecalculating);\n      }\n      // Prevent jQuery cache memory leak\n      popUpEl.remove();\n\n      if (showHint) {\n          inputsContainer.remove();\n      }\n    });\n\n    var $popup = $compile(popUpEl)(scope);\n\n    if (appendToBody) {\n      $document.find('body').append($popup);\n    } else if (appendTo) {\n      angular.element(appendTo).eq(0).append($popup);\n    } else {\n      element.after($popup);\n    }\n\n    this.init = function(_modelCtrl) {\n      modelCtrl = _modelCtrl;\n      ngModelOptions = extractOptions(modelCtrl);\n\n      scope.debounceUpdate = $parse(ngModelOptions.getOption('debounce'))(originalScope);\n\n      //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM\n      //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue\n      modelCtrl.$parsers.unshift(function(inputValue) {\n        hasFocus = true;\n\n        if (minLength === 0 || inputValue && inputValue.length >= minLength) {\n          if (waitTime > 0) {\n            cancelPreviousTimeout();\n            scheduleSearchWithTimeout(inputValue);\n          } else {\n            getMatchesAsync(inputValue);\n          }\n        } else {\n          isLoadingSetter(originalScope, false);\n          cancelPreviousTimeout();\n          resetMatches();\n        }\n\n        if (isEditable) {\n          return inputValue;\n        }\n\n        if (!inputValue) {\n          // Reset in case user had typed something previously.\n          modelCtrl.$setValidity('editable', true);\n          return null;\n        }\n\n        modelCtrl.$setValidity('editable', false);\n        return undefined;\n      });\n\n      modelCtrl.$formatters.push(function(modelValue) {\n        var candidateViewValue, emptyViewValue;\n        var locals = {};\n\n        // The validity may be set to false via $parsers (see above) if\n        // the model is restricted to selected values. If the model\n        // is set manually it is considered to be valid.\n        if (!isEditable) {\n          modelCtrl.$setValidity('editable', true);\n        }\n\n        if (inputFormatter) {\n          locals.$model = modelValue;\n          return inputFormatter(originalScope, locals);\n        }\n\n        //it might happen that we don't have enough info to properly render input value\n        //we need to check for this situation and simply return model value if we can't apply custom formatting\n        locals[parserResult.itemName] = modelValue;\n        candidateViewValue = parserResult.viewMapper(originalScope, locals);\n        locals[parserResult.itemName] = undefined;\n        emptyViewValue = parserResult.viewMapper(originalScope, locals);\n\n        return candidateViewValue !== emptyViewValue ? candidateViewValue : modelValue;\n      });\n    };\n\n    function extractOptions(ngModelCtrl) {\n      var ngModelOptions;\n\n      if (angular.version.minor < 6) { // in angular < 1.6 $options could be missing\n        // guarantee a value\n        ngModelOptions = ngModelCtrl.$options || {};\n\n        // mimic 1.6+ api\n        ngModelOptions.getOption = function (key) {\n          return ngModelOptions[key];\n        };\n      } else { // in angular >=1.6 $options is always present\n        ngModelOptions = ngModelCtrl.$options;\n      }\n\n      return ngModelOptions;\n    }\n  }])\n\n  .directive('uibTypeahead', function() {\n    return {\n      controller: 'UibTypeaheadController',\n      require: ['ngModel', 'uibTypeahead'],\n      link: function(originalScope, element, attrs, ctrls) {\n        ctrls[1].init(ctrls[0]);\n      }\n    };\n  })\n\n  .directive('uibTypeaheadPopup', ['$$debounce', function($$debounce) {\n    return {\n      scope: {\n        matches: '=',\n        query: '=',\n        active: '=',\n        position: '&',\n        moveInProgress: '=',\n        select: '&',\n        assignIsOpen: '&',\n        debounce: '&'\n      },\n      replace: true,\n      templateUrl: function(element, attrs) {\n        return attrs.popupTemplateUrl || 'uib/template/typeahead/typeahead-popup.html';\n      },\n      link: function(scope, element, attrs) {\n        scope.templateUrl = attrs.templateUrl;\n\n        scope.isOpen = function() {\n          var isDropdownOpen = scope.matches.length > 0;\n          scope.assignIsOpen({ isOpen: isDropdownOpen });\n          return isDropdownOpen;\n        };\n\n        scope.isActive = function(matchIdx) {\n          return scope.active === matchIdx;\n        };\n\n        scope.selectActive = function(matchIdx) {\n          scope.active = matchIdx;\n        };\n\n        scope.selectMatch = function(activeIdx, evt) {\n          var debounce = scope.debounce();\n          if (angular.isNumber(debounce) || angular.isObject(debounce)) {\n            $$debounce(function() {\n              scope.select({activeIdx: activeIdx, evt: evt});\n            }, angular.isNumber(debounce) ? debounce : debounce['default']);\n          } else {\n            scope.select({activeIdx: activeIdx, evt: evt});\n          }\n        };\n      }\n    };\n  }])\n\n  .directive('uibTypeaheadMatch', ['$templateRequest', '$compile', '$parse', function($templateRequest, $compile, $parse) {\n    return {\n      scope: {\n        index: '=',\n        match: '=',\n        query: '='\n      },\n      link: function(scope, element, attrs) {\n        var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'uib/template/typeahead/typeahead-match.html';\n        $templateRequest(tplUrl).then(function(tplContent) {\n          var tplEl = angular.element(tplContent.trim());\n          element.replaceWith(tplEl);\n          $compile(tplEl)(scope);\n        });\n      }\n    };\n  }])\n\n  .filter('uibTypeaheadHighlight', ['$sce', '$injector', '$log', function($sce, $injector, $log) {\n    var isSanitizePresent;\n    isSanitizePresent = $injector.has('$sanitize');\n\n    function escapeRegexp(queryToEscape) {\n      // Regex: capture the whole query string and replace it with the string that will be used to match\n      // the results, for example if the capture is \"a\" the result will be \\a\n      return queryToEscape.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n    }\n\n    function containsHtml(matchItem) {\n      return /<.*>/g.test(matchItem);\n    }\n\n    return function(matchItem, query) {\n      if (!isSanitizePresent && containsHtml(matchItem)) {\n        $log.warn('Unsafe use of typeahead please use ngSanitize'); // Warn the user about the danger\n      }\n      matchItem = query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem; // Replaces the capture string with a the same string inside of a \"strong\" tag\n      if (!isSanitizePresent) {\n        matchItem = $sce.trustAsHtml(matchItem); // If $sanitize is not present we pack the string in a $sce object for the ng-bind-html directive\n      }\n      return matchItem;\n    };\n  }]);\n","template/accordion/accordion-group.html.js":"angular.module(\"uib/template/accordion/accordion-group.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/accordion/accordion-group.html\",\n    \"<div role=\\\"tab\\\" id=\\\"{{::headingId}}\\\" aria-selected=\\\"{{isOpen}}\\\" class=\\\"panel-heading\\\" ng-keypress=\\\"toggleOpen($event)\\\">\\n\" +\n    \"  <h4 class=\\\"panel-title\\\">\\n\" +\n    \"    <a role=\\\"button\\\" data-toggle=\\\"collapse\\\" href aria-expanded=\\\"{{isOpen}}\\\" aria-controls=\\\"{{::panelId}}\\\" tabindex=\\\"0\\\" class=\\\"accordion-toggle\\\" ng-click=\\\"toggleOpen()\\\" uib-accordion-transclude=\\\"heading\\\" ng-disabled=\\\"isDisabled\\\" uib-tabindex-toggle><span uib-accordion-header ng-class=\\\"{'text-muted': isDisabled}\\\">{{heading}}</span></a>\\n\" +\n    \"  </h4>\\n\" +\n    \"</div>\\n\" +\n    \"<div id=\\\"{{::panelId}}\\\" aria-labelledby=\\\"{{::headingId}}\\\" aria-hidden=\\\"{{!isOpen}}\\\" role=\\\"tabpanel\\\" class=\\\"panel-collapse collapse\\\" uib-collapse=\\\"!isOpen\\\">\\n\" +\n    \"  <div class=\\\"panel-body\\\" ng-transclude></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/accordion/accordion.html.js":"angular.module(\"uib/template/accordion/accordion.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/accordion/accordion.html\",\n    \"<div role=\\\"tablist\\\" class=\\\"panel-group\\\" ng-transclude></div>\");\n}]);\n","template/alert/alert.html.js":"angular.module(\"uib/template/alert/alert.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/alert/alert.html\",\n    \"<button ng-show=\\\"closeable\\\" type=\\\"button\\\" class=\\\"close\\\" ng-click=\\\"close({$event: $event})\\\">\\n\" +\n    \"  <span aria-hidden=\\\"true\\\">&times;</span>\\n\" +\n    \"  <span class=\\\"sr-only\\\">Close</span>\\n\" +\n    \"</button>\\n\" +\n    \"<div ng-transclude></div>\\n\" +\n    \"\");\n}]);\n","template/carousel/carousel.html.js":"angular.module(\"uib/template/carousel/carousel.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/carousel/carousel.html\",\n    \"<div class=\\\"carousel-inner\\\" ng-transclude></div>\\n\" +\n    \"<a role=\\\"button\\\" href class=\\\"left carousel-control\\\" ng-click=\\\"prev()\\\" ng-class=\\\"{ disabled: isPrevDisabled() }\\\" ng-show=\\\"slides.length > 1\\\">\\n\" +\n    \"  <span aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-left\\\"></span>\\n\" +\n    \"  <span class=\\\"sr-only\\\">previous</span>\\n\" +\n    \"</a>\\n\" +\n    \"<a role=\\\"button\\\" href class=\\\"right carousel-control\\\" ng-click=\\\"next()\\\" ng-class=\\\"{ disabled: isNextDisabled() }\\\" ng-show=\\\"slides.length > 1\\\">\\n\" +\n    \"  <span aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-right\\\"></span>\\n\" +\n    \"  <span class=\\\"sr-only\\\">next</span>\\n\" +\n    \"</a>\\n\" +\n    \"<ol class=\\\"carousel-indicators\\\" ng-show=\\\"slides.length > 1\\\">\\n\" +\n    \"  <li ng-repeat=\\\"slide in slides | orderBy:indexOfSlide track by $index\\\" ng-class=\\\"{ active: isActive(slide) }\\\" ng-click=\\\"select(slide)\\\">\\n\" +\n    \"    <span class=\\\"sr-only\\\">slide {{ $index + 1 }} of {{ slides.length }}<span ng-if=\\\"isActive(slide)\\\">, currently active</span></span>\\n\" +\n    \"  </li>\\n\" +\n    \"</ol>\\n\" +\n    \"\");\n}]);\n","template/carousel/slide.html.js":"angular.module(\"uib/template/carousel/slide.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/carousel/slide.html\",\n    \"<div class=\\\"text-center\\\" ng-transclude></div>\\n\" +\n    \"\");\n}]);\n","template/datepicker/datepicker.html.js":"angular.module(\"uib/template/datepicker/datepicker.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/datepicker/datepicker.html\",\n    \"<div ng-switch=\\\"datepickerMode\\\">\\n\" +\n    \"  <div uib-daypicker ng-switch-when=\\\"day\\\" tabindex=\\\"0\\\" class=\\\"uib-daypicker\\\"></div>\\n\" +\n    \"  <div uib-monthpicker ng-switch-when=\\\"month\\\" tabindex=\\\"0\\\" class=\\\"uib-monthpicker\\\"></div>\\n\" +\n    \"  <div uib-yearpicker ng-switch-when=\\\"year\\\" tabindex=\\\"0\\\" class=\\\"uib-yearpicker\\\"></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/datepicker/day.html.js":"angular.module(\"uib/template/datepicker/day.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/datepicker/day.html\",\n    \"<table role=\\\"grid\\\" aria-labelledby=\\\"{{::uniqueId}}-title\\\" aria-activedescendant=\\\"{{activeDateId}}\\\">\\n\" +\n    \"  <thead>\\n\" +\n    \"    <tr>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-left uib-left\\\" ng-click=\\\"move(-1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-left\\\"></i><span class=\\\"sr-only\\\">previous</span></button></th>\\n\" +\n    \"      <th colspan=\\\"{{::5 + showWeeks}}\\\"><button id=\\\"{{::uniqueId}}-title\\\" role=\\\"heading\\\" aria-live=\\\"assertive\\\" aria-atomic=\\\"true\\\" type=\\\"button\\\" class=\\\"btn btn-default btn-sm uib-title\\\" ng-click=\\\"toggleMode()\\\" ng-disabled=\\\"datepickerMode === maxMode\\\" tabindex=\\\"-1\\\"><strong>{{title}}</strong></button></th>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-right uib-right\\\" ng-click=\\\"move(1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-right\\\"></i><span class=\\\"sr-only\\\">next</span></button></th>\\n\" +\n    \"    </tr>\\n\" +\n    \"    <tr>\\n\" +\n    \"      <th ng-if=\\\"showWeeks\\\" class=\\\"text-center\\\"></th>\\n\" +\n    \"      <th ng-repeat=\\\"label in ::labels track by $index\\\" class=\\\"text-center\\\"><small aria-label=\\\"{{::label.full}}\\\">{{::label.abbr}}</small></th>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </thead>\\n\" +\n    \"  <tbody>\\n\" +\n    \"    <tr class=\\\"uib-weeks\\\" ng-repeat=\\\"row in rows track by $index\\\" role=\\\"row\\\">\\n\" +\n    \"      <td ng-if=\\\"showWeeks\\\" class=\\\"text-center h6\\\"><em>{{ weekNumbers[$index] }}</em></td>\\n\" +\n    \"      <td ng-repeat=\\\"dt in row\\\" class=\\\"uib-day text-center\\\" role=\\\"gridcell\\\"\\n\" +\n    \"        id=\\\"{{::dt.uid}}\\\"\\n\" +\n    \"        ng-class=\\\"::dt.customClass\\\">\\n\" +\n    \"        <button type=\\\"button\\\" class=\\\"btn btn-default btn-sm\\\"\\n\" +\n    \"          uib-is-class=\\\"\\n\" +\n    \"            'btn-info' for selectedDt,\\n\" +\n    \"            'active' for activeDt\\n\" +\n    \"            on dt\\\"\\n\" +\n    \"          ng-click=\\\"select(dt.date)\\\"\\n\" +\n    \"          ng-disabled=\\\"::dt.disabled\\\"\\n\" +\n    \"          tabindex=\\\"-1\\\"><span ng-class=\\\"::{'text-muted': dt.secondary, 'text-info': dt.current}\\\">{{::dt.label}}</span></button>\\n\" +\n    \"      </td>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </tbody>\\n\" +\n    \"</table>\\n\" +\n    \"\");\n}]);\n","template/datepicker/month.html.js":"angular.module(\"uib/template/datepicker/month.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/datepicker/month.html\",\n    \"<table role=\\\"grid\\\" aria-labelledby=\\\"{{::uniqueId}}-title\\\" aria-activedescendant=\\\"{{activeDateId}}\\\">\\n\" +\n    \"  <thead>\\n\" +\n    \"    <tr>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-left uib-left\\\" ng-click=\\\"move(-1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-left\\\"></i><span class=\\\"sr-only\\\">previous</span></button></th>\\n\" +\n    \"      <th colspan=\\\"{{::yearHeaderColspan}}\\\"><button id=\\\"{{::uniqueId}}-title\\\" role=\\\"heading\\\" aria-live=\\\"assertive\\\" aria-atomic=\\\"true\\\" type=\\\"button\\\" class=\\\"btn btn-default btn-sm uib-title\\\" ng-click=\\\"toggleMode()\\\" ng-disabled=\\\"datepickerMode === maxMode\\\" tabindex=\\\"-1\\\"><strong>{{title}}</strong></button></th>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-right uib-right\\\" ng-click=\\\"move(1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-right\\\"></i><span class=\\\"sr-only\\\">next</span></i></button></th>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </thead>\\n\" +\n    \"  <tbody>\\n\" +\n    \"    <tr class=\\\"uib-months\\\" ng-repeat=\\\"row in rows track by $index\\\" role=\\\"row\\\">\\n\" +\n    \"      <td ng-repeat=\\\"dt in row\\\" class=\\\"uib-month text-center\\\" role=\\\"gridcell\\\"\\n\" +\n    \"        id=\\\"{{::dt.uid}}\\\"\\n\" +\n    \"        ng-class=\\\"::dt.customClass\\\">\\n\" +\n    \"        <button type=\\\"button\\\" class=\\\"btn btn-default\\\"\\n\" +\n    \"          uib-is-class=\\\"\\n\" +\n    \"            'btn-info' for selectedDt,\\n\" +\n    \"            'active' for activeDt\\n\" +\n    \"            on dt\\\"\\n\" +\n    \"          ng-click=\\\"select(dt.date)\\\"\\n\" +\n    \"          ng-disabled=\\\"::dt.disabled\\\"\\n\" +\n    \"          tabindex=\\\"-1\\\"><span ng-class=\\\"::{'text-info': dt.current}\\\">{{::dt.label}}</span></button>\\n\" +\n    \"      </td>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </tbody>\\n\" +\n    \"</table>\\n\" +\n    \"\");\n}]);\n","template/datepicker/year.html.js":"angular.module(\"uib/template/datepicker/year.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/datepicker/year.html\",\n    \"<table role=\\\"grid\\\" aria-labelledby=\\\"{{::uniqueId}}-title\\\" aria-activedescendant=\\\"{{activeDateId}}\\\">\\n\" +\n    \"  <thead>\\n\" +\n    \"    <tr>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-left uib-left\\\" ng-click=\\\"move(-1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-left\\\"></i><span class=\\\"sr-only\\\">previous</span></button></th>\\n\" +\n    \"      <th colspan=\\\"{{::columns - 2}}\\\"><button id=\\\"{{::uniqueId}}-title\\\" role=\\\"heading\\\" aria-live=\\\"assertive\\\" aria-atomic=\\\"true\\\" type=\\\"button\\\" class=\\\"btn btn-default btn-sm uib-title\\\" ng-click=\\\"toggleMode()\\\" ng-disabled=\\\"datepickerMode === maxMode\\\" tabindex=\\\"-1\\\"><strong>{{title}}</strong></button></th>\\n\" +\n    \"      <th><button type=\\\"button\\\" class=\\\"btn btn-default btn-sm pull-right uib-right\\\" ng-click=\\\"move(1)\\\" tabindex=\\\"-1\\\"><i aria-hidden=\\\"true\\\" class=\\\"glyphicon glyphicon-chevron-right\\\"></i><span class=\\\"sr-only\\\">next</span></button></th>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </thead>\\n\" +\n    \"  <tbody>\\n\" +\n    \"    <tr class=\\\"uib-years\\\" ng-repeat=\\\"row in rows track by $index\\\" role=\\\"row\\\">\\n\" +\n    \"      <td ng-repeat=\\\"dt in row\\\" class=\\\"uib-year text-center\\\" role=\\\"gridcell\\\"\\n\" +\n    \"        id=\\\"{{::dt.uid}}\\\"\\n\" +\n    \"        ng-class=\\\"::dt.customClass\\\">\\n\" +\n    \"        <button type=\\\"button\\\" class=\\\"btn btn-default\\\"\\n\" +\n    \"          uib-is-class=\\\"\\n\" +\n    \"            'btn-info' for selectedDt,\\n\" +\n    \"            'active' for activeDt\\n\" +\n    \"            on dt\\\"\\n\" +\n    \"          ng-click=\\\"select(dt.date)\\\"\\n\" +\n    \"          ng-disabled=\\\"::dt.disabled\\\"\\n\" +\n    \"          tabindex=\\\"-1\\\"><span ng-class=\\\"::{'text-info': dt.current}\\\">{{::dt.label}}</span></button>\\n\" +\n    \"      </td>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </tbody>\\n\" +\n    \"</table>\\n\" +\n    \"\");\n}]);\n","template/datepickerPopup/popup.html.js":"angular.module(\"uib/template/datepickerPopup/popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/datepickerPopup/popup.html\",\n    \"<ul role=\\\"presentation\\\" class=\\\"uib-datepicker-popup dropdown-menu uib-position-measure\\\" dropdown-nested ng-if=\\\"isOpen\\\" ng-keydown=\\\"keydown($event)\\\" ng-click=\\\"$event.stopPropagation()\\\">\\n\" +\n    \"  <li ng-transclude></li>\\n\" +\n    \"  <li ng-if=\\\"showButtonBar\\\" class=\\\"uib-button-bar\\\">\\n\" +\n    \"    <span class=\\\"btn-group pull-left\\\">\\n\" +\n    \"      <button type=\\\"button\\\" class=\\\"btn btn-sm btn-info uib-datepicker-current\\\" ng-click=\\\"select('today', $event)\\\" ng-disabled=\\\"isDisabled('today')\\\">{{ getText('current') }}</button>\\n\" +\n    \"      <button type=\\\"button\\\" class=\\\"btn btn-sm btn-danger uib-clear\\\" ng-click=\\\"select(null, $event)\\\">{{ getText('clear') }}</button>\\n\" +\n    \"    </span>\\n\" +\n    \"    <button type=\\\"button\\\" class=\\\"btn btn-sm btn-success pull-right uib-close\\\" ng-click=\\\"close($event)\\\">{{ getText('close') }}</button>\\n\" +\n    \"  </li>\\n\" +\n    \"</ul>\\n\" +\n    \"\");\n}]);\n","template/modal/window.html.js":"angular.module(\"uib/template/modal/window.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/modal/window.html\",\n    \"<div class=\\\"modal-dialog {{size ? 'modal-' + size : ''}}\\\"><div class=\\\"modal-content\\\" uib-modal-transclude></div></div>\\n\" +\n    \"\");\n}]);\n","template/pager/pager.html.js":"angular.module(\"uib/template/pager/pager.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/pager/pager.html\",\n    \"<li ng-class=\\\"{disabled: noPrevious()||ngDisabled, previous: align}\\\"><a href ng-click=\\\"selectPage(page - 1, $event)\\\" ng-disabled=\\\"noPrevious()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('previous')}}</a></li>\\n\" +\n    \"<li ng-class=\\\"{disabled: noNext()||ngDisabled, next: align}\\\"><a href ng-click=\\\"selectPage(page + 1, $event)\\\" ng-disabled=\\\"noNext()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('next')}}</a></li>\\n\" +\n    \"\");\n}]);\n","template/pagination/pagination.html.js":"angular.module(\"uib/template/pagination/pagination.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/pagination/pagination.html\",\n    \"<li role=\\\"menuitem\\\" ng-if=\\\"::boundaryLinks\\\" ng-class=\\\"{disabled: noPrevious()||ngDisabled}\\\" class=\\\"pagination-first\\\"><a href ng-click=\\\"selectPage(1, $event)\\\" ng-disabled=\\\"noPrevious()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('first')}}</a></li>\\n\" +\n    \"<li role=\\\"menuitem\\\" ng-if=\\\"::directionLinks\\\" ng-class=\\\"{disabled: noPrevious()||ngDisabled}\\\" class=\\\"pagination-prev\\\"><a href ng-click=\\\"selectPage(page - 1, $event)\\\" ng-disabled=\\\"noPrevious()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('previous')}}</a></li>\\n\" +\n    \"<li role=\\\"menuitem\\\" ng-repeat=\\\"page in pages track by $index\\\" ng-class=\\\"{active: page.active,disabled: ngDisabled&&!page.active}\\\" class=\\\"pagination-page\\\"><a href ng-click=\\\"selectPage(page.number, $event)\\\" ng-disabled=\\\"ngDisabled&&!page.active\\\" uib-tabindex-toggle>{{page.text}}</a></li>\\n\" +\n    \"<li role=\\\"menuitem\\\" ng-if=\\\"::directionLinks\\\" ng-class=\\\"{disabled: noNext()||ngDisabled}\\\" class=\\\"pagination-next\\\"><a href ng-click=\\\"selectPage(page + 1, $event)\\\" ng-disabled=\\\"noNext()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('next')}}</a></li>\\n\" +\n    \"<li role=\\\"menuitem\\\" ng-if=\\\"::boundaryLinks\\\" ng-class=\\\"{disabled: noNext()||ngDisabled}\\\" class=\\\"pagination-last\\\"><a href ng-click=\\\"selectPage(totalPages, $event)\\\" ng-disabled=\\\"noNext()||ngDisabled\\\" uib-tabindex-toggle>{{::getText('last')}}</a></li>\\n\" +\n    \"\");\n}]);\n","template/tooltip/tooltip-html-popup.html.js":"angular.module(\"uib/template/tooltip/tooltip-html-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/tooltip/tooltip-html-popup.html\",\n    \"<div class=\\\"tooltip-arrow\\\"></div>\\n\" +\n    \"<div class=\\\"tooltip-inner\\\" ng-bind-html=\\\"contentExp()\\\"></div>\\n\" +\n    \"\");\n}]);\n","template/tooltip/tooltip-popup.html.js":"angular.module(\"uib/template/tooltip/tooltip-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/tooltip/tooltip-popup.html\",\n    \"<div class=\\\"tooltip-arrow\\\"></div>\\n\" +\n    \"<div class=\\\"tooltip-inner\\\" ng-bind=\\\"content\\\"></div>\\n\" +\n    \"\");\n}]);\n","template/tooltip/tooltip-template-popup.html.js":"angular.module(\"uib/template/tooltip/tooltip-template-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/tooltip/tooltip-template-popup.html\",\n    \"<div class=\\\"tooltip-arrow\\\"></div>\\n\" +\n    \"<div class=\\\"tooltip-inner\\\"\\n\" +\n    \"  uib-tooltip-template-transclude=\\\"contentExp()\\\"\\n\" +\n    \"  tooltip-template-transclude-scope=\\\"originScope()\\\"></div>\\n\" +\n    \"\");\n}]);\n","template/popover/popover-html.html.js":"angular.module(\"uib/template/popover/popover-html.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/popover/popover-html.html\",\n    \"<div class=\\\"arrow\\\"></div>\\n\" +\n    \"\\n\" +\n    \"<div class=\\\"popover-inner\\\">\\n\" +\n    \"    <h3 class=\\\"popover-title\\\" ng-bind=\\\"uibTitle\\\" ng-if=\\\"uibTitle\\\"></h3>\\n\" +\n    \"    <div class=\\\"popover-content\\\" ng-bind-html=\\\"contentExp()\\\"></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/popover/popover-template.html.js":"angular.module(\"uib/template/popover/popover-template.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/popover/popover-template.html\",\n    \"<div class=\\\"arrow\\\"></div>\\n\" +\n    \"\\n\" +\n    \"<div class=\\\"popover-inner\\\">\\n\" +\n    \"    <h3 class=\\\"popover-title\\\" ng-bind=\\\"uibTitle\\\" ng-if=\\\"uibTitle\\\"></h3>\\n\" +\n    \"    <div class=\\\"popover-content\\\"\\n\" +\n    \"      uib-tooltip-template-transclude=\\\"contentExp()\\\"\\n\" +\n    \"      tooltip-template-transclude-scope=\\\"originScope()\\\"></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/popover/popover.html.js":"angular.module(\"uib/template/popover/popover.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/popover/popover.html\",\n    \"<div class=\\\"arrow\\\"></div>\\n\" +\n    \"\\n\" +\n    \"<div class=\\\"popover-inner\\\">\\n\" +\n    \"    <h3 class=\\\"popover-title\\\" ng-bind=\\\"uibTitle\\\" ng-if=\\\"uibTitle\\\"></h3>\\n\" +\n    \"    <div class=\\\"popover-content\\\" ng-bind=\\\"content\\\"></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/progressbar/bar.html.js":"angular.module(\"uib/template/progressbar/bar.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/progressbar/bar.html\",\n    \"<div class=\\\"progress-bar\\\" ng-class=\\\"type && 'progress-bar-' + type\\\" role=\\\"progressbar\\\" aria-valuenow=\\\"{{value}}\\\" aria-valuemin=\\\"0\\\" aria-valuemax=\\\"{{max}}\\\" ng-style=\\\"{width: (percent < 100 ? percent : 100) + '%'}\\\" aria-valuetext=\\\"{{percent | number:0}}%\\\" aria-labelledby=\\\"{{::title}}\\\" ng-transclude></div>\\n\" +\n    \"\");\n}]);\n","template/progressbar/progress.html.js":"angular.module(\"uib/template/progressbar/progress.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/progressbar/progress.html\",\n    \"<div class=\\\"progress\\\" ng-transclude aria-labelledby=\\\"{{::title}}\\\"></div>\");\n}]);\n","template/progressbar/progressbar.html.js":"angular.module(\"uib/template/progressbar/progressbar.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/progressbar/progressbar.html\",\n    \"<div class=\\\"progress\\\">\\n\" +\n    \"  <div class=\\\"progress-bar\\\" ng-class=\\\"type && 'progress-bar-' + type\\\" role=\\\"progressbar\\\" aria-valuenow=\\\"{{value}}\\\" aria-valuemin=\\\"0\\\" aria-valuemax=\\\"{{max}}\\\" ng-style=\\\"{width: (percent < 100 ? percent : 100) + '%'}\\\" aria-valuetext=\\\"{{percent | number:0}}%\\\" aria-labelledby=\\\"{{::title}}\\\" ng-transclude></div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/rating/rating.html.js":"angular.module(\"uib/template/rating/rating.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/rating/rating.html\",\n    \"<span ng-mouseleave=\\\"reset()\\\" ng-keydown=\\\"onKeydown($event)\\\" tabindex=\\\"0\\\" role=\\\"slider\\\" aria-valuemin=\\\"0\\\" aria-valuemax=\\\"{{range.length}}\\\" aria-valuenow=\\\"{{value}}\\\" aria-valuetext=\\\"{{title}}\\\">\\n\" +\n    \"    <span ng-repeat-start=\\\"r in range track by $index\\\" class=\\\"sr-only\\\">({{ $index < value ? '*' : ' ' }})</span>\\n\" +\n    \"    <i ng-repeat-end ng-mouseenter=\\\"enter($index + 1)\\\" ng-click=\\\"rate($index + 1)\\\" class=\\\"glyphicon\\\" ng-class=\\\"$index < value && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')\\\" ng-attr-title=\\\"{{r.title}}\\\"></i>\\n\" +\n    \"</span>\\n\" +\n    \"\");\n}]);\n","template/tabs/tab.html.js":"angular.module(\"uib/template/tabs/tab.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/tabs/tab.html\",\n    \"<li ng-class=\\\"[{active: active, disabled: disabled}, classes]\\\" class=\\\"uib-tab nav-item\\\">\\n\" +\n    \"  <a href ng-click=\\\"select($event)\\\" class=\\\"nav-link\\\" uib-tab-heading-transclude>{{heading}}</a>\\n\" +\n    \"</li>\\n\" +\n    \"\");\n}]);\n","template/tabs/tabset.html.js":"angular.module(\"uib/template/tabs/tabset.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/tabs/tabset.html\",\n    \"<div>\\n\" +\n    \"  <ul class=\\\"nav nav-{{tabset.type || 'tabs'}}\\\" ng-class=\\\"{'nav-stacked': vertical, 'nav-justified': justified}\\\" ng-transclude></ul>\\n\" +\n    \"  <div class=\\\"tab-content\\\">\\n\" +\n    \"    <div class=\\\"tab-pane\\\"\\n\" +\n    \"         ng-repeat=\\\"tab in tabset.tabs\\\"\\n\" +\n    \"         ng-class=\\\"{active: tabset.active === tab.index}\\\"\\n\" +\n    \"         uib-tab-content-transclude=\\\"tab\\\">\\n\" +\n    \"    </div>\\n\" +\n    \"  </div>\\n\" +\n    \"</div>\\n\" +\n    \"\");\n}]);\n","template/timepicker/timepicker.html.js":"angular.module(\"uib/template/timepicker/timepicker.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/timepicker/timepicker.html\",\n    \"<table class=\\\"uib-timepicker\\\">\\n\" +\n    \"  <tbody>\\n\" +\n    \"    <tr class=\\\"text-center\\\" ng-show=\\\"::showSpinners\\\">\\n\" +\n    \"      <td class=\\\"uib-increment hours\\\"><a ng-click=\\\"incrementHours()\\\" ng-class=\\\"{disabled: noIncrementHours()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noIncrementHours()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-up\\\"></span></a></td>\\n\" +\n    \"      <td>&nbsp;</td>\\n\" +\n    \"      <td class=\\\"uib-increment minutes\\\"><a ng-click=\\\"incrementMinutes()\\\" ng-class=\\\"{disabled: noIncrementMinutes()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noIncrementMinutes()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-up\\\"></span></a></td>\\n\" +\n    \"      <td ng-show=\\\"showSeconds\\\">&nbsp;</td>\\n\" +\n    \"      <td ng-show=\\\"showSeconds\\\" class=\\\"uib-increment seconds\\\"><a ng-click=\\\"incrementSeconds()\\\" ng-class=\\\"{disabled: noIncrementSeconds()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noIncrementSeconds()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-up\\\"></span></a></td>\\n\" +\n    \"      <td ng-show=\\\"showMeridian\\\"></td>\\n\" +\n    \"    </tr>\\n\" +\n    \"    <tr>\\n\" +\n    \"      <td class=\\\"form-group uib-time hours\\\" ng-class=\\\"{'has-error': invalidHours}\\\">\\n\" +\n    \"        <input type=\\\"text\\\" placeholder=\\\"HH\\\" ng-model=\\\"hours\\\" ng-change=\\\"updateHours()\\\" class=\\\"form-control text-center\\\" ng-readonly=\\\"::readonlyInput\\\" maxlength=\\\"2\\\" tabindex=\\\"{{::tabindex}}\\\" ng-disabled=\\\"noIncrementHours()\\\" ng-blur=\\\"blur()\\\">\\n\" +\n    \"      </td>\\n\" +\n    \"      <td class=\\\"uib-separator\\\">:</td>\\n\" +\n    \"      <td class=\\\"form-group uib-time minutes\\\" ng-class=\\\"{'has-error': invalidMinutes}\\\">\\n\" +\n    \"        <input type=\\\"text\\\" placeholder=\\\"MM\\\" ng-model=\\\"minutes\\\" ng-change=\\\"updateMinutes()\\\" class=\\\"form-control text-center\\\" ng-readonly=\\\"::readonlyInput\\\" maxlength=\\\"2\\\" tabindex=\\\"{{::tabindex}}\\\" ng-disabled=\\\"noIncrementMinutes()\\\" ng-blur=\\\"blur()\\\">\\n\" +\n    \"      </td>\\n\" +\n    \"      <td ng-show=\\\"showSeconds\\\" class=\\\"uib-separator\\\">:</td>\\n\" +\n    \"      <td class=\\\"form-group uib-time seconds\\\" ng-class=\\\"{'has-error': invalidSeconds}\\\" ng-show=\\\"showSeconds\\\">\\n\" +\n    \"        <input type=\\\"text\\\" placeholder=\\\"SS\\\" ng-model=\\\"seconds\\\" ng-change=\\\"updateSeconds()\\\" class=\\\"form-control text-center\\\" ng-readonly=\\\"readonlyInput\\\" maxlength=\\\"2\\\" tabindex=\\\"{{::tabindex}}\\\" ng-disabled=\\\"noIncrementSeconds()\\\" ng-blur=\\\"blur()\\\">\\n\" +\n    \"      </td>\\n\" +\n    \"      <td ng-show=\\\"showMeridian\\\" class=\\\"uib-time am-pm\\\"><button type=\\\"button\\\" ng-class=\\\"{disabled: noToggleMeridian()}\\\" class=\\\"btn btn-default text-center\\\" ng-click=\\\"toggleMeridian()\\\" ng-disabled=\\\"noToggleMeridian()\\\" tabindex=\\\"{{::tabindex}}\\\">{{meridian}}</button></td>\\n\" +\n    \"    </tr>\\n\" +\n    \"    <tr class=\\\"text-center\\\" ng-show=\\\"::showSpinners\\\">\\n\" +\n    \"      <td class=\\\"uib-decrement hours\\\"><a ng-click=\\\"decrementHours()\\\" ng-class=\\\"{disabled: noDecrementHours()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noDecrementHours()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-down\\\"></span></a></td>\\n\" +\n    \"      <td>&nbsp;</td>\\n\" +\n    \"      <td class=\\\"uib-decrement minutes\\\"><a ng-click=\\\"decrementMinutes()\\\" ng-class=\\\"{disabled: noDecrementMinutes()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noDecrementMinutes()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-down\\\"></span></a></td>\\n\" +\n    \"      <td ng-show=\\\"showSeconds\\\">&nbsp;</td>\\n\" +\n    \"      <td ng-show=\\\"showSeconds\\\" class=\\\"uib-decrement seconds\\\"><a ng-click=\\\"decrementSeconds()\\\" ng-class=\\\"{disabled: noDecrementSeconds()}\\\" class=\\\"btn btn-link\\\" ng-disabled=\\\"noDecrementSeconds()\\\" tabindex=\\\"-1\\\"><span class=\\\"glyphicon glyphicon-chevron-down\\\"></span></a></td>\\n\" +\n    \"      <td ng-show=\\\"showMeridian\\\"></td>\\n\" +\n    \"    </tr>\\n\" +\n    \"  </tbody>\\n\" +\n    \"</table>\\n\" +\n    \"\");\n}]);\n","template/typeahead/typeahead-match.html.js":"angular.module(\"uib/template/typeahead/typeahead-match.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/typeahead/typeahead-match.html\",\n    \"<a href\\n\" +\n    \"   tabindex=\\\"-1\\\"\\n\" +\n    \"   ng-bind-html=\\\"match.label | uibTypeaheadHighlight:query\\\"\\n\" +\n    \"   ng-attr-title=\\\"{{match.label}}\\\"></a>\\n\" +\n    \"\");\n}]);\n","template/typeahead/typeahead-popup.html.js":"angular.module(\"uib/template/typeahead/typeahead-popup.html\", []).run([\"$templateCache\", function ($templateCache) {\n  $templateCache.put(\"uib/template/typeahead/typeahead-popup.html\",\n    \"<ul class=\\\"dropdown-menu\\\" ng-show=\\\"isOpen() && !moveInProgress\\\" ng-style=\\\"{top: position().top+'px', left: position().left+'px'}\\\" role=\\\"listbox\\\" aria-hidden=\\\"{{!isOpen()}}\\\">\\n\" +\n    \"    <li class=\\\"uib-typeahead-match\\\" ng-repeat=\\\"match in matches track by $index\\\" ng-class=\\\"{active: isActive($index) }\\\" ng-mouseenter=\\\"selectActive($index)\\\" ng-click=\\\"selectMatch($index, $event)\\\" role=\\\"option\\\" id=\\\"{{::match.id}}\\\">\\n\" +\n    \"        <div uib-typeahead-match index=\\\"$index\\\" match=\\\"match\\\" query=\\\"query\\\" template-url=\\\"templateUrl\\\"></div>\\n\" +\n    \"    </li>\\n\" +\n    \"</ul>\\n\" +\n    \"\");\n}]);\n"}}