diff --git a/bower.json b/bower.json index 1a75135e7..e5abe8be7 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.3.2", + "version": "2.3.3", "keywords": [ "angular", "bootstrap" diff --git a/dist/angular-strap.compat.js b/dist/angular-strap.compat.js new file mode 100644 index 000000000..8ba4786f9 --- /dev/null +++ b/dist/angular-strap.compat.js @@ -0,0 +1,4053 @@ +/** + * angular-strap + * @version v2.3.3 - 2015-09-24 + * @link http://mgcrea.github.io/angular-strap + * @author Olivier Louvignes (https://github.com/mgcrea) + * @license MIT License, http://www.opensource.org/licenses/MIT + */ +(function(window, document, undefined) { + 'use strict'; + angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$bsTypeahead', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'typeahead', + prefixEvent: '$typeahead', + placement: 'bottom-left', + templateUrl: 'typeahead/typeahead.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + minLength: 1, + filter: 'bsAsyncFilter', + limit: 6, + autoSelect: false, + comparator: '', + trimValue: true + }; + this.$get = ["$window", "$rootScope", "$bsTooltip", "$$bsRAF", "$timeout", function($window, $rootScope, $tooltip, $$rAF, $timeout) { + var bodyEl = angular.element($window.document.body); + function TypeaheadFactory(element, controller, config) { + var $typeahead = {}; + var options = angular.extend({}, defaults, config); + $typeahead = $tooltip(element, options); + var parentScope = config.scope; + var scope = $typeahead.$scope; + scope.$resetMatches = function() { + scope.$matches = []; + scope.$activeIndex = options.autoSelect ? 0 : -1; + }; + scope.$resetMatches(); + scope.$activate = function(index) { + scope.$$postDigest(function() { + $typeahead.activate(index); + }); + }; + scope.$select = function(index, evt) { + scope.$$postDigest(function() { + $typeahead.select(index); + }); + }; + scope.$isVisible = function() { + return $typeahead.$isVisible(); + }; + $typeahead.update = function(matches) { + scope.$matches = matches; + if (scope.$activeIndex >= matches.length) { + scope.$activeIndex = options.autoSelect ? 0 : -1; + } + safeDigest(scope); + $$rAF($typeahead.$applyPlacement); + }; + $typeahead.activate = function(index) { + scope.$activeIndex = index; + }; + $typeahead.select = function(index) { + if (index === -1) return; + var value = scope.$matches[index].value; + controller.$setViewValue(value); + controller.$render(); + scope.$resetMatches(); + if (parentScope) parentScope.$digest(); + scope.$emit(options.prefixEvent + '.select', value, index, $typeahead); + }; + $typeahead.$isVisible = function() { + if (!options.minLength || !controller) { + return !!scope.$matches.length; + } + return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength; + }; + $typeahead.$getIndex = function(value) { + var l = scope.$matches.length, i = l; + if (!l) return; + for (i = l; i--; ) { + if (scope.$matches[i].value === value) break; + } + if (i < 0) return; + return i; + }; + $typeahead.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + }; + $typeahead.$onKeyDown = function(evt) { + if (!/(38|40|13)/.test(evt.keyCode)) return; + if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) { + evt.preventDefault(); + evt.stopPropagation(); + } + if (evt.keyCode === 13 && scope.$matches.length) { + $typeahead.select(scope.$activeIndex); + } else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; + scope.$digest(); + }; + var show = $typeahead.show; + $typeahead.show = function() { + show(); + $timeout(function() { + $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + element && element.on('keydown', $typeahead.$onKeyDown); + } + }, 0, false); + }; + var hide = $typeahead.hide; + $typeahead.hide = function() { + $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + element && element.off('keydown', $typeahead.$onKeyDown); + } + if (!options.autoSelect) $typeahead.activate(-1); + hide(); + }; + return $typeahead; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + TypeaheadFactory.defaults = defaults; + return TypeaheadFactory; + } ]; + }).filter('bsAsyncFilter', ["$filter", function($filter) { + return function(array, expression, comparator) { + if (array && angular.isFunction(array.then)) { + return array.then(function(results) { + return $filter('filter')(results, expression, comparator); + }); + } else { + return $filter('filter')(array, expression, comparator); + } + }; + } ]).directive('bsTypeahead', ["$window", "$parse", "$q", "$bsTypeahead", "$bsParseOptions", function($window, $parse, $q, $typeahead, $parseOptions) { + var defaults = $typeahead.defaults; + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'trimValue' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + if (!element.attr('autocomplete')) element.attr('autocomplete', 'off'); + var filter = options.filter || defaults.filter; + var limit = options.limit || defaults.limit; + var comparator = options.comparator || defaults.comparator; + var bsOptions = attr.bsOptions; + if (filter) bsOptions += ' | ' + filter + ':$viewValue'; + if (comparator) bsOptions += ':' + comparator; + if (limit) bsOptions += ' | limitTo:' + limit; + var parsedOptions = $parseOptions(bsOptions); + var typeahead = $typeahead(element, controller, options); + if (options.watchOptions) { + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').replace(/\(.*\)/g, '').trim(); + scope.$watchCollection(watchedOptions, function(newValue, oldValue) { + parsedOptions.valuesFn(scope, controller).then(function(values) { + typeahead.update(values); + controller.$render(); + }); + }); + } + scope.$watch(attr.ngModel, function(newValue, oldValue) { + scope.$modelValue = newValue; + parsedOptions.valuesFn(scope, controller).then(function(values) { + if (options.selectMode && !values.length && newValue.length > 0) { + controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1)); + return; + } + if (values.length > limit) values = values.slice(0, limit); + var isVisible = typeahead.$isVisible(); + isVisible && typeahead.update(values); + if (values.length === 1 && values[0].value === newValue) return; + !isVisible && typeahead.update(values); + controller.$render(); + }); + }); + controller.$formatters.push(function(modelValue) { + var displayValue = parsedOptions.displayValue(modelValue); + if (displayValue) { + return displayValue; + } + if (modelValue && typeof modelValue !== 'object') { + return modelValue; + } + return ''; + }); + controller.$render = function() { + if (controller.$isEmpty(controller.$viewValue)) { + return element.val(''); + } + var index = typeahead.$getIndex(controller.$modelValue); + var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue; + selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected; + var value = selected ? selected.toString().replace(/<(?:.|\n)*?>/gm, '') : ''; + element.val(options.trimValue === false ? value : value.trim()); + }; + scope.$on('$destroy', function() { + if (typeahead) typeahead.destroy(); + options = null; + typeahead = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsTooltip', function() { + var defaults = this.defaults = { + animation: 'am-fade', + customClass: '', + prefixClass: 'tooltip', + prefixEvent: 'tooltip', + container: false, + target: false, + placement: 'top', + templateUrl: 'tooltip/tooltip.tpl.html', + template: '', + contentTemplate: false, + trigger: 'hover focus', + keyboard: false, + html: false, + show: false, + title: '', + type: '', + delay: 0, + autoClose: false, + bsEnabled: true, + viewport: { + selector: 'body', + padding: 0 + } + }; + this.$get = ["$window", "$rootScope", "$bsCompiler", "$q", "$templateCache", "$http", "$animate", "$sce", "bsDimensions", "$$bsRAF", "$timeout", function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) { + var trim = String.prototype.trim; + var isTouch = 'createTouch' in $window.document; + var htmlReplaceRegExp = /ng-bind="/gi; + var $body = angular.element($window.document); + function TooltipFactory(element, config) { + var $tooltip = {}; + var options = $tooltip.$options = angular.extend({}, defaults, config); + var promise = $tooltip.$promise = $bsCompiler.compile(options); + var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + var nodeName = element[0].nodeName.toLowerCase(); + if (options.delay && angular.isString(options.delay)) { + var split = options.delay.split(',').map(parseFloat); + options.delay = split.length > 1 ? { + show: split[0], + hide: split[1] + } : split[0]; + } + $tooltip.$id = options.id || element.attr('id') || ''; + if (options.title) { + scope.title = $sce.trustAsHtml(options.title); + } + scope.$setEnabled = function(isEnabled) { + scope.$$postDigest(function() { + $tooltip.setEnabled(isEnabled); + }); + }; + scope.$hide = function() { + scope.$$postDigest(function() { + $tooltip.hide(); + }); + }; + scope.$show = function() { + scope.$$postDigest(function() { + $tooltip.show(); + }); + }; + scope.$toggle = function() { + scope.$$postDigest(function() { + $tooltip.toggle(); + }); + }; + $tooltip.$isShown = scope.$isShown = false; + var timeout, hoverState; + var compileData, tipElement, tipContainer, tipScope; + promise.then(function(data) { + compileData = data; + $tooltip.init(); + }); + $tooltip.init = function() { + if (options.delay && angular.isNumber(options.delay)) { + options.delay = { + show: options.delay, + hide: options.delay + }; + } + if (options.container === 'self') { + tipContainer = element; + } else if (angular.isElement(options.container)) { + tipContainer = options.container; + } else if (options.container) { + tipContainer = findElement(options.container); + } + bindTriggerEvents(); + if (options.target) { + options.target = angular.isElement(options.target) ? options.target : findElement(options.target); + } + if (options.show) { + scope.$$postDigest(function() { + options.trigger === 'focus' ? element[0].focus() : $tooltip.show(); + }); + } + }; + $tooltip.destroy = function() { + unbindTriggerEvents(); + destroyTipElement(); + scope.$destroy(); + }; + $tooltip.enter = function() { + clearTimeout(timeout); + hoverState = 'in'; + if (!options.delay || !options.delay.show) { + return $tooltip.show(); + } + timeout = setTimeout(function() { + if (hoverState === 'in') $tooltip.show(); + }, options.delay.show); + }; + $tooltip.show = function() { + if (!options.bsEnabled || $tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.show.before', $tooltip); + var parent, after; + if (options.container) { + parent = tipContainer; + if (tipContainer[0].lastChild) { + after = angular.element(tipContainer[0].lastChild); + } else { + after = null; + } + } else { + parent = null; + after = element; + } + if (tipElement) destroyTipElement(); + tipScope = $tooltip.$scope.$new(); + tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {}); + tipElement.css({ + top: '-9999px', + left: '-9999px', + right: 'auto', + display: 'block', + visibility: 'hidden' + }); + if (options.animation) tipElement.addClass(options.animation); + if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type); + if (options.customClass) tipElement.addClass(options.customClass); + after ? after.after(tipElement) : parent.prepend(tipElement); + $tooltip.$isShown = scope.$isShown = true; + safeDigest(scope); + $tooltip.$applyPlacement(); + if (angular.version.minor <= 2) { + $animate.enter(tipElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(tipElement, parent, after).then(enterAnimateCallback); + } + safeDigest(scope); + $$rAF(function() { + if (tipElement) tipElement.css({ + visibility: 'visible' + }); + }); + if (options.keyboard) { + if (options.trigger !== 'focus') { + $tooltip.focus(); + } + bindKeyboardEvents(); + } + if (options.autoClose) { + bindAutoCloseEvents(); + } + }; + function enterAnimateCallback() { + scope.$emit(options.prefixEvent + '.show', $tooltip); + } + $tooltip.leave = function() { + clearTimeout(timeout); + hoverState = 'out'; + if (!options.delay || !options.delay.hide) { + return $tooltip.hide(); + } + timeout = setTimeout(function() { + if (hoverState === 'out') { + $tooltip.hide(); + } + }, options.delay.hide); + }; + var _blur; + var _tipToHide; + $tooltip.hide = function(blur) { + if (!$tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.hide.before', $tooltip); + _blur = blur; + _tipToHide = tipElement; + if (angular.version.minor <= 2) { + $animate.leave(tipElement, leaveAnimateCallback); + } else { + $animate.leave(tipElement).then(leaveAnimateCallback); + } + $tooltip.$isShown = scope.$isShown = false; + safeDigest(scope); + if (options.keyboard && tipElement !== null) { + unbindKeyboardEvents(); + } + if (options.autoClose && tipElement !== null) { + unbindAutoCloseEvents(); + } + }; + function leaveAnimateCallback() { + scope.$emit(options.prefixEvent + '.hide', $tooltip); + if (tipElement === _tipToHide) { + if (_blur && options.trigger === 'focus') { + return element[0].blur(); + } + destroyTipElement(); + } + } + $tooltip.toggle = function() { + $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter(); + }; + $tooltip.focus = function() { + tipElement[0].focus(); + }; + $tooltip.setEnabled = function(isEnabled) { + options.bsEnabled = isEnabled; + }; + $tooltip.setViewport = function(viewport) { + options.viewport = viewport; + }; + $tooltip.$applyPlacement = function() { + if (!tipElement) return; + var placement = options.placement, autoToken = /\s?auto?\s?/i, autoPlace = autoToken.test(placement); + if (autoPlace) { + placement = placement.replace(autoToken, '') || defaults.placement; + } + tipElement.addClass(options.placement); + var elementPosition = getPosition(), tipWidth = tipElement.prop('offsetWidth'), tipHeight = tipElement.prop('offsetHeight'); + $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport); + if (autoPlace) { + var originalPlacement = placement; + var viewportPosition = getPosition($tooltip.$viewport); + if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) { + placement = originalPlacement.replace('bottom', 'top'); + } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) { + placement = originalPlacement.replace('top', 'bottom'); + } + if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') && elementPosition.right + tipWidth > viewportPosition.width) { + placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right'); + } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') && elementPosition.left - tipWidth < viewportPosition.left) { + placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left'); + } + tipElement.removeClass(originalPlacement).addClass(placement); + } + var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight); + applyPlacement(tipPosition, placement); + }; + $tooltip.$onKeyUp = function(evt) { + if (evt.which === 27 && $tooltip.$isShown) { + $tooltip.hide(); + evt.stopPropagation(); + } + }; + $tooltip.$onFocusKeyUp = function(evt) { + if (evt.which === 27) { + element[0].blur(); + evt.stopPropagation(); + } + }; + $tooltip.$onFocusElementMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + $tooltip.$isShown ? element[0].blur() : element[0].focus(); + }; + function bindTriggerEvents() { + var triggers = options.trigger.split(' '); + angular.forEach(triggers, function(trigger) { + if (trigger === 'click') { + element.on('click', $tooltip.toggle); + } else if (trigger !== 'manual') { + element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + }); + } + function unbindTriggerEvents() { + var triggers = options.trigger.split(' '); + for (var i = triggers.length; i--; ) { + var trigger = triggers[i]; + if (trigger === 'click') { + element.off('click', $tooltip.toggle); + } else if (trigger !== 'manual') { + element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + } + } + function bindKeyboardEvents() { + if (options.trigger !== 'focus') { + tipElement.on('keyup', $tooltip.$onKeyUp); + } else { + element.on('keyup', $tooltip.$onFocusKeyUp); + } + } + function unbindKeyboardEvents() { + if (options.trigger !== 'focus') { + tipElement.off('keyup', $tooltip.$onKeyUp); + } else { + element.off('keyup', $tooltip.$onFocusKeyUp); + } + } + var _autoCloseEventsBinded = false; + function bindAutoCloseEvents() { + $timeout(function() { + tipElement.on('click', stopEventPropagation); + $body.on('click', $tooltip.hide); + _autoCloseEventsBinded = true; + }, 0, false); + } + function unbindAutoCloseEvents() { + if (_autoCloseEventsBinded) { + tipElement.off('click', stopEventPropagation); + $body.off('click', $tooltip.hide); + _autoCloseEventsBinded = false; + } + } + function stopEventPropagation(event) { + event.stopPropagation(); + } + function getPosition($element) { + $element = $element || (options.target || element); + var el = $element[0], isBody = el.tagName === 'BODY'; + var elRect = el.getBoundingClientRect(); + var rect = {}; + for (var p in elRect) { + rect[p] = elRect[p]; + } + if (rect.width === null) { + rect = angular.extend({}, rect, { + width: elRect.right - elRect.left, + height: elRect.bottom - elRect.top + }); + } + var elOffset = isBody ? { + top: 0, + left: 0 + } : dimensions.offset(el), scroll = { + scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 + }, outerDims = isBody ? { + width: document.documentElement.clientWidth, + height: $window.innerHeight + } : null; + return angular.extend({}, rect, scroll, outerDims, elOffset); + } + function getCalculatedOffset(placement, position, actualWidth, actualHeight) { + var offset; + var split = placement.split('-'); + switch (split[0]) { + case 'right': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left + position.width + }; + break; + + case 'bottom': + offset = { + top: position.top + position.height, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + + case 'left': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left - actualWidth + }; + break; + + default: + offset = { + top: position.top - actualHeight, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + } + if (!split[1]) { + return offset; + } + if (split[0] === 'top' || split[0] === 'bottom') { + switch (split[1]) { + case 'left': + offset.left = position.left; + break; + + case 'right': + offset.left = position.left + position.width - actualWidth; + } + } else if (split[0] === 'left' || split[0] === 'right') { + switch (split[1]) { + case 'top': + offset.top = position.top - actualHeight; + break; + + case 'bottom': + offset.top = position.top + position.height; + } + } + return offset; + } + function applyPlacement(offset, placement) { + var tip = tipElement[0], width = tip.offsetWidth, height = tip.offsetHeight; + var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10), marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10); + if (isNaN(marginTop)) marginTop = 0; + if (isNaN(marginLeft)) marginLeft = 0; + offset.top = offset.top + marginTop; + offset.left = offset.left + marginLeft; + dimensions.setOffset(tip, angular.extend({ + using: function(props) { + tipElement.css({ + top: Math.round(props.top) + 'px', + left: Math.round(props.left) + 'px', + right: '' + }); + } + }, offset), 0); + var actualWidth = tip.offsetWidth, actualHeight = tip.offsetHeight; + if (placement === 'top' && actualHeight !== height) { + offset.top = offset.top + height - actualHeight; + } + if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return; + var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight); + if (delta.left) { + offset.left += delta.left; + } else { + offset.top += delta.top; + } + dimensions.setOffset(tip, offset); + if (/top|right|bottom|left/.test(placement)) { + var isVertical = /top|bottom/.test(placement), arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight, arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'; + replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical); + } + } + function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) { + var delta = { + top: 0, + left: 0 + }; + if (!$tooltip.$viewport) return delta; + var viewportPadding = options.viewport && options.viewport.padding || 0; + var viewportDimensions = getPosition($tooltip.$viewport); + if (/right|left/.test(placement)) { + var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll; + var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight; + if (topEdgeOffset < viewportDimensions.top) { + delta.top = viewportDimensions.top - topEdgeOffset; + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset; + } + } else { + var leftEdgeOffset = position.left - viewportPadding; + var rightEdgeOffset = position.left + viewportPadding + actualWidth; + if (leftEdgeOffset < viewportDimensions.left) { + delta.left = viewportDimensions.left - leftEdgeOffset; + } else if (rightEdgeOffset > viewportDimensions.right) { + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset; + } + } + return delta; + } + function replaceArrow(delta, dimension, isHorizontal) { + var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]); + $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%').css(isHorizontal ? 'top' : 'left', ''); + } + function destroyTipElement() { + clearTimeout(timeout); + if ($tooltip.$isShown && tipElement !== null) { + if (options.autoClose) { + unbindAutoCloseEvents(); + } + if (options.keyboard) { + unbindKeyboardEvents(); + } + } + if (tipScope) { + tipScope.$destroy(); + tipScope = null; + } + if (tipElement) { + tipElement.remove(); + tipElement = $tooltip.$element = null; + } + } + return $tooltip; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + var fetchPromises = {}; + function fetchTemplate(template) { + if (fetchPromises[template]) return fetchPromises[template]; + return fetchPromises[template] = $http.get(template, { + cache: $templateCache + }).then(function(res) { + return res.data; + }); + } + return TooltipFactory; + } ]; + }).directive('bsTooltip', ["$window", "$location", "$sce", "$bsTooltip", "$$bsRAF", function($window, $location, $sce, $tooltip, $$rAF) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + var dataTarget = element.attr('data-target'); + if (angular.isDefined(dataTarget)) { + if (falseValueRegExp.test(dataTarget)) options.target = false; else options.target = dataTarget; + } + if (!scope.hasOwnProperty('title')) { + scope.title = ''; + } + attr.$observe('title', function(newValue) { + if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) { + var oldValue = scope.title; + scope.title = $sce.trustAsHtml(newValue); + angular.isDefined(oldValue) && $$rAF(function() { + tooltip && tooltip.$applyPlacement(); + }); + } + }); + attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.title = newValue; + } + angular.isDefined(oldValue) && $$rAF(function() { + tooltip && tooltip.$applyPlacement(); + }); + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i); + newValue === true ? tooltip.show() : tooltip.hide(); + }); + attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i); + newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true); + }); + attr.viewport && scope.$watch(attr.viewport, function(newValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + tooltip.setViewport(newValue); + }); + var tooltip = $tooltip(element, options); + scope.$on('$destroy', function() { + if (tooltip) tooltip.destroy(); + options = null; + tooltip = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.timepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$bsTimepicker', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'timepicker', + placement: 'bottom-left', + templateUrl: 'timepicker/timepicker.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + useNative: true, + timeType: 'date', + timeFormat: 'shortTime', + timezone: null, + modelTimeFormat: null, + autoclose: false, + minTime: -Infinity, + maxTime: +Infinity, + length: 5, + hourStep: 1, + minuteStep: 5, + secondStep: 5, + roundDisplay: false, + iconUp: 'glyphicon glyphicon-chevron-up', + iconDown: 'glyphicon glyphicon-chevron-down', + arrowBehavior: 'pager' + }; + this.$get = ["$window", "$document", "$rootScope", "$sce", "$bsDateFormatter", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) { + var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + if (!defaults.lang) { + defaults.lang = $dateFormatter.getDefaultLocale(); + } + function timepickerFactory(element, controller, config) { + var $timepicker = $tooltip(element, angular.extend({}, defaults, config)); + var parentScope = config.scope; + var options = $timepicker.$options; + var scope = $timepicker.$scope; + var lang = options.lang; + var formatDate = function(date, format, timezone) { + return $dateFormatter.formatDate(date, format, lang, timezone); + }; + function floorMinutes(time) { + var coeff = 1e3 * 60 * options.minuteStep; + return new Date(Math.floor(time.getTime() / coeff) * coeff); + } + var selectedIndex = 0; + var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date(); + var startDate = controller.$dateValue || defaultDate; + var viewDate = { + hour: startDate.getHours(), + meridian: startDate.getHours() < 12, + minute: startDate.getMinutes(), + second: startDate.getSeconds(), + millisecond: startDate.getMilliseconds() + }; + var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang); + var hoursFormat = $dateFormatter.hoursFormat(format), timeSeparator = $dateFormatter.timeSeparator(format), minutesFormat = $dateFormatter.minutesFormat(format), secondsFormat = $dateFormatter.secondsFormat(format), showSeconds = $dateFormatter.showSeconds(format), showAM = $dateFormatter.showAM(format); + scope.$iconUp = options.iconUp; + scope.$iconDown = options.iconDown; + scope.$select = function(date, index) { + $timepicker.select(date, index); + }; + scope.$moveIndex = function(value, index) { + $timepicker.$moveIndex(value, index); + }; + scope.$switchMeridian = function(date) { + $timepicker.switchMeridian(date); + }; + $timepicker.update = function(date) { + if (angular.isDate(date) && !isNaN(date.getTime())) { + $timepicker.$date = date; + angular.extend(viewDate, { + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + millisecond: date.getMilliseconds() + }); + $timepicker.$build(); + } else if (!$timepicker.$isBuilt) { + $timepicker.$build(); + } + }; + $timepicker.select = function(date, index, keep) { + if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1); + if (!angular.isDate(date)) date = new Date(date); + if (index === 0) controller.$dateValue.setHours(date.getHours()); else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes()); else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds()); + controller.$setViewValue(angular.copy(controller.$dateValue)); + controller.$render(); + if (options.autoclose && !keep) { + $timeout(function() { + $timepicker.hide(true); + }); + } + }; + $timepicker.switchMeridian = function(date) { + if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) { + return; + } + var hours = (date || controller.$dateValue).getHours(); + controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12); + controller.$setViewValue(angular.copy(controller.$dateValue)); + controller.$render(); + }; + $timepicker.$build = function() { + var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10); + var hours = [], hour; + for (i = 0; i < options.length; i++) { + hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep); + hours.push({ + date: hour, + label: formatDate(hour, hoursFormat), + selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), + disabled: $timepicker.$isDisabled(hour, 0) + }); + } + var minutes = [], minute; + for (i = 0; i < options.length; i++) { + minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep); + minutes.push({ + date: minute, + label: formatDate(minute, minutesFormat), + selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), + disabled: $timepicker.$isDisabled(minute, 1) + }); + } + var seconds = [], second; + for (i = 0; i < options.length; i++) { + second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep); + seconds.push({ + date: second, + label: formatDate(second, secondsFormat), + selected: $timepicker.$date && $timepicker.$isSelected(second, 2), + disabled: $timepicker.$isDisabled(second, 2) + }); + } + var rows = []; + for (i = 0; i < options.length; i++) { + if (showSeconds) { + rows.push([ hours[i], minutes[i], seconds[i] ]); + } else { + rows.push([ hours[i], minutes[i] ]); + } + } + scope.rows = rows; + scope.showSeconds = showSeconds; + scope.showAM = showAM; + scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12; + scope.timeSeparator = timeSeparator; + $timepicker.$isBuilt = true; + }; + $timepicker.$isSelected = function(date, index) { + if (!$timepicker.$date) return false; else if (index === 0) { + return date.getHours() === $timepicker.$date.getHours(); + } else if (index === 1) { + return date.getMinutes() === $timepicker.$date.getMinutes(); + } else if (index === 2) { + return date.getSeconds() === $timepicker.$date.getSeconds(); + } + }; + $timepicker.$isDisabled = function(date, index) { + var selectedTime; + if (index === 0) { + selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3; + } else if (index === 1) { + selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3; + } else if (index === 2) { + selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4; + } + return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1; + }; + scope.$arrowAction = function(value, index) { + if (options.arrowBehavior === 'picker') { + $timepicker.$setTimeByStep(value, index); + } else { + $timepicker.$moveIndex(value, index); + } + }; + $timepicker.$setTimeByStep = function(value, index) { + var newDate = new Date($timepicker.$date || startDate); + var hours = newDate.getHours(); + var minutes = newDate.getMinutes(); + var seconds = newDate.getSeconds(); + if (index === 0) { + newDate.setHours(hours - parseInt(options.hourStep, 10) * value); + } else if (index === 1) { + newDate.setMinutes(minutes - parseInt(options.minuteStep, 10) * value); + } else if (index === 2) { + newDate.setSeconds(seconds - parseInt(options.secondStep, 10) * value); + } + $timepicker.select(newDate, index, true); + }; + $timepicker.$moveIndex = function(value, index) { + var targetDate; + if (index === 0) { + targetDate = new Date(1970, 0, 1, viewDate.hour + value * options.length, viewDate.minute, viewDate.second); + angular.extend(viewDate, { + hour: targetDate.getHours() + }); + } else if (index === 1) { + targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + value * options.length * options.minuteStep, viewDate.second); + angular.extend(viewDate, { + minute: targetDate.getMinutes() + }); + } else if (index === 2) { + targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + value * options.length * options.secondStep); + angular.extend(viewDate, { + second: targetDate.getSeconds() + }); + } + $timepicker.$build(); + }; + $timepicker.$onMouseDown = function(evt) { + if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + if (targetEl[0].nodeName.toLowerCase() !== 'button') { + targetEl = targetEl.parent(); + } + targetEl.triggerHandler('click'); + } + }; + $timepicker.$onKeyDown = function(evt) { + if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; + evt.preventDefault(); + evt.stopPropagation(); + if (evt.keyCode === 13) { + $timepicker.hide(true); + return; + } + var newDate = new Date($timepicker.$date); + var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length; + var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length; + var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length; + var sepLength = 1; + var lateralMove = /(37|39)/.test(evt.keyCode); + var count = 2 + showSeconds * 1 + showAM * 1; + if (lateralMove) { + if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1; else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0; + } + var selectRange = [ 0, hoursLength ]; + var incr = 0; + if (evt.keyCode === 38) incr = -1; + if (evt.keyCode === 40) incr = +1; + var isSeconds = selectedIndex === 2 && showSeconds; + var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds; + if (selectedIndex === 0) { + newDate.setHours(hours + incr * parseInt(options.hourStep, 10)); + hoursLength = formatDate(newDate, hoursFormat).length; + selectRange = [ 0, hoursLength ]; + } else if (selectedIndex === 1) { + newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10)); + minutesLength = formatDate(newDate, minutesFormat).length; + selectRange = [ hoursLength + sepLength, minutesLength ]; + } else if (isSeconds) { + newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10)); + secondsLength = formatDate(newDate, secondsFormat).length; + selectRange = [ hoursLength + sepLength + minutesLength + sepLength, secondsLength ]; + } else if (isMeridian) { + if (!lateralMove) $timepicker.switchMeridian(); + selectRange = [ hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2 ]; + } + $timepicker.select(newDate, selectedIndex, true); + createSelection(selectRange[0], selectRange[1]); + parentScope.$digest(); + }; + function createSelection(start, length) { + var end = start + length; + if (element[0].createTextRange) { + var selRange = element[0].createTextRange(); + selRange.collapse(true); + selRange.moveStart('character', start); + selRange.moveEnd('character', end); + selRange.select(); + } else if (element[0].setSelectionRange) { + element[0].setSelectionRange(start, end); + } else if (angular.isUndefined(element[0].selectionStart)) { + element[0].selectionStart = start; + element[0].selectionEnd = end; + } + } + function focusElement() { + element[0].focus(); + } + var _init = $timepicker.init; + $timepicker.init = function() { + if (isNative && options.useNative) { + element.prop('type', 'time'); + element.css('-webkit-appearance', 'textfield'); + return; + } else if (isTouch) { + element.prop('type', 'text'); + element.attr('readonly', 'true'); + element.on('click', focusElement); + } + _init(); + }; + var _destroy = $timepicker.destroy; + $timepicker.destroy = function() { + if (isNative && options.useNative) { + element.off('click', focusElement); + } + _destroy(); + }; + var _show = $timepicker.show; + $timepicker.show = function() { + if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; + _show(); + $timeout(function() { + $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if (options.keyboard) { + element && element.on('keydown', $timepicker.$onKeyDown); + } + }, 0, false); + }; + var _hide = $timepicker.hide; + $timepicker.hide = function(blur) { + if (!$timepicker.$isShown) return; + $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if (options.keyboard) { + element && element.off('keydown', $timepicker.$onKeyDown); + } + _hide(blur); + }; + return $timepicker; + } + timepickerFactory.defaults = defaults; + return timepickerFactory; + } ]; + }).directive('bsTimepicker', ["$window", "$parse", "$q", "$bsDateFormatter", "$bsDateParser", "$bsTimepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) { + var defaults = $timepicker.defaults; + var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoclose', 'useNative', 'roundDisplay' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!timepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i); + newValue === true ? timepicker.show() : timepicker.hide(); + }); + if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm'; + var timepicker = $timepicker(element, controller, options); + options = timepicker.$options; + var lang = options.lang; + var formatDate = function(date, format, timezone) { + return $dateFormatter.formatDate(date, format, lang, timezone); + }; + var dateParser = $dateParser({ + format: options.timeFormat, + lang: lang + }); + angular.forEach([ 'minTime', 'maxTime' ], function(key) { + angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) { + timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue); + !isNaN(timepicker.$options[key]) && timepicker.$build(); + validateAgainstMinMaxTime(controller.$dateValue); + }); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + timepicker.update(controller.$dateValue); + }, true); + function validateAgainstMinMaxTime(parsedTime) { + if (!angular.isDate(parsedTime)) return; + var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime; + var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime; + var isValid = isMinValid && isMaxValid; + controller.$setValidity('date', isValid); + controller.$setValidity('min', isMinValid); + controller.$setValidity('max', isMaxValid); + if (!isValid) { + return; + } + controller.$dateValue = parsedTime; + } + controller.$parsers.unshift(function(viewValue) { + var date; + if (!viewValue) { + controller.$setValidity('date', true); + return null; + } + var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue); + if (!parsedTime || isNaN(parsedTime.getTime())) { + controller.$setValidity('date', false); + return undefined; + } else { + validateAgainstMinMaxTime(parsedTime); + } + if (options.timeType === 'string') { + date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true); + return formatDate(date, options.modelTimeFormat || options.timeFormat); + } + date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); + if (options.timeType === 'number') { + return date.getTime(); + } else if (options.timeType === 'unix') { + return date.getTime() / 1e3; + } else if (options.timeType === 'iso') { + return date.toISOString(); + } else { + return new Date(date); + } + }); + controller.$formatters.push(function(modelValue) { + var date; + if (angular.isUndefined(modelValue) || modelValue === null) { + date = NaN; + } else if (angular.isDate(modelValue)) { + date = modelValue; + } else if (options.timeType === 'string') { + date = dateParser.parse(modelValue, null, options.modelTimeFormat); + } else if (options.timeType === 'unix') { + date = new Date(modelValue * 1e3); + } else { + date = new Date(modelValue); + } + controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); + return getTimeFormattedString(); + }); + controller.$render = function() { + element.val(getTimeFormattedString()); + }; + function getTimeFormattedString() { + return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat); + } + scope.$on('$destroy', function() { + if (timepicker) timepicker.destroy(); + options = null; + timepicker = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.tab', []).provider('$bsTab', function() { + var defaults = this.defaults = { + animation: 'am-fade', + template: 'tab/tab.tpl.html', + navClass: 'nav-tabs', + activeClass: 'active' + }; + var controller = this.controller = function($scope, $element, $attrs) { + var self = this; + self.$options = angular.copy(defaults); + angular.forEach([ 'animation', 'navClass', 'activeClass' ], function(key) { + if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; + }); + $scope.$navClass = self.$options.navClass; + $scope.$activeClass = self.$options.activeClass; + self.$panes = $scope.$panes = []; + self.$activePaneChangeListeners = self.$viewChangeListeners = []; + self.$push = function(pane) { + if (angular.isUndefined(self.$panes.$active)) { + $scope.$setActive(pane.name || 0); + } + self.$panes.push(pane); + }; + self.$remove = function(pane) { + var index = self.$panes.indexOf(pane); + var active = self.$panes.$active; + var activeIndex; + if (angular.isString(active)) { + activeIndex = self.$panes.map(function(pane) { + return pane.name; + }).indexOf(active); + } else { + activeIndex = self.$panes.$active; + } + self.$panes.splice(index, 1); + if (index < activeIndex) { + activeIndex--; + } else if (index === activeIndex && activeIndex === self.$panes.length) { + activeIndex--; + } + if (activeIndex >= 0 && activeIndex < self.$panes.length) { + self.$setActive(self.$panes[activeIndex].name || activeIndex); + } else { + self.$setActive(); + } + }; + self.$setActive = $scope.$setActive = function(value) { + self.$panes.$active = value; + self.$activePaneChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$isActive = $scope.$isActive = function($pane, $index) { + return self.$panes.$active === $pane.name || self.$panes.$active === $index; + }; + }; + this.$get = function() { + var $tab = {}; + $tab.defaults = defaults; + $tab.controller = controller; + return $tab; + }; + }).directive('bsTabs', ["$window", "$animate", "$bsTab", "$parse", function($window, $animate, $tab, $parse) { + var defaults = $tab.defaults; + return { + require: [ '?ngModel', 'bsTabs' ], + transclude: true, + scope: true, + controller: [ '$scope', '$element', '$attrs', $tab.controller ], + templateUrl: function(element, attr) { + return attr.template || defaults.template; + }, + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsTabsCtrl = controllers[1]; + if (ngModelCtrl) { + bsTabsCtrl.$activePaneChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active); + }); + ngModelCtrl.$formatters.push(function(modelValue) { + bsTabsCtrl.$setActive(modelValue); + return modelValue; + }); + } + if (attrs.bsActivePane) { + var parsedBsActivePane = $parse(attrs.bsActivePane); + bsTabsCtrl.$activePaneChangeListeners.push(function() { + parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active); + }); + scope.$watch(attrs.bsActivePane, function(newValue, oldValue) { + bsTabsCtrl.$setActive(newValue); + }, true); + } + } + }; + } ]).directive('bsPane', ["$window", "$animate", "$sce", function($window, $animate, $sce) { + return { + require: [ '^?ngModel', '^bsTabs' ], + scope: true, + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsTabsCtrl = controllers[1]; + element.addClass('tab-pane'); + attrs.$observe('title', function(newValue, oldValue) { + scope.title = $sce.trustAsHtml(newValue); + }); + scope.name = attrs.name; + if (bsTabsCtrl.$options.animation) { + element.addClass(bsTabsCtrl.$options.animation); + } + attrs.$observe('disabled', function(newValue, oldValue) { + scope.disabled = scope.$eval(newValue); + }); + bsTabsCtrl.$push(scope); + scope.$on('$destroy', function() { + bsTabsCtrl.$remove(scope); + }); + function render() { + var index = bsTabsCtrl.$panes.indexOf(scope); + $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass); + } + bsTabsCtrl.$activePaneChangeListeners.push(function() { + render(); + }); + render(); + } + }; + } ]); + angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$bsSelect', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'select', + prefixEvent: '$select', + placement: 'bottom-left', + templateUrl: 'select/select.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + multiple: false, + allNoneButtons: false, + sort: true, + caretHtml: ' ', + placeholder: 'Choose among the following...', + allText: 'All', + noneText: 'None', + maxLength: 3, + maxLengthHtml: 'selected', + iconCheckmark: 'glyphicon glyphicon-ok' + }; + this.$get = ["$window", "$document", "$rootScope", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $tooltip, $timeout) { + var bodyEl = angular.element($window.document.body); + var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + function SelectFactory(element, controller, config) { + var $select = {}; + var options = angular.extend({}, defaults, config); + $select = $tooltip(element, options); + var scope = $select.$scope; + scope.$matches = []; + if (options.multiple) { + scope.$activeIndex = []; + } else { + scope.$activeIndex = -1; + } + scope.$isMultiple = options.multiple; + scope.$showAllNoneButtons = options.allNoneButtons && options.multiple; + scope.$iconCheckmark = options.iconCheckmark; + scope.$allText = options.allText; + scope.$noneText = options.noneText; + scope.$activate = function(index) { + scope.$$postDigest(function() { + $select.activate(index); + }); + }; + scope.$select = function(index, evt) { + scope.$$postDigest(function() { + $select.select(index); + }); + }; + scope.$isVisible = function() { + return $select.$isVisible(); + }; + scope.$isActive = function(index) { + return $select.$isActive(index); + }; + scope.$selectAll = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (!scope.$isActive(i)) { + scope.$select(i); + } + } + }; + scope.$selectNone = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (scope.$isActive(i)) { + scope.$select(i); + } + } + }; + $select.update = function(matches) { + scope.$matches = matches; + $select.$updateActiveIndex(); + }; + $select.activate = function(index) { + if (options.multiple) { + $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index); + if (options.sort) scope.$activeIndex.sort(function(a, b) { + return a - b; + }); + } else { + scope.$activeIndex = index; + } + return scope.$activeIndex; + }; + $select.select = function(index) { + var value = scope.$matches[index].value; + scope.$apply(function() { + $select.activate(index); + if (options.multiple) { + controller.$setViewValue(scope.$activeIndex.map(function(index) { + if (angular.isUndefined(scope.$matches[index])) { + return null; + } + return scope.$matches[index].value; + })); + } else { + controller.$setViewValue(value); + $select.hide(); + } + }); + scope.$emit(options.prefixEvent + '.select', value, index, $select); + }; + $select.$updateActiveIndex = function() { + if (controller.$modelValue && scope.$matches.length) { + if (options.multiple && angular.isArray(controller.$modelValue)) { + scope.$activeIndex = controller.$modelValue.map(function(value) { + return $select.$getIndex(value); + }); + } else { + scope.$activeIndex = $select.$getIndex(controller.$modelValue); + } + } else if (scope.$activeIndex >= scope.$matches.length) { + scope.$activeIndex = options.multiple ? [] : 0; + } else if (!controller.$modelValue && !options.multiple) { + scope.$activeIndex = -1; + } + }; + $select.$isVisible = function() { + if (!options.minLength || !controller) { + return scope.$matches.length; + } + return scope.$matches.length && controller.$viewValue.length >= options.minLength; + }; + $select.$isActive = function(index) { + if (options.multiple) { + return scope.$activeIndex.indexOf(index) !== -1; + } else { + return scope.$activeIndex === index; + } + }; + $select.$getIndex = function(value) { + var l = scope.$matches.length, i = l; + if (!l) return; + for (i = l; i--; ) { + if (scope.$matches[i].value === value) break; + } + if (i < 0) return; + return i; + }; + $select.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + targetEl.triggerHandler('click'); + } + }; + $select.$onKeyDown = function(evt) { + if (!/(9|13|38|40)/.test(evt.keyCode)) return; + if (evt.keyCode !== 9) { + evt.preventDefault(); + evt.stopPropagation(); + } + if (options.multiple && evt.keyCode === 9) { + return $select.hide(); + } + if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) { + return $select.select(scope.$activeIndex); + } + if (!options.multiple) { + if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; + scope.$digest(); + } + }; + $select.$isIE = function() { + var ua = $window.navigator.userAgent; + return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0; + }; + $select.$selectScrollFix = function(e) { + if ($document[0].activeElement.tagName === 'UL') { + e.preventDefault(); + e.stopImmediatePropagation(); + e.target.focus(); + } + }; + var _show = $select.show; + $select.show = function() { + _show(); + if (options.multiple) { + $select.$element.addClass('select-multiple'); + } + $timeout(function() { + $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); + if (options.keyboard) { + element.on('keydown', $select.$onKeyDown); + } + }, 0, false); + }; + var _hide = $select.hide; + $select.hide = function() { + if (!options.multiple && !controller.$modelValue) { + scope.$activeIndex = -1; + } + $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $select.$onKeyDown); + } + _hide(true); + }; + return $select; + } + SelectFactory.defaults = defaults; + return SelectFactory; + } ]; + }).directive('bsSelect', ["$window", "$parse", "$q", "$bsSelect", "$bsParseOptions", function($window, $parse, $q, $select, $parseOptions) { + var defaults = $select.defaults; + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope, + placeholder: defaults.placeholder + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'allNoneButtons', 'sort' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + var dataMultiple = element.attr('data-multiple'); + if (angular.isDefined(dataMultiple)) { + if (falseValueRegExp.test(dataMultiple)) options.multiple = false; else options.multiple = dataMultiple; + } + if (element[0].nodeName.toLowerCase() === 'select') { + var inputEl = element; + inputEl.css('display', 'none'); + element = angular.element(''); + inputEl.after(element); + } + var parsedOptions = $parseOptions(attr.bsOptions); + var select = $select(element, controller, options); + if (select.$isIE()) { + element[0].addEventListener('blur', select.$selectScrollFix); + } + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').trim(); + scope.$watchCollection(watchedOptions, function(newValue, oldValue) { + parsedOptions.valuesFn(scope, controller).then(function(values) { + select.update(values); + controller.$render(); + }); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + select.$updateActiveIndex(); + controller.$render(); + }, true); + controller.$render = function() { + var selected, index; + if (options.multiple && angular.isArray(controller.$modelValue)) { + selected = controller.$modelValue.map(function(value) { + index = select.$getIndex(value); + return angular.isDefined(index) ? select.$scope.$matches[index].label : false; + }).filter(angular.isDefined); + if (selected.length > (options.maxLength || defaults.maxLength)) { + selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml); + } else { + selected = selected.join(', '); + } + } else { + index = select.$getIndex(controller.$modelValue); + selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false; + } + element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml)); + }; + if (options.multiple) { + controller.$isEmpty = function(value) { + return !value || value.length === 0; + }; + } + scope.$on('$destroy', function() { + if (select) select.destroy(); + options = null; + select = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsScrollspy', function() { + var spies = this.$$spies = {}; + var defaults = this.defaults = { + debounce: 150, + throttle: 100, + offset: 100 + }; + this.$get = ["$window", "$document", "$rootScope", "bsDimensions", "bsDebounce", "bsThrottle", function($window, $document, $rootScope, dimensions, debounce, throttle) { + var windowEl = angular.element($window); + var docEl = angular.element($document.prop('documentElement')); + var bodyEl = angular.element($window.document.body); + function nodeName(element, name) { + return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); + } + function ScrollSpyFactory(config) { + var options = angular.extend({}, defaults, config); + if (!options.element) options.element = bodyEl; + var isWindowSpy = nodeName(options.element, 'body'); + var scrollEl = isWindowSpy ? windowEl : options.element; + var scrollId = isWindowSpy ? 'window' : options.id; + if (spies[scrollId]) { + spies[scrollId].$$count++; + return spies[scrollId]; + } + var $scrollspy = {}; + var unbindViewContentLoaded, unbindIncludeContentLoaded; + var trackedElements = $scrollspy.$trackedElements = []; + var sortedElements = []; + var activeTarget; + var debouncedCheckPosition; + var throttledCheckPosition; + var debouncedCheckOffsets; + var viewportHeight; + var scrollTop; + $scrollspy.init = function() { + this.$$count = 1; + debouncedCheckPosition = debounce(this.checkPosition, options.debounce); + throttledCheckPosition = throttle(this.checkPosition, options.throttle); + scrollEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', debouncedCheckPosition); + scrollEl.on('scroll', throttledCheckPosition); + debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); + unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); + unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); + debouncedCheckOffsets(); + if (scrollId) { + spies[scrollId] = $scrollspy; + } + }; + $scrollspy.destroy = function() { + this.$$count--; + if (this.$$count > 0) { + return; + } + scrollEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', debouncedCheckPosition); + scrollEl.off('scroll', throttledCheckPosition); + unbindViewContentLoaded(); + unbindIncludeContentLoaded(); + if (scrollId) { + delete spies[scrollId]; + } + }; + $scrollspy.checkPosition = function() { + if (!sortedElements.length) return; + scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; + viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); + if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { + return $scrollspy.$activateElement(sortedElements[0]); + } + for (var i = sortedElements.length; i--; ) { + if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; + if (activeTarget === sortedElements[i].target) continue; + if (scrollTop < sortedElements[i].offsetTop) continue; + if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; + return $scrollspy.$activateElement(sortedElements[i]); + } + }; + $scrollspy.checkPositionWithEventLoop = function() { + setTimeout($scrollspy.checkPosition, 1); + }; + $scrollspy.$activateElement = function(element) { + if (activeTarget) { + var activeElement = $scrollspy.$getTrackedElement(activeTarget); + if (activeElement) { + activeElement.source.removeClass('active'); + if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { + activeElement.source.parent().parent().removeClass('active'); + } + } + } + activeTarget = element.target; + element.source.addClass('active'); + if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { + element.source.parent().parent().addClass('active'); + } + }; + $scrollspy.$getTrackedElement = function(target) { + return trackedElements.filter(function(obj) { + return obj.target === target; + })[0]; + }; + $scrollspy.checkOffsets = function() { + angular.forEach(trackedElements, function(trackedElement) { + var targetElement = document.querySelector(trackedElement.target); + trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; + if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; + }); + sortedElements = trackedElements.filter(function(el) { + return el.offsetTop !== null; + }).sort(function(a, b) { + return a.offsetTop - b.offsetTop; + }); + debouncedCheckPosition(); + }; + $scrollspy.trackElement = function(target, source) { + trackedElements.push({ + target: target, + source: source + }); + }; + $scrollspy.untrackElement = function(target, source) { + var toDelete; + for (var i = trackedElements.length; i--; ) { + if (trackedElements[i].target === target && trackedElements[i].source === source) { + toDelete = i; + break; + } + } + trackedElements = trackedElements.splice(toDelete, 1); + }; + $scrollspy.activate = function(i) { + trackedElements[i].addClass('active'); + }; + $scrollspy.init(); + return $scrollspy; + } + return ScrollSpyFactory; + } ]; + }).directive('bsScrollspy', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'EAC', + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'offset', 'target' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var scrollspy = $scrollspy(options); + scrollspy.trackElement(options.target, element); + scope.$on('$destroy', function() { + if (scrollspy) { + scrollspy.untrackElement(options.target, element); + scrollspy.destroy(); + } + options = null; + scrollspy = null; + }); + } + }; + } ]).directive('bsScrollspyList', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'A', + compile: function postLink(element, attr) { + var children = element[0].querySelectorAll('li > a[href]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$bsPopover', function() { + var defaults = this.defaults = { + animation: 'am-fade', + customClass: '', + container: false, + target: false, + placement: 'right', + templateUrl: 'popover/popover.tpl.html', + contentTemplate: false, + trigger: 'click', + keyboard: true, + html: false, + title: '', + content: '', + delay: 0, + autoClose: false + }; + this.$get = ["$bsTooltip", function($tooltip) { + function PopoverFactory(element, config) { + var options = angular.extend({}, defaults, config); + var $popover = $tooltip(element, options); + if (options.content) { + $popover.$scope.content = options.content; + } + return $popover; + } + return PopoverFactory; + } ]; + }).directive('bsPopover', ["$window", "$sce", "$bsPopover", function($window, $sce, $popover) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoClose' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + var dataTarget = element.attr('data-target'); + if (angular.isDefined(dataTarget)) { + if (falseValueRegExp.test(dataTarget)) options.target = false; else options.target = dataTarget; + } + angular.forEach([ 'title', 'content' ], function(key) { + attr[key] && attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + angular.isDefined(oldValue) && requestAnimationFrame(function() { + popover && popover.$applyPlacement(); + }); + }); + }); + attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + angular.isDefined(oldValue) && requestAnimationFrame(function() { + popover && popover.$applyPlacement(); + }); + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!popover || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i); + newValue === true ? popover.show() : popover.hide(); + }); + attr.viewport && scope.$watch(attr.viewport, function(newValue) { + if (!popover || !angular.isDefined(newValue)) return; + popover.setViewport(newValue); + }); + var popover = $popover(element, options); + scope.$on('$destroy', function() { + if (popover) popover.destroy(); + options = null; + popover = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.navbar', []).provider('$bsNavbar', function() { + var defaults = this.defaults = { + activeClass: 'active', + routeAttr: 'data-match-route', + strict: false + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsNavbar', ["$window", "$location", "$bsNavbar", function($window, $location, $navbar) { + var defaults = $navbar.defaults; + return { + restrict: 'A', + link: function postLink(scope, element, attr, controller) { + var options = angular.copy(defaults); + angular.forEach(Object.keys(defaults), function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + scope.$watch(function() { + return $location.path(); + }, function(newValue, oldValue) { + var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']'); + angular.forEach(liElements, function(li) { + var liElement = angular.element(li); + var pattern = liElement.attr(options.routeAttr).replace('/', '\\/'); + if (options.strict) { + pattern = '^' + pattern + '$'; + } + var regexp = new RegExp(pattern, 'i'); + if (regexp.test(newValue)) { + liElement.addClass(options.activeClass); + } else { + liElement.removeClass(options.activeClass); + } + }); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsModal', function() { + var defaults = this.defaults = { + animation: 'am-fade', + backdropAnimation: 'am-fade', + prefixClass: 'modal', + prefixEvent: 'modal', + placement: 'top', + templateUrl: 'modal/modal.tpl.html', + template: '', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true + }; + this.$get = ["$window", "$rootScope", "$bsCompiler", "$animate", "$timeout", "$sce", "bsDimensions", function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) { + var forEach = angular.forEach; + var trim = String.prototype.trim; + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + var bodyElement = angular.element($window.document.body); + function ModalFactory(config) { + var $modal = {}; + var options = $modal.$options = angular.extend({}, defaults, config); + var promise = $modal.$promise = $bsCompiler.compile(options); + var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + if (!options.element && !options.container) { + options.container = 'body'; + } + $modal.$id = options.id || options.element && options.element.attr('id') || ''; + forEach([ 'title', 'content' ], function(key) { + if (options[key]) scope[key] = $sce.trustAsHtml(options[key]); + }); + scope.$hide = function() { + scope.$$postDigest(function() { + $modal.hide(); + }); + }; + scope.$show = function() { + scope.$$postDigest(function() { + $modal.show(); + }); + }; + scope.$toggle = function() { + scope.$$postDigest(function() { + $modal.toggle(); + }); + }; + $modal.$isShown = scope.$isShown = false; + var compileData, modalElement, modalScope; + var backdropElement = angular.element('
'); + backdropElement.css({ + position: 'fixed', + top: '0px', + left: '0px', + bottom: '0px', + right: '0px', + 'z-index': 1038 + }); + promise.then(function(data) { + compileData = data; + $modal.init(); + }); + $modal.init = function() { + if (options.show) { + scope.$$postDigest(function() { + $modal.show(); + }); + } + }; + $modal.destroy = function() { + destroyModalElement(); + if (backdropElement) { + backdropElement.remove(); + backdropElement = null; + } + scope.$destroy(); + }; + $modal.show = function() { + if ($modal.$isShown) return; + var parent, after; + if (angular.isElement(options.container)) { + parent = options.container; + after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null; + } else { + if (options.container) { + parent = findElement(options.container); + after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null; + } else { + parent = null; + after = options.element; + } + } + if (modalElement) destroyModalElement(); + modalScope = $modal.$scope.$new(); + modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {}); + if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) { + return; + } + modalElement.css({ + display: 'block' + }).addClass(options.placement); + if (options.animation) { + if (options.backdrop) { + backdropElement.addClass(options.backdropAnimation); + } + modalElement.addClass(options.animation); + } + if (options.backdrop) { + $animate.enter(backdropElement, bodyElement, null); + } + if (angular.version.minor <= 2) { + $animate.enter(modalElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + } + $modal.$isShown = scope.$isShown = true; + safeDigest(scope); + var el = modalElement[0]; + requestAnimationFrame(function() { + el.focus(); + }); + bodyElement.addClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.addClass(options.prefixClass + '-with-' + options.animation); + } + bindBackdropEvents(); + bindKeyboardEvents(); + }; + function enterAnimateCallback() { + scope.$emit(options.prefixEvent + '.show', $modal); + } + $modal.hide = function() { + if (!$modal.$isShown) return; + if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { + return; + } + if (angular.version.minor <= 2) { + $animate.leave(modalElement, leaveAnimateCallback); + } else { + $animate.leave(modalElement).then(leaveAnimateCallback); + } + if (options.backdrop) { + $animate.leave(backdropElement); + } + $modal.$isShown = scope.$isShown = false; + safeDigest(scope); + unbindBackdropEvents(); + unbindKeyboardEvents(); + }; + function leaveAnimateCallback() { + scope.$emit(options.prefixEvent + '.hide', $modal); + bodyElement.removeClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.removeClass(options.prefixClass + '-with-' + options.animation); + } + } + $modal.toggle = function() { + $modal.$isShown ? $modal.hide() : $modal.show(); + }; + $modal.focus = function() { + modalElement[0].focus(); + }; + $modal.$onKeyUp = function(evt) { + if (evt.which === 27 && $modal.$isShown) { + $modal.hide(); + evt.stopPropagation(); + } + }; + function bindBackdropEvents() { + if (options.backdrop) { + modalElement.on('click', hideOnBackdropClick); + backdropElement.on('click', hideOnBackdropClick); + backdropElement.on('wheel', preventEventDefault); + } + } + function unbindBackdropEvents() { + if (options.backdrop) { + modalElement.off('click', hideOnBackdropClick); + backdropElement.off('click', hideOnBackdropClick); + backdropElement.off('wheel', preventEventDefault); + } + } + function bindKeyboardEvents() { + if (options.keyboard) { + modalElement.on('keyup', $modal.$onKeyUp); + } + } + function unbindKeyboardEvents() { + if (options.keyboard) { + modalElement.off('keyup', $modal.$onKeyUp); + } + } + function hideOnBackdropClick(evt) { + if (evt.target !== evt.currentTarget) return; + options.backdrop === 'static' ? $modal.focus() : $modal.hide(); + } + function preventEventDefault(evt) { + evt.preventDefault(); + } + function destroyModalElement() { + if ($modal.$isShown && modalElement !== null) { + unbindBackdropEvents(); + unbindKeyboardEvents(); + } + if (modalScope) { + modalScope.$destroy(); + modalScope = null; + } + if (modalElement) { + modalElement.remove(); + modalElement = $modal.$element = null; + } + } + return $modal; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + return ModalFactory; + } ]; + }).directive('bsModal', ["$window", "$sce", "$bsModal", function($window, $sce, $modal) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'title', 'content' ], function(key) { + attr[key] && attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + }); + attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + var modal = $modal(options); + element.on(attr.trigger || 'click', modal.toggle); + scope.$on('$destroy', function() { + if (modal) modal.destroy(); + options = null; + modal = null; + }); + } + }; + } ]); + angular.version.minor < 3 && angular.version.dot < 14 && angular.module('ng').factory('$$bsRAF', ["$window", "$timeout", function($window, $timeout) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; + var cancelAnimationFrame = $window.cancelAnimationFrame || $window.webkitCancelAnimationFrame || $window.mozCancelAnimationFrame || $window.webkitCancelRequestAnimationFrame; + var rafSupported = !!requestAnimationFrame; + var raf = rafSupported ? function(fn) { + var id = requestAnimationFrame(fn); + return function() { + cancelAnimationFrame(id); + }; + } : function(fn) { + var timer = $timeout(fn, 16.66, false); + return function() { + $timeout.cancel(timer); + }; + }; + raf.supported = rafSupported; + return raf; + } ]); + angular.module('mgcrea.ngStrap.helpers.parseOptions', []).provider('$bsParseOptions', function() { + var defaults = this.defaults = { + regexp: /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/ + }; + this.$get = ["$parse", "$q", function($parse, $q) { + function ParseOptionsFactory(attr, config) { + var $parseOptions = {}; + var options = angular.extend({}, defaults, config); + $parseOptions.$values = []; + var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn; + $parseOptions.init = function() { + $parseOptions.$match = match = attr.match(options.regexp); + displayFn = $parse(match[2] || match[1]), valueName = match[4] || match[6], keyName = match[5], + groupByFn = $parse(match[3] || ''), valueFn = $parse(match[2] ? match[1] : valueName), + valuesFn = $parse(match[7]); + }; + $parseOptions.valuesFn = function(scope, controller) { + return $q.when(valuesFn(scope, controller)).then(function(values) { + if (!angular.isArray(values)) { + values = []; + } + $parseOptions.$values = values.length ? parseValues(values, scope) : []; + return $parseOptions.$values; + }); + }; + $parseOptions.displayValue = function(modelValue) { + var scope = {}; + scope[valueName] = modelValue; + return displayFn(scope); + }; + function parseValues(values, scope) { + return values.map(function(match, index) { + var locals = {}, label, value; + locals[valueName] = match; + label = displayFn(scope, locals); + value = valueFn(scope, locals); + return { + label: label, + value: value, + index: index + }; + }); + } + $parseOptions.init(); + return $parseOptions; + } + return ParseOptionsFactory; + } ]; + }); + angular.module('mgcrea.ngStrap.helpers.dimensions', []).factory('bsDimensions', ["$document", "$window", function($document, $window) { + var jqLite = angular.element; + var fn = {}; + var nodeName = fn.nodeName = function(element, name) { + return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase(); + }; + fn.css = function(element, prop, extra) { + var value; + if (element.currentStyle) { + value = element.currentStyle[prop]; + } else if (window.getComputedStyle) { + value = window.getComputedStyle(element)[prop]; + } else { + value = element.style[prop]; + } + return extra === true ? parseFloat(value) || 0 : value; + }; + fn.offset = function(element) { + var boxRect = element.getBoundingClientRect(); + var docElement = element.ownerDocument; + return { + width: boxRect.width || element.offsetWidth, + height: boxRect.height || element.offsetHeight, + top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0), + left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0) + }; + }; + fn.setOffset = function(element, options, i) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = fn.css(element, 'position'), curElem = angular.element(element), props = {}; + if (position === 'static') { + element.style.position = 'relative'; + } + curOffset = fn.offset(element); + curCSSTop = fn.css(element, 'top'); + curCSSLeft = fn.css(element, 'left'); + calculatePosition = (position === 'absolute' || position === 'fixed') && (curCSSTop + curCSSLeft).indexOf('auto') > -1; + if (calculatePosition) { + curPosition = fn.position(element); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat(curCSSTop) || 0; + curLeft = parseFloat(curCSSLeft) || 0; + } + if (angular.isFunction(options)) { + options = options.call(element, i, curOffset); + } + if (options.top !== null) { + props.top = options.top - curOffset.top + curTop; + } + if (options.left !== null) { + props.left = options.left - curOffset.left + curLeft; + } + if ('using' in options) { + options.using.call(curElem, props); + } else { + curElem.css({ + top: props.top + 'px', + left: props.left + 'px' + }); + } + }; + fn.position = function(element) { + var offsetParentRect = { + top: 0, + left: 0 + }, offsetParentElement, offset; + if (fn.css(element, 'position') === 'fixed') { + offset = element.getBoundingClientRect(); + } else { + offsetParentElement = offsetParent(element); + offset = fn.offset(element); + if (!nodeName(offsetParentElement, 'html')) { + offsetParentRect = fn.offset(offsetParentElement); + } + offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true); + offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true); + } + return { + width: element.offsetWidth, + height: element.offsetHeight, + top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true), + left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true) + }; + }; + var offsetParent = function offsetParentElement(element) { + var docElement = element.ownerDocument; + var offsetParent = element.offsetParent || docElement; + if (nodeName(offsetParent, '#document')) return docElement.documentElement; + while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElement.documentElement; + }; + fn.height = function(element, outer) { + var value = element.offsetHeight; + if (outer) { + value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true); + } else { + value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true); + } + return value; + }; + fn.width = function(element, outer) { + var value = element.offsetWidth; + if (outer) { + value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true); + } else { + value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true); + } + return value; + }; + return fn; + } ]); + angular.module('mgcrea.ngStrap.helpers.debounce', []).factory('bsDebounce', ["$timeout", function($timeout) { + return function(func, wait, immediate) { + var timeout = null; + return function() { + var context = this, args = arguments, callNow = immediate && !timeout; + if (timeout) { + $timeout.cancel(timeout); + } + timeout = $timeout(function later() { + timeout = null; + if (!immediate) { + func.apply(context, args); + } + }, wait, false); + if (callNow) { + func.apply(context, args); + } + return timeout; + }; + }; + } ]).factory('bsThrottle', ["$timeout", function($timeout) { + return function(func, wait, options) { + var timeout = null; + options || (options = {}); + return function() { + var context = this, args = arguments; + if (!timeout) { + if (options.leading !== false) { + func.apply(context, args); + } + timeout = $timeout(function later() { + timeout = null; + if (options.trailing !== false) { + func.apply(context, args); + } + }, wait, false); + } + }; + }; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateParser', []).provider('$bsDateParser', ["$localeProvider", function($localeProvider) { + function ParseDate() { + this.year = 1970; + this.month = 0; + this.day = 1; + this.hours = 0; + this.minutes = 0; + this.seconds = 0; + this.milliseconds = 0; + } + ParseDate.prototype.setMilliseconds = function(value) { + this.milliseconds = value; + }; + ParseDate.prototype.setSeconds = function(value) { + this.seconds = value; + }; + ParseDate.prototype.setMinutes = function(value) { + this.minutes = value; + }; + ParseDate.prototype.setHours = function(value) { + this.hours = value; + }; + ParseDate.prototype.getHours = function() { + return this.hours; + }; + ParseDate.prototype.setDate = function(value) { + this.day = value; + }; + ParseDate.prototype.setMonth = function(value) { + this.month = value; + }; + ParseDate.prototype.setFullYear = function(value) { + this.year = value; + }; + ParseDate.prototype.fromDate = function(value) { + this.year = value.getFullYear(); + this.month = value.getMonth(); + this.day = value.getDate(); + this.hours = value.getHours(); + this.minutes = value.getMinutes(); + this.seconds = value.getSeconds(); + this.milliseconds = value.getMilliseconds(); + return this; + }; + ParseDate.prototype.toDate = function() { + return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds); + }; + var proto = ParseDate.prototype; + function noop() {} + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + function indexOfCaseInsensitive(array, value) { + var len = array.length, str = value.toString().toLowerCase(); + for (var i = 0; i < len; i++) { + if (array[i].toLowerCase() === str) { + return i; + } + } + return -1; + } + var defaults = this.defaults = { + format: 'shortDate', + strict: false + }; + this.$get = ["$locale", "dateFilter", function($locale, dateFilter) { + var DateParserFactory = function(config) { + var options = angular.extend({}, defaults, config); + var $dateParser = {}; + var regExpMap = { + sss: '[0-9]{3}', + ss: '[0-5][0-9]', + s: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + mm: '[0-5][0-9]', + m: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + HH: '[01][0-9]|2[0-3]', + H: options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]', + hh: '[0][1-9]|[1][012]', + h: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + a: 'AM|PM', + EEEE: $locale.DATETIME_FORMATS.DAY.join('|'), + EEE: $locale.DATETIME_FORMATS.SHORTDAY.join('|'), + dd: '0[1-9]|[12][0-9]|3[01]', + d: options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]', + MMMM: $locale.DATETIME_FORMATS.MONTH.join('|'), + MMM: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'), + MM: '0[1-9]|1[012]', + M: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + yyyy: '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}', + yy: '[0-9]{2}', + y: options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}' + }; + var setFnMap = { + sss: proto.setMilliseconds, + ss: proto.setSeconds, + s: proto.setSeconds, + mm: proto.setMinutes, + m: proto.setMinutes, + HH: proto.setHours, + H: proto.setHours, + hh: proto.setHours, + h: proto.setHours, + EEEE: noop, + EEE: noop, + dd: proto.setDate, + d: proto.setDate, + a: function(value) { + var hours = this.getHours() % 12; + return this.setHours(value.match(/pm/i) ? hours + 12 : hours); + }, + MMMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); + }, + MMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); + }, + MM: function(value) { + return this.setMonth(1 * value - 1); + }, + M: function(value) { + return this.setMonth(1 * value - 1); + }, + yyyy: proto.setFullYear, + yy: function(value) { + return this.setFullYear(2e3 + 1 * value); + }, + y: function(value) { + return 1 * value <= 50 && value.length === 2 ? this.setFullYear(2e3 + 1 * value) : this.setFullYear(1 * value); + } + }; + var regex, setMap; + $dateParser.init = function() { + $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format; + regex = regExpForFormat($dateParser.$format); + setMap = setMapForFormat($dateParser.$format); + }; + $dateParser.isValid = function(date) { + if (angular.isDate(date)) return !isNaN(date.getTime()); + return regex.test(date); + }; + $dateParser.parse = function(value, baseDate, format, timezone) { + if (format) format = $locale.DATETIME_FORMATS[format] || format; + if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone); + var formatRegex = format ? regExpForFormat(format) : regex; + var formatSetMap = format ? setMapForFormat(format) : setMap; + var matches = formatRegex.exec(value); + if (!matches) return false; + var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0)); + for (var i = 0; i < matches.length - 1; i++) { + formatSetMap[i] && formatSetMap[i].call(date, matches[i + 1]); + } + var newDate = date.toDate(); + if (parseInt(date.day, 10) !== newDate.getDate()) { + return false; + } + return newDate; + }; + $dateParser.getDateForAttribute = function(key, value) { + var date; + if (value === 'today') { + var today = new Date(); + date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, key === 'minDate' ? 0 : -1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + date = new Date(value.substr(1, value.length - 2)); + } else if (isNumeric(value)) { + date = new Date(parseInt(value, 10)); + } else if (angular.isString(value) && 0 === value.length) { + date = key === 'minDate' ? -Infinity : +Infinity; + } else { + date = new Date(value); + } + return date; + }; + $dateParser.getTimeForAttribute = function(key, value) { + var time; + if (value === 'now') { + time = new Date().setFullYear(1970, 0, 1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1); + } else if (isNumeric(value)) { + time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1); + } else if (angular.isString(value) && 0 === value.length) { + time = key === 'minTime' ? -Infinity : +Infinity; + } else { + time = $dateParser.parse(value, new Date(1970, 0, 1, 0)); + } + return time; + }; + $dateParser.daylightSavingAdjust = function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }; + $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) { + if (!date) { + return null; + } + if (timezone && timezone === 'UTC') { + date = new Date(date.getTime()); + date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset()); + } + return date; + }; + function setMapForFormat(format) { + var keys = Object.keys(setFnMap), i; + var map = [], sortedMap = []; + var clonedFormat = format; + for (i = 0; i < keys.length; i++) { + if (format.split(keys[i]).length > 1) { + var index = clonedFormat.search(keys[i]); + format = format.split(keys[i]).join(''); + if (setFnMap[keys[i]]) { + map[index] = setFnMap[keys[i]]; + } + } + } + angular.forEach(map, function(v) { + if (v) sortedMap.push(v); + }); + return sortedMap; + } + function escapeReservedSymbols(text) { + return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]'); + } + function regExpForFormat(format) { + var keys = Object.keys(regExpMap), i; + var re = format; + for (i = 0; i < keys.length; i++) { + re = re.split(keys[i]).join('${' + i + '}'); + } + for (i = 0; i < keys.length; i++) { + re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')'); + } + format = escapeReservedSymbols(format); + return new RegExp('^' + re + '$', [ 'i' ]); + } + $dateParser.init(); + return $dateParser; + }; + return DateParserFactory; + } ]; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateFormatter', []).service('$bsDateFormatter', ["$locale", "dateFilter", function($locale, dateFilter) { + this.getDefaultLocale = function() { + return $locale.id; + }; + this.getDatetimeFormat = function(format, lang) { + return $locale.DATETIME_FORMATS[format] || format; + }; + this.weekdaysShort = function(lang) { + return $locale.DATETIME_FORMATS.SHORTDAY; + }; + function splitTimeFormat(format) { + return /(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(format).slice(1); + } + this.hoursFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[0]; + }; + this.minutesFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[2]; + }; + this.secondsFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[4]; + }; + this.timeSeparator = function(timeFormat) { + return splitTimeFormat(timeFormat)[1]; + }; + this.showSeconds = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[4]; + }; + this.showAM = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[5]; + }; + this.formatDate = function(date, format, lang, timezone) { + return dateFilter(date, format, timezone); + }; + } ]); + angular.module('mgcrea.ngStrap.core', []).service('$bsCompiler', bsCompilerService); + function bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) { + this.compile = function(options) { + if (options.template && /\.html$/.test(options.template)) { + console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'); + options.templateUrl = options.template; + options.template = ''; + } + var templateUrl = options.templateUrl; + var template = options.template || ''; + var controller = options.controller; + var controllerAs = options.controllerAs; + var resolve = angular.copy(options.resolve || {}); + var locals = angular.copy(options.locals || {}); + var transformTemplate = options.transformTemplate || angular.identity; + var bindToController = options.bindToController; + angular.forEach(resolve, function(value, key) { + if (angular.isString(value)) { + resolve[key] = $injector.get(value); + } else { + resolve[key] = $injector.invoke(value); + } + }); + angular.extend(resolve, locals); + if (templateUrl) { + resolve.$template = fetchTemplate(templateUrl); + } else { + resolve.$template = $q.when(template); + } + if (options.contentTemplate) { + resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { + var templateEl = angular.element(templates[0]); + var contentEl = findElement('[ng-bind="content"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); + if (!options.templateUrl) contentEl.next().remove(); + return templateEl[0].outerHTML; + }); + } + return $q.all(resolve).then(function(locals) { + var template = transformTemplate(locals.$template); + if (options.html) { + template = template.replace(/ng-bind="/gi, 'ng-bind-html="'); + } + var element = angular.element('
').html(template.trim()).contents(); + var linkFn = $compile(element); + return { + locals: locals, + element: element, + link: function link(scope) { + locals.$scope = scope; + if (controller) { + var invokeCtrl = $controller(controller, locals, true); + if (bindToController) { + angular.extend(invokeCtrl.instance, locals); + } + var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl(); + element.data('$ngControllerController', ctrl); + element.children().data('$ngControllerController', ctrl); + if (controllerAs) { + scope[controllerAs] = ctrl; + } + } + return linkFn.apply(null, arguments); + } + }; + }); + }; + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + var fetchPromises = {}; + function fetchTemplate(template) { + if (fetchPromises[template]) return fetchPromises[template]; + return fetchPromises[template] = $http.get(template, { + cache: $templateCache + }).then(function(res) { + return res.data; + }); + } + } + bsCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controller", "$templateCache"]; + angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider('$bsDropdown', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'dropdown', + prefixEvent: 'dropdown', + placement: 'bottom-left', + templateUrl: 'dropdown/dropdown.tpl.html', + trigger: 'click', + container: false, + keyboard: true, + html: false, + delay: 0 + }; + this.$get = ["$window", "$rootScope", "$bsTooltip", "$timeout", function($window, $rootScope, $tooltip, $timeout) { + var bodyEl = angular.element($window.document.body); + var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector; + function DropdownFactory(element, config) { + var $dropdown = {}; + var options = angular.extend({}, defaults, config); + var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + $dropdown = $tooltip(element, options); + var parentEl = element.parent(); + $dropdown.$onKeyDown = function(evt) { + if (!/(38|40)/.test(evt.keyCode)) return; + evt.preventDefault(); + evt.stopPropagation(); + var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a')); + if (!items.length) return; + var index; + angular.forEach(items, function(el, i) { + if (matchesSelector && matchesSelector.call(el, ':focus')) index = i; + }); + if (evt.keyCode === 38 && index > 0) index--; else if (evt.keyCode === 40 && index < items.length - 1) index++; else if (angular.isUndefined(index)) index = 0; + items.eq(index)[0].focus(); + }; + var show = $dropdown.show; + $dropdown.show = function() { + show(); + $timeout(function() { + options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); + bodyEl.on('click', onBodyClick); + }, 0, false); + parentEl.hasClass('dropdown') && parentEl.addClass('open'); + }; + var hide = $dropdown.hide; + $dropdown.hide = function() { + if (!$dropdown.$isShown) return; + options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); + bodyEl.off('click', onBodyClick); + parentEl.hasClass('dropdown') && parentEl.removeClass('open'); + hide(); + }; + var destroy = $dropdown.destroy; + $dropdown.destroy = function() { + bodyEl.off('click', onBodyClick); + destroy(); + }; + function onBodyClick(evt) { + if (evt.target === element[0]) return; + return evt.target !== element[0] && $dropdown.hide(); + } + return $dropdown; + } + return DropdownFactory; + } ]; + }).directive('bsDropdown', ["$window", "$sce", "$bsDropdown", function($window, $sce, $dropdown) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + newValue === true ? dropdown.show() : dropdown.hide(); + }); + var dropdown = $dropdown(element, options); + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.datepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$bsDatepicker', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'datepicker', + placement: 'bottom-left', + templateUrl: 'datepicker/datepicker.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + useNative: false, + dateType: 'date', + dateFormat: 'shortDate', + timezone: null, + modelDateFormat: null, + dayFormat: 'dd', + monthFormat: 'MMM', + yearFormat: 'yyyy', + monthTitleFormat: 'MMMM yyyy', + yearTitleFormat: 'yyyy', + strictFormat: false, + autoclose: false, + minDate: -Infinity, + maxDate: +Infinity, + startView: 0, + minView: 0, + startWeek: 0, + daysOfWeekDisabled: '', + iconLeft: 'glyphicon glyphicon-chevron-left', + iconRight: 'glyphicon glyphicon-chevron-right' + }; + this.$get = ["$window", "$document", "$rootScope", "$sce", "$bsDateFormatter", "bsDatepickerViews", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) { + var bodyEl = angular.element($window.document.body); + var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale(); + function DatepickerFactory(element, controller, config) { + var $datepicker = $tooltip(element, angular.extend({}, defaults, config)); + var parentScope = config.scope; + var options = $datepicker.$options; + var scope = $datepicker.$scope; + if (options.startView) options.startView -= options.minView; + var pickerViews = datepickerViews($datepicker); + $datepicker.$views = pickerViews.views; + var viewDate = pickerViews.viewDate; + scope.$mode = options.startView; + scope.$iconLeft = options.iconLeft; + scope.$iconRight = options.iconRight; + var $picker = $datepicker.$views[scope.$mode]; + scope.$select = function(date) { + $datepicker.select(date); + }; + scope.$selectPane = function(value) { + $datepicker.$selectPane(value); + }; + scope.$toggleMode = function() { + $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length); + }; + $datepicker.update = function(date) { + if (angular.isDate(date) && !isNaN(date.getTime())) { + $datepicker.$date = date; + $picker.update.call($picker, date); + } + $datepicker.$build(true); + }; + $datepicker.updateDisabledDates = function(dateRanges) { + options.disabledDateRanges = dateRanges; + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], $datepicker.$setDisabledEl); + } + }; + $datepicker.select = function(date, keep) { + if (!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date); + if (!scope.$mode || keep) { + controller.$setViewValue(angular.copy(date)); + controller.$render(); + if (options.autoclose && !keep) { + $timeout(function() { + $datepicker.hide(true); + }); + } + } else { + angular.extend(viewDate, { + year: date.getFullYear(), + month: date.getMonth(), + date: date.getDate() + }); + $datepicker.setMode(scope.$mode - 1); + $datepicker.$build(); + } + }; + $datepicker.setMode = function(mode) { + scope.$mode = mode; + $picker = $datepicker.$views[scope.$mode]; + $datepicker.$build(); + }; + $datepicker.$build = function(pristine) { + if (pristine === true && $picker.built) return; + if (pristine === false && !$picker.built) return; + $picker.build.call($picker); + }; + $datepicker.$updateSelected = function() { + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], updateSelected); + } + }; + $datepicker.$isSelected = function(date) { + return $picker.isSelected(date); + }; + $datepicker.$setDisabledEl = function(el) { + el.disabled = $picker.isDisabled(el.date); + }; + $datepicker.$selectPane = function(value) { + var steps = $picker.steps; + var targetDate = new Date(Date.UTC(viewDate.year + (steps.year || 0) * value, viewDate.month + (steps.month || 0) * value, 1)); + angular.extend(viewDate, { + year: targetDate.getUTCFullYear(), + month: targetDate.getUTCMonth(), + date: targetDate.getUTCDate() + }); + $datepicker.$build(); + }; + $datepicker.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + if (targetEl[0].nodeName.toLowerCase() !== 'button') { + targetEl = targetEl.parent(); + } + targetEl.triggerHandler('click'); + } + }; + $datepicker.$onKeyDown = function(evt) { + if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; + evt.preventDefault(); + evt.stopPropagation(); + if (evt.keyCode === 13) { + if (!scope.$mode) { + return $datepicker.hide(true); + } else { + return scope.$apply(function() { + $datepicker.setMode(scope.$mode - 1); + }); + } + } + $picker.onKeyDown(evt); + parentScope.$digest(); + }; + function updateSelected(el) { + el.selected = $datepicker.$isSelected(el.date); + } + function focusElement() { + element[0].focus(); + } + var _init = $datepicker.init; + $datepicker.init = function() { + if (isNative && options.useNative) { + element.prop('type', 'date'); + element.css('-webkit-appearance', 'textfield'); + return; + } else if (isTouch) { + element.prop('type', 'text'); + element.attr('readonly', 'true'); + element.on('click', focusElement); + } + _init(); + }; + var _destroy = $datepicker.destroy; + $datepicker.destroy = function() { + if (isNative && options.useNative) { + element.off('click', focusElement); + } + _destroy(); + }; + var _show = $datepicker.show; + $datepicker.show = function() { + if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; + _show(); + $timeout(function() { + if (!$datepicker.$isShown) return; + $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.on('keydown', $datepicker.$onKeyDown); + } + }, 0, false); + }; + var _hide = $datepicker.hide; + $datepicker.hide = function(blur) { + if (!$datepicker.$isShown) return; + $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $datepicker.$onKeyDown); + } + _hide(blur); + }; + return $datepicker; + } + DatepickerFactory.defaults = defaults; + return DatepickerFactory; + } ]; + }).directive('bsDatepicker', ["$window", "$parse", "$q", "$bsDateFormatter", "$bsDateParser", "$bsDatepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) { + var defaults = $datepicker.defaults; + var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoclose', 'useNative' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!datepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i); + newValue === true ? datepicker.show() : datepicker.hide(); + }); + var datepicker = $datepicker(element, controller, options); + options = datepicker.$options; + if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd'; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + angular.forEach([ 'minDate', 'maxDate' ], function(key) { + angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) { + datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue); + !isNaN(datepicker.$options[key]) && datepicker.$build(false); + validateAgainstMinMaxDate(controller.$dateValue); + }); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + datepicker.update(controller.$dateValue); + }, true); + function normalizeDateRanges(ranges) { + if (!ranges || !ranges.length) return null; + return ranges; + } + if (angular.isDefined(attr.disabledDates)) { + scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) { + disabledRanges = normalizeDateRanges(disabledRanges); + previousValue = normalizeDateRanges(previousValue); + if (disabledRanges) { + datepicker.updateDisabledDates(disabledRanges); + } + }); + } + function validateAgainstMinMaxDate(parsedDate) { + if (!angular.isDate(parsedDate)) return; + var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate; + var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate; + var isValid = isMinValid && isMaxValid; + controller.$setValidity('date', isValid); + controller.$setValidity('min', isMinValid); + controller.$setValidity('max', isMaxValid); + if (isValid) controller.$dateValue = parsedDate; + } + controller.$parsers.unshift(function(viewValue) { + var date; + if (!viewValue) { + controller.$setValidity('date', true); + return null; + } + var parsedDate = dateParser.parse(viewValue, controller.$dateValue); + if (!parsedDate || isNaN(parsedDate.getTime())) { + controller.$setValidity('date', false); + return; + } else { + validateAgainstMinMaxDate(parsedDate); + } + if (options.dateType === 'string') { + date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true); + return formatDate(date, options.modelDateFormat || options.dateFormat); + } + date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); + if (options.dateType === 'number') { + return date.getTime(); + } else if (options.dateType === 'unix') { + return date.getTime() / 1e3; + } else if (options.dateType === 'iso') { + return date.toISOString(); + } else { + return new Date(date); + } + }); + controller.$formatters.push(function(modelValue) { + var date; + if (angular.isUndefined(modelValue) || modelValue === null) { + date = NaN; + } else if (angular.isDate(modelValue)) { + date = modelValue; + } else if (options.dateType === 'string') { + date = dateParser.parse(modelValue, null, options.modelDateFormat); + } else if (options.dateType === 'unix') { + date = new Date(modelValue * 1e3); + } else { + date = new Date(modelValue); + } + controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); + return getDateFormattedString(); + }); + controller.$render = function() { + element.val(getDateFormattedString()); + }; + function getDateFormattedString() { + return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat); + } + scope.$on('$destroy', function() { + if (datepicker) datepicker.destroy(); + options = null; + datepicker = null; + }); + } + }; + } ]).provider('bsDatepickerViews', function() { + var defaults = this.defaults = { + dayFormat: 'dd', + daySplit: 7 + }; + function split(arr, size) { + var arrays = []; + while (arr.length > 0) { + arrays.push(arr.splice(0, size)); + } + return arrays; + } + function mod(n, m) { + return (n % m + m) % m; + } + this.$get = ["$bsDateFormatter", "$bsDateParser", "$sce", function($dateFormatter, $dateParser, $sce) { + return function(picker) { + var scope = picker.$scope; + var options = picker.$options; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + var weekDaysMin = $dateFormatter.weekdaysShort(lang); + var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek)); + var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + ''); + var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date()); + var viewDate = { + year: startDate.getFullYear(), + month: startDate.getMonth(), + date: startDate.getDate() + }; + var views = [ { + format: options.dayFormat, + split: 7, + steps: { + month: 1 + }, + update: function(date, force) { + if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getDate() !== viewDate.date || date.getDate() === 1) { + viewDate.date = picker.$date.getDate(); + picker.$updateSelected(); + } + }, + build: function() { + var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset(); + var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset(); + var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString(); + if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 6e4); + var days = [], day; + for (var i = 0; i < 42; i++) { + day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i)); + days.push({ + date: day, + isToday: day.toDateString() === today, + label: formatDate(day, this.format), + selected: picker.$date && this.isSelected(day), + muted: day.getMonth() !== viewDate.month, + disabled: this.isDisabled(day) + }); + } + scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat); + scope.showLabels = true; + scope.labels = weekDaysLabelsHtml; + scope.rows = split(days, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate(); + }, + isDisabled: function(date) { + var time = date.getTime(); + if (time < options.minDate || time > options.maxDate) return true; + if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true; + if (options.disabledDateRanges) { + for (var i = 0; i < options.disabledDateRanges.length; i++) { + if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) { + return true; + } + } + } + return false; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualTime = picker.$date.getTime(); + var newDate; + if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5); else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5); else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5); else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'month', + format: options.monthFormat, + split: 4, + steps: { + year: 1 + }, + update: function(date, force) { + if (!this.built || date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var firstMonth = new Date(viewDate.year, 0, 1); + var months = [], month; + for (var i = 0; i < 12; i++) { + month = new Date(viewDate.year, i, 1); + months.push({ + date: month, + label: formatDate(month, this.format), + selected: picker.$isSelected(month), + disabled: this.isDisabled(month) + }); + } + scope.title = formatDate(month, options.yearTitleFormat); + scope.showLabels = false; + scope.rows = split(months, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualMonth = picker.$date.getMonth(); + var newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1); else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4); else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1); else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'year', + format: options.yearFormat, + split: 4, + steps: { + year: 12 + }, + update: function(date, force) { + if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var firstYear = viewDate.year - viewDate.year % (this.split * 3); + var years = [], year; + for (var i = 0; i < 12; i++) { + year = new Date(firstYear + i, 0, 1); + years.push({ + date: year, + label: formatDate(year, this.format), + selected: picker.$isSelected(year), + disabled: this.isDisabled(year) + }); + } + scope.title = years[0].label + '-' + years[years.length - 1].label; + scope.showLabels = false; + scope.rows = split(years, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear() + 1, 0, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualYear = picker.$date.getFullYear(), newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setYear(actualYear - 1); else if (evt.keyCode === 38) newDate.setYear(actualYear - 4); else if (evt.keyCode === 39) newDate.setYear(actualYear + 1); else if (evt.keyCode === 40) newDate.setYear(actualYear + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + } ]; + return { + views: options.minView ? Array.prototype.slice.call(views, options.minView) : views, + viewDate: viewDate + }; + }; + } ]; + }); + angular.module('mgcrea.ngStrap.collapse', []).provider('$bsCollapse', function() { + var defaults = this.defaults = { + animation: 'am-collapse', + disallowToggle: false, + activeClass: 'in', + startCollapsed: false, + allowMultiple: false + }; + var controller = this.controller = function($scope, $element, $attrs) { + var self = this; + self.$options = angular.copy(defaults); + angular.forEach([ 'animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'disallowToggle', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) { + self.$options[key] = false; + } + }); + self.$toggles = []; + self.$targets = []; + self.$viewChangeListeners = []; + self.$registerToggle = function(element) { + self.$toggles.push(element); + }; + self.$registerTarget = function(element) { + self.$targets.push(element); + }; + self.$unregisterToggle = function(element) { + var index = self.$toggles.indexOf(element); + self.$toggles.splice(index, 1); + }; + self.$unregisterTarget = function(element) { + var index = self.$targets.indexOf(element); + self.$targets.splice(index, 1); + if (self.$options.allowMultiple) { + deactivateItem(element); + } + fixActiveItemIndexes(index); + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$targets.$active = !self.$options.startCollapsed ? [ 0 ] : []; + self.$setActive = $scope.$setActive = function(value) { + if (angular.isArray(value)) { + self.$targets.$active = value; + } else if (!self.$options.disallowToggle) { + isActive(value) ? deactivateItem(value) : activateItem(value); + } else { + activateItem(value); + } + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$activeIndexes = function() { + return self.$options.allowMultiple ? self.$targets.$active : self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1; + }; + function fixActiveItemIndexes(index) { + var activeIndexes = self.$targets.$active; + for (var i = 0; i < activeIndexes.length; i++) { + if (index < activeIndexes[i]) { + activeIndexes[i] = activeIndexes[i] - 1; + } + if (activeIndexes[i] === self.$targets.length) { + activeIndexes[i] = self.$targets.length - 1; + } + } + } + function isActive(value) { + var activeItems = self.$targets.$active; + return activeItems.indexOf(value) === -1 ? false : true; + } + function deactivateItem(value) { + var index = self.$targets.$active.indexOf(value); + if (index !== -1) { + self.$targets.$active.splice(index, 1); + } + } + function activateItem(value) { + if (!self.$options.allowMultiple) { + self.$targets.$active.splice(0, 1); + } + if (self.$targets.$active.indexOf(value) === -1) { + self.$targets.$active.push(value); + } + } + }; + this.$get = function() { + var $collapse = {}; + $collapse.defaults = defaults; + $collapse.controller = controller; + return $collapse; + }; + }).directive('bsCollapse', ["$window", "$animate", "$bsCollapse", function($window, $animate, $collapse) { + var defaults = $collapse.defaults; + return { + require: [ '?ngModel', 'bsCollapse' ], + controller: [ '$scope', '$element', '$attrs', $collapse.controller ], + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsCollapseCtrl = controllers[1]; + if (ngModelCtrl) { + bsCollapseCtrl.$viewChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes()); + }); + ngModelCtrl.$formatters.push(function(modelValue) { + if (angular.isArray(modelValue)) { + bsCollapseCtrl.$setActive(modelValue); + } else { + var activeIndexes = bsCollapseCtrl.$activeIndexes(); + if (angular.isArray(activeIndexes)) { + if (activeIndexes.indexOf(modelValue * 1) === -1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } else if (activeIndexes !== modelValue * 1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } + return modelValue; + }); + } + } + }; + } ]).directive('bsCollapseToggle', function() { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsCollapseCtrl = controllers[1]; + element.attr('data-toggle', 'collapse'); + bsCollapseCtrl.$registerToggle(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterToggle(element); + }); + element.on('click', function() { + var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element); + bsCollapseCtrl.$setActive(index * 1); + scope.$apply(); + }); + } + }; + }).directive('bsCollapseTarget', ["$animate", function($animate) { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsCollapseCtrl = controllers[1]; + element.addClass('collapse'); + if (bsCollapseCtrl.$options.animation) { + element.addClass(bsCollapseCtrl.$options.animation); + } + bsCollapseCtrl.$registerTarget(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterTarget(element); + }); + function render() { + var index = bsCollapseCtrl.$targets.indexOf(element); + var active = bsCollapseCtrl.$activeIndexes(); + var action = 'removeClass'; + if (angular.isArray(active)) { + if (active.indexOf(index) !== -1) { + action = 'addClass'; + } + } else if (index === active) { + action = 'addClass'; + } + $animate[action](element, bsCollapseCtrl.$options.activeClass); + } + bsCollapseCtrl.$viewChangeListeners.push(function() { + render(); + }); + render(); + } + }; + } ]); + angular.module('mgcrea.ngStrap.button', []).provider('$bsButton', function() { + var defaults = this.defaults = { + activeClass: 'active', + toggleEvent: 'click' + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsCheckboxGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="checkbox"]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.attr('bs-checkbox', ''); + childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); + }); + } + }; + }).directive('bsCheckbox', ["$bsButton", "$$bsRAF", function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; + if (constantValueRegExp.test(attr.trueValue)) { + trueValue = scope.$eval(attr.trueValue); + } + var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; + if (constantValueRegExp.test(attr.falseValue)) { + falseValue = scope.$eval(attr.falseValue); + } + var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; + if (hasExoticValues) { + controller.$parsers.push(function(viewValue) { + return viewValue ? trueValue : falseValue; + }); + controller.$formatters.push(function(modelValue) { + return angular.equals(modelValue, trueValue); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + controller.$render(); + }); + } + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, trueValue); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + if (!isInput) { + controller.$setViewValue(!activeElement.hasClass('active')); + } + if (!hasExoticValues) { + controller.$render(); + } + }); + }); + } + }; + } ]).directive('bsRadioGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="radio"]'); + angular.forEach(children, function(child) { + angular.element(child).attr('bs-radio', ''); + angular.element(child).attr('ng-model', attr.ngModel); + }); + } + }; + }).directive('bsRadio', ["$bsButton", "$$bsRAF", function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var value; + attr.$observe('value', function(v) { + value = constantValueRegExp.test(v) ? scope.$eval(v) : v; + controller.$render(); + }); + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, value); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + controller.$setViewValue(value); + controller.$render(); + }); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$bsAside', function() { + var defaults = this.defaults = { + animation: 'am-fade-and-slide-right', + prefixClass: 'aside', + prefixEvent: 'aside', + placement: 'right', + templateUrl: 'aside/aside.tpl.html', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true + }; + this.$get = ["$bsModal", function($modal) { + function AsideFactory(config) { + var $aside = {}; + var options = angular.extend({}, defaults, config); + $aside = $modal(options); + return $aside; + } + return AsideFactory; + } ]; + }).directive('bsAside', ["$window", "$sce", "$bsAside", function($window, $sce, $aside) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'title', 'content' ], function(key) { + attr[key] && attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + }); + attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + var aside = $aside(options); + element.on(attr.trigger || 'click', aside.toggle); + scope.$on('$destroy', function() { + if (aside) aside.destroy(); + options = null; + aside = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$bsAlert', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'alert', + prefixEvent: 'alert', + placement: null, + templateUrl: 'alert/alert.tpl.html', + container: false, + element: null, + backdrop: false, + keyboard: true, + show: true, + duration: false, + type: false, + dismissable: true + }; + this.$get = ["$bsModal", "$timeout", function($modal, $timeout) { + function AlertFactory(config) { + var $alert = {}; + var options = angular.extend({}, defaults, config); + $alert = $modal(options); + $alert.$scope.dismissable = !!options.dismissable; + if (options.type) { + $alert.$scope.type = options.type; + } + var show = $alert.show; + if (options.duration) { + $alert.show = function() { + show(); + $timeout(function() { + $alert.hide(); + }, options.duration * 1e3); + }; + } + return $alert; + } + return AlertFactory; + } ]; + }).directive('bsAlert', ["$window", "$sce", "$bsAlert", function($window, $sce, $alert) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'keyboard', 'html', 'container', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + if (!scope.hasOwnProperty('title')) { + scope.title = ''; + } + angular.forEach([ 'title', 'content', 'type' ], function(key) { + attr[key] && attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + }); + attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + var alert = $alert(options); + element.on(attr.trigger || 'click', alert.toggle); + scope.$on('$destroy', function() { + if (alert) alert.destroy(); + options = null; + alert = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.affix', [ 'mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce' ]).provider('$bsAffix', function() { + var defaults = this.defaults = { + offsetTop: 'auto', + inlineStyles: true + }; + this.$get = ["$window", "bsDebounce", "bsDimensions", function($window, debounce, dimensions) { + var bodyEl = angular.element($window.document.body); + var windowEl = angular.element($window); + function AffixFactory(element, config) { + var $affix = {}; + var options = angular.extend({}, defaults, config); + var targetEl = options.target; + var reset = 'affix affix-top affix-bottom', setWidth = false, initialAffixTop = 0, initialOffsetTop = 0, offsetTop = 0, offsetBottom = 0, affixed = null, unpin = null; + var parent = element.parent(); + if (options.offsetParent) { + if (options.offsetParent.match(/^\d+$/)) { + for (var i = 0; i < options.offsetParent * 1 - 1; i++) { + parent = parent.parent(); + } + } else { + parent = angular.element(options.offsetParent); + } + } + $affix.init = function() { + this.$parseOffsets(); + initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop; + setWidth = !element[0].style.width; + targetEl.on('scroll', this.checkPosition); + targetEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', this.$debouncedOnResize); + this.checkPosition(); + this.checkPositionWithEventLoop(); + }; + $affix.destroy = function() { + targetEl.off('scroll', this.checkPosition); + targetEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', this.$debouncedOnResize); + }; + $affix.checkPositionWithEventLoop = function() { + setTimeout($affix.checkPosition, 1); + }; + $affix.checkPosition = function() { + var scrollTop = getScrollTop(); + var position = dimensions.offset(element[0]); + var elementHeight = dimensions.height(element[0]); + var affix = getRequiredAffixClass(unpin, position, elementHeight); + if (affixed === affix) return; + affixed = affix; + if (affix === 'top') { + unpin = null; + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', ''); + } + } else if (affix === 'bottom') { + if (options.offsetUnpin) { + unpin = -(options.offsetUnpin * 1); + } else { + unpin = position.top - scrollTop; + } + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', options.offsetParent ? '' : bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop + 'px'); + } + } else { + unpin = null; + if (setWidth) { + element.css('width', element[0].offsetWidth + 'px'); + } + if (options.inlineStyles) { + element.css('position', 'fixed'); + element.css('top', initialAffixTop + 'px'); + } + } + element.removeClass(reset).addClass('affix' + (affix !== 'middle' ? '-' + affix : '')); + }; + $affix.$onResize = function() { + $affix.$parseOffsets(); + $affix.checkPosition(); + }; + $affix.$debouncedOnResize = debounce($affix.$onResize, 50); + $affix.$parseOffsets = function() { + var initialPosition = element.css('position'); + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + } + if (options.offsetTop) { + if (options.offsetTop === 'auto') { + options.offsetTop = '+0'; + } + if (options.offsetTop.match(/^[-+]\d+$/)) { + initialAffixTop = -options.offsetTop * 1; + if (options.offsetParent) { + offsetTop = dimensions.offset(parent[0]).top + options.offsetTop * 1; + } else { + offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + options.offsetTop * 1; + } + } else { + offsetTop = options.offsetTop * 1; + } + } + if (options.offsetBottom) { + if (options.offsetParent && options.offsetBottom.match(/^[-+]\d+$/)) { + offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + options.offsetBottom * 1 + 1; + } else { + offsetBottom = options.offsetBottom * 1; + } + } + if (options.inlineStyles) { + element.css('position', initialPosition); + } + }; + function getRequiredAffixClass(unpin, position, elementHeight) { + var scrollTop = getScrollTop(); + var scrollHeight = getScrollHeight(); + if (scrollTop <= offsetTop) { + return 'top'; + } else if (unpin !== null && scrollTop + unpin <= position.top) { + return 'middle'; + } else if (offsetBottom !== null && position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom) { + return 'bottom'; + } else { + return 'middle'; + } + } + function getScrollTop() { + return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop; + } + function getScrollHeight() { + return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight; + } + $affix.init(); + return $affix; + } + return AffixFactory; + } ]; + }).directive('bsAffix', ["$bsAffix", "$window", function($affix, $window) { + return { + restrict: 'EAC', + require: '^?bsAffixTarget', + link: function postLink(scope, element, attr, affixTarget) { + var options = { + scope: scope, + target: affixTarget ? affixTarget.$element : angular.element($window) + }; + angular.forEach([ 'offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles' ], function(key) { + if (angular.isDefined(attr[key])) { + var option = attr[key]; + if (/true/i.test(option)) option = true; + if (/false/i.test(option)) option = false; + options[key] = option; + } + }); + var affix = $affix(element, options); + scope.$on('$destroy', function() { + affix && affix.destroy(); + options = null; + affix = null; + }); + } + }; + } ]).directive('bsAffixTarget', function() { + return { + controller: ["$element", function($element) { + this.$element = $element; + } ] + }; + }); + angular.module('mgcrea.ngStrap', [ 'mgcrea.ngStrap.modal', 'mgcrea.ngStrap.aside', 'mgcrea.ngStrap.alert', 'mgcrea.ngStrap.button', 'mgcrea.ngStrap.select', 'mgcrea.ngStrap.datepicker', 'mgcrea.ngStrap.timepicker', 'mgcrea.ngStrap.navbar', 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.popover', 'mgcrea.ngStrap.dropdown', 'mgcrea.ngStrap.typeahead', 'mgcrea.ngStrap.scrollspy', 'mgcrea.ngStrap.affix', 'mgcrea.ngStrap.tab', 'mgcrea.ngStrap.collapse' ]); +})(window, document); \ No newline at end of file diff --git a/dist/angular-strap.compat.min.js b/dist/angular-strap.compat.min.js new file mode 100644 index 000000000..51442a2ba --- /dev/null +++ b/dist/angular-strap.compat.min.js @@ -0,0 +1,3 @@ +!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),n?d.$template=l(n):d.$template=e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$bsTypeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$bsTooltip','$$bsRAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsTooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','bsDimensions','$$bsRAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===P&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function b(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===P&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function w(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function y(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',k),h.on('click',F.hide),K=!0},0,!1)}function S(){K&&(R.off('click',k),h.off('click',F.hide),K=!1)}function k(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function T(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function C(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=M(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';E(f,n[p],d)}}}function M(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function E(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&S(),V.keyboard&&y()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),P=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){b(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'})}),V.keyboard&&('focus'!==V.trigger&&F.focus(),w()),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&y(),V.autoClose&&null!==R&&S())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||w),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*g.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*g.length*g.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*g.length*g.secondStep),angular.extend(y,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,S).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*M;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var b=2===v&&C,w=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,S).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):b?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):w&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var E=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void E())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$bsDateFormatter','$bsDateParser','$bsTimepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$bsTab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$bsTooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=d.$matches.length?d.$activeIndex=c.multiple?[]:0:r.$modelValue||c.multiple||(d.$activeIndex=-1)},u.$isVisible=function(){return c.minLength&&r?d.$matches.length&&r.$viewValue.length>=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){c.multiple||r.$modelValue||(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$bsSelect','$bsParseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){ +return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$bsScrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','bsDimensions','bsDebounce','bsThrottle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,b,w,y,D,S,k,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,w=s(this.checkPosition,c.debounce),y=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',w),m.on('scroll',y),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',w),m.off('scroll',y),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(k=(g?a.pageYOffset:m.prop('scrollTop'))||0,S=Math.max(a.innerHeight,f.prop('clientHeight')),kC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(b){var t=x.$getTrackedElement(b);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}b=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),w()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','bsDebounce','bsDimensions','$bsScrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','bsDebounce','bsDimensions','$bsScrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$bsPopover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$bsTooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$bsPopover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(s.test(l)?r.target=!1:r.target=l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$bsNavbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$bsNavbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsModal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','bsDimensions',function(n,a,o,i,r,s,l){function u(t){function n(){S.$emit(y.prefixEvent+'.show',w)}function r(){S.$emit(y.prefixEvent+'.hide',w),g.removeClass(y.prefixClass+'-open'),y.animation&&g.removeClass(y.prefixClass+'-with-'+y.animation)}function l(){y.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){y.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){y.keyboard&&x.on('keyup',w.$onKeyUp)}function $(){y.keyboard&&x.off('keyup',w.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===y.backdrop?w.focus():w.hide())}function v(e){e.preventDefault()}function b(){w.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=w.$element=null)}var w={},y=w.$options=angular.extend({},e,t),D=w.$promise=o.compile(y),S=w.$scope=y.scope&&y.scope.$new()||a.$new();y.element||y.container||(y.container='body'),w.$id=y.id||y.element&&y.element.attr('id')||'',f(['title','content'],function(e){y[e]&&(S[e]=s.trustAsHtml(y[e]))}),S.$hide=function(){S.$$postDigest(function(){w.hide()})},S.$show=function(){S.$$postDigest(function(){w.show()})},S.$toggle=function(){S.$$postDigest(function(){w.toggle()})},w.$isShown=S.$isShown=!1;var k,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){k=e,w.init()}),w.init=function(){y.show&&S.$$postDigest(function(){w.show()})},w.destroy=function(){b(),C&&(C.remove(),C=null),S.$destroy()},w.show=function(){if(!w.$isShown){var e,t;if(angular.isElement(y.container)?(e=y.container,t=y.container[0].lastChild?angular.element(y.container[0].lastChild):null):y.container?(e=d(y.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=y.element),x&&b(),T=w.$scope.$new(),x=w.$element=k.link(T,function(e,t){}),!S.$emit(y.prefixEvent+'.show.before',w).defaultPrevented){x.css({display:'block'}).addClass(y.placement),y.animation&&(y.backdrop&&C.addClass(y.backdropAnimation),x.addClass(y.animation)),y.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),w.$isShown=S.$isShown=!0,c(S);var a=x[0];p(function(){a.focus()}),g.addClass(y.prefixClass+'-open'),y.animation&&g.addClass(y.prefixClass+'-with-'+y.animation),l(),m()}}},w.hide=function(){w.$isShown&&(S.$emit(y.prefixEvent+'.hide.before',w).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),y.backdrop&&i.leave(C),w.$isShown=S.$isShown=!1,c(S),u(),$()))},w.toggle=function(){w.$isShown?w.hide():w.show()},w.focus=function(){x[0].focus()},w.$onKeyUp=function(e){27===e.which&&w.$isShown&&(w.hide(),e.stopPropagation())},w}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).directive('bsModal',['$window','$sce','$bsModal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$bsRAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$bsParseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('bsDimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('bsDebounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('bsThrottle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$bsDateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$bsDateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$bsDropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$bsTooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new();u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var b=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),b()};var w=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(w(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var y=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),y(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$bsDateFormatter','$bsDateParser','$bsDatepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('bsDatepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$bsDateFormatter','$bsDateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()); +},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.collapse',[]).provider('$bsCollapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n=a?'top':null!==e&&a+e<=t.top?'middle':null!==b&&t.top+n+$>=o-b?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,b=0,w=null,y=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var S=0;S<1*f.offsetParent-1;S++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(y,t,n);w!==r&&(w=r,'top'===r?(y=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(y=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-b-n-h+'px'))):(y=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(b=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$bsAffix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document); \ No newline at end of file diff --git a/dist/angular-strap.js b/dist/angular-strap.js index e229c63ea..e117a3cef 100644 --- a/dist/angular-strap.js +++ b/dist/angular-strap.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -3611,70 +3611,6 @@ } }; } ]); - angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$aside', function() { - var defaults = this.defaults = { - animation: 'am-fade-and-slide-right', - prefixClass: 'aside', - prefixEvent: 'aside', - placement: 'right', - templateUrl: 'aside/aside.tpl.html', - contentTemplate: false, - container: false, - element: null, - backdrop: true, - keyboard: true, - html: false, - show: true - }; - this.$get = [ '$modal', function($modal) { - function AsideFactory(config) { - var $aside = {}; - var options = angular.extend({}, defaults, config); - $aside = $modal(options); - return $aside; - } - return AsideFactory; - } ]; - }).directive('bsAside', [ '$window', '$sce', '$aside', function($window, $sce, $aside) { - var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; - return { - restrict: 'EAC', - scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope, - element: element, - show: false - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - angular.forEach([ 'title', 'content' ], function(key) { - attr[key] && attr.$observe(key, function(newValue, oldValue) { - scope[key] = $sce.trustAsHtml(newValue); - }); - }); - attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); - } else { - scope.content = newValue; - } - }, true); - var aside = $aside(options); - element.on(attr.trigger || 'click', aside.toggle); - scope.$on('$destroy', function() { - if (aside) aside.destroy(); - options = null; - aside = null; - }); - } - }; - } ]); angular.module('mgcrea.ngStrap.button', []).provider('$button', function() { var defaults = this.defaults = { activeClass: 'active', @@ -3794,6 +3730,70 @@ } }; } ]); + angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$aside', function() { + var defaults = this.defaults = { + animation: 'am-fade-and-slide-right', + prefixClass: 'aside', + prefixEvent: 'aside', + placement: 'right', + templateUrl: 'aside/aside.tpl.html', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true + }; + this.$get = [ '$modal', function($modal) { + function AsideFactory(config) { + var $aside = {}; + var options = angular.extend({}, defaults, config); + $aside = $modal(options); + return $aside; + } + return AsideFactory; + } ]; + }).directive('bsAside', [ '$window', '$sce', '$aside', function($window, $sce, $aside) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'title', 'content' ], function(key) { + attr[key] && attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + }); + attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + var aside = $aside(options); + element.on(attr.trigger || 'click', aside.toggle); + scope.$on('$destroy', function() { + if (aside) aside.destroy(); + options = null; + aside = null; + }); + } + }; + } ]); angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$alert', function() { var defaults = this.defaults = { animation: 'am-fade', diff --git a/dist/angular-strap.min.js b/dist/angular-strap.min.js index fb35b71dd..0c5e547da 100644 --- a/dist/angular-strap.min.js +++ b/dist/angular-strap.min.js @@ -1,11 +1,11 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){d[t]=angular.isString(e)?a.get(e):a.invoke(e)}),angular.extend(d,f),d.$template=n?l(n):e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===P&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===P&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function T(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function C(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=E(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';M(f,n[p],d)}}}function E(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),P=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'})}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y()),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*E;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var M=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):new Date('unix'===f.timeType?1e3*e:e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],d.$activeIndex=c.multiple?[]:-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=d.$matches.length?d.$activeIndex=c.multiple?[]:0:r.$modelValue||c.multiple||(d.$activeIndex=-1)},u.$isVisible=function(){return c.minLength&&r?d.$matches.length&&r.$viewValue.length>=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){c.multiple||r.$modelValue||(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(s.multiple=l.test(u)?!1:u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined), -e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),SC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(r.target=s.test(l)?!1:l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function r(){k.$emit(b.prefixEvent+'.hide',y),g.removeClass(b.prefixClass+'-open'),b.animation&&g.removeClass(b.prefixClass+'-with-'+b.animation)}function l(){b.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){b.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function $(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',f(['title','content'],function(e){b[e]&&(k[e]=s.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=d(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,c(k);var a=x[0];p(function(){a.focus()}),g.addClass(b.prefixClass+'-open'),b.animation&&g.addClass(b.prefixClass+'-with-'+b.animation),l(),m()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),b.backdrop&&i.leave(C),y.$isShown=k.$isShown=!1,c(k),u(),$()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t=1*e&&2===e.length?2e3+1*e:1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=(new t).fromDate(a&&!isNaN(a.getTime())?a:new Date(1970,0,1,0)),$=0;$12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}{var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new()}u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):new Date('unix'===d.dateType?1e3*e:e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1, -r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document); +!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),n?d.$template=l(n):d.$template=e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function T(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function C(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=E(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';M(f,n[p],d)}}}function E(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),N=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var P=V.delay.split(',').map(parseFloat);V.delay=P.length>1?{show:P[0],hide:P[1]}:P[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'})}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y()),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-it?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*E;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var M=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=d.$matches.length?d.$activeIndex=c.multiple?[]:0:r.$modelValue||c.multiple||(d.$activeIndex=-1)},u.$isVisible=function(){return c.minLength&&r?d.$matches.length&&r.$viewValue.length>=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){c.multiple||r.$modelValue||(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){ +return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),SC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(s.test(l)?r.target=!1:r.target=l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function r(){k.$emit(b.prefixEvent+'.hide',y),g.removeClass(b.prefixClass+'-open'),b.animation&&g.removeClass(b.prefixClass+'-with-'+b.animation)}function l(){b.backdrop&&(x.on('click',h),C.on('click',h),C.on('wheel',v))}function u(){b.backdrop&&(x.off('click',h),C.off('click',h),C.off('wheel',v))}function m(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function $(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function h(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(u(),$()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',f(['title','content'],function(e){b[e]&&(k[e]=s.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=d(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&i.enter(C,g,null),angular.version.minor<=2?i.enter(x,e,t,n):i.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,c(k);var a=x[0];p(function(){a.focus()}),g.addClass(b.prefixClass+'-open'),b.animation&&g.addClass(b.prefixClass+'-with-'+b.animation),l(),m()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?i.leave(x,r):i.leave(x).then(r),b.backdrop&&i.leave(C),y.$isShown=k.$isShown=!1,c(k),u(),$()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),g=angular.element(n.document.body);return u}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),$=0;$12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new();u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1), +n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document); //# sourceMappingURL=angular-strap.min.js.map \ No newline at end of file diff --git a/dist/angular-strap.min.js.map b/dist/angular-strap.min.js.map index a4e644689..115a0c7ac 100644 --- a/dist/angular-strap.min.js.map +++ b/dist/angular-strap.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","dropdown/dropdown.js","tooltip/tooltip.js","timepicker/timepicker.js","tab/tab.js","select/select.js","scrollspy/scrollspy.js","popover/popover.js","navbar/navbar.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","datepicker/datepicker.js","collapse/collapse.js","aside/aside.js","button/button.js","alert/alert.js","affix/affix.js","module.js"],"names":["placement","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","defaults","this","animation","data","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","$scope","$matches","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$$rAF","$render","$emit","prefixEvent","parentScope","length","l","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$timeout","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","array","isFunction","$$phase","$window","body","$filter","expression","directive","results","restrict","require","falseValueRegExp","attr","bsOptions","test","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","isVisible","slice","$formatters","displayValue","push","modelValue","selected","val","destroy","isDefined","label","toString","$on","target","title","type","autoClose","bsEnabled","viewport","selector","padding","String","htmlReplaceRegExp","$body","$tooltip","split","enterAnimateCallback","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","nodeName","triggers","toggle","unbindTriggerEvents","enter","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","width","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","documentElement","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","tipScope","$destroy","$options","$promise","$bsCompiler","$new","$rootScope","toLowerCase","$id","map","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","promise","init","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","version","minor","addClass","$animate","customClass","$applyPlacement","focus","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","$location","transclusion","dataTarget","hasOwnProperty","tooltip","$observe","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","minute","$setViewValue","keep","Date","setHours","setMinutes","setSeconds","hours","midIndex","$isSelected","disabled","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","prop","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","getTimeForAttribute","parse","timezoneOffsetAdjust","NaN","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","splice","$setActive","name","fn","$pane","$tab","transclude","postLink","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","render","$isActive","prefixClass","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$selectNone","$updateActiveIndex","b","a","$apply","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","activeElement","tagName","e","dataMultiple","inputEl","addEventListener","isArray","join","$isEmpty","spies","$document","windowEl","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","scrollTop","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","source","$getTrackedElement","targetElement","querySelector","trackedElement","trackElement","toDelete","untrackElement","scrollspy","childEl","querySelectorAll","child","content","$popover","PopoverFactory","requestAnimationFrame","popover","bsPopover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","bodyElement","ModalFactory","$modal","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","destroyModalElement","modalScope","$show","bottom","z-index","defaultPrevented","backdropAnimation","bindBackdropEvents","which","$root","query","bsModal","modal","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","$values","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","keyName","jqLite","currentStyle","window","getComputedStyle","extra","boxRect","getBoundingClientRect","style","offsetHeight","docElement","ownerDocument","curPosition","curLeft","curCSSTop","pageYOffset","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","call","offsetParentRect","offsetParentElement","offsetParent","offsetWidth","outer","func","immediate","factory","context","args","cancel","callNow","leading","trailing","wait","year","$localeProvider","milliseconds","ParseDate","prototype","isNumeric","n","isFinite","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","noop","toDate","regExpMap","sss","$locale","dateFilter","mm","keys","setFnMap","clonedFormat","search","v","sortedMap","regExpForFormat","re","text","Object","escapeReservedSymbols","regex","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","s","setDate","setMonth","setMap","$format","setMapForFormat","baseDate","formatRegex","formatSetMap","exec","fromDate","getDate","today","getDateForAttribute","substr","daylightSavingAdjust","undo","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","bsDropdown","dropdown","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","updateSelected","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","daySplit","arr","mod","arrays","size","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDate","getDay","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","firstMonth","months","lastDate","actualMonth","firstYear","years","actualYear","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","controllers","bsCollapseToggle","$registerTarget","action","AsideFactory","$aside","bsAside","aside","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","equals","checked","bind","toggleEvent","toggleClass","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","setWidth","initialAffixTop","getRequiredAffixClass","unpin","getScrollTop","scrollHeight","getScrollHeight","initialOffsetTop","offsetBottom","affixed","$parseOffsets","affix","elementHeight","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: helpers/raf.js\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","dropdown/dropdown.js","tooltip/tooltip.js","timepicker/timepicker.js","tab/tab.js","select/select.js","scrollspy/scrollspy.js","popover/popover.js","navbar/navbar.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","datepicker/datepicker.js","collapse/collapse.js","button/button.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["placement","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","defaults","this","animation","data","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","bodyEl","$typeahead","$scope","$matches","config","$resetMatches","$$postDigest","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$$rAF","$render","$emit","prefixEvent","parentScope","length","l","$viewValue","i","preventDefault","stopPropagation","keyCode","$digest","show","$timeout","$element","$onMouseDown","hide","on","$onKeyDown","TypeaheadFactory","array","isFunction","$$phase","$window","body","$filter","expression","directive","results","restrict","require","falseValueRegExp","attr","bsOptions","test","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","isVisible","slice","$formatters","displayValue","push","modelValue","selected","val","destroy","isDefined","label","toString","$on","target","title","type","autoClose","bsEnabled","viewport","selector","padding","String","htmlReplaceRegExp","$body","$tooltip","split","enterAnimateCallback","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","nodeName","triggers","toggle","unbindTriggerEvents","enter","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","width","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","documentElement","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","tipScope","$destroy","$options","$promise","$bsCompiler","$new","$rootScope","toLowerCase","$id","map","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","promise","init","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","version","minor","addClass","$animate","customClass","$applyPlacement","focus","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","$location","transclusion","dataTarget","hasOwnProperty","tooltip","$observe","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","minute","$setViewValue","keep","Date","setHours","setMinutes","setSeconds","hours","midIndex","$isSelected","disabled","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","prop","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","getTimeForAttribute","parse","timezoneOffsetAdjust","NaN","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","splice","$setActive","name","fn","$pane","$tab","transclude","postLink","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","render","$isActive","prefixClass","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","b","a","$apply","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","activeElement","tagName","e","dataMultiple","inputEl","addEventListener","isArray","join","$isEmpty","spies","$document","windowEl","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","scrollTop","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","source","$getTrackedElement","targetElement","querySelector","trackedElement","trackElement","toDelete","untrackElement","scrollspy","childEl","querySelectorAll","child","content","$popover","PopoverFactory","requestAnimationFrame","popover","bsPopover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","bodyElement","ModalFactory","$modal","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","destroyModalElement","modalScope","$show","bottom","z-index","defaultPrevented","backdropAnimation","bindBackdropEvents","which","$root","query","bsModal","modal","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","$values","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","keyName","jqLite","currentStyle","window","getComputedStyle","extra","boxRect","getBoundingClientRect","style","offsetHeight","docElement","ownerDocument","curPosition","curLeft","curCSSTop","pageYOffset","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","call","offsetParentRect","offsetParentElement","offsetParent","offsetWidth","outer","func","immediate","factory","context","args","cancel","callNow","leading","trailing","wait","year","$localeProvider","milliseconds","ParseDate","prototype","isNumeric","n","isFinite","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","noop","toDate","regExpMap","sss","$locale","dateFilter","mm","keys","setFnMap","clonedFormat","search","v","sortedMap","regExpForFormat","re","text","Object","escapeReservedSymbols","regex","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","s","setDate","setMonth","setMap","setMapForFormat","$format","baseDate","formatRegex","formatSetMap","exec","fromDate","getDate","today","getDateForAttribute","substr","daylightSavingAdjust","undo","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","bsDropdown","dropdown","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","updateSelected","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","daySplit","arr","mod","arrays","size","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDate","getDay","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","firstMonth","months","lastDate","actualMonth","firstYear","years","actualYear","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","controllers","bsCollapseToggle","$registerTarget","action","toggleEvent","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","equals","checked","bind","toggleClass","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","setWidth","initialAffixTop","getRequiredAffixClass","unpin","getScrollTop","scrollHeight","getScrollHeight","initialOffsetTop","offsetBottom","affixed","$parseOffsets","affix","elementHeight","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: helpers/raf.js\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/angular-strap.tpl.js b/dist/angular-strap.tpl.js index 530ee1e05..c24c076aa 100644 --- a/dist/angular-strap.tpl.js +++ b/dist/angular-strap.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/angular-strap.tpl.min.js b/dist/angular-strap.tpl.min.js index 9d9ab279a..ce96899c5 100644 --- a/dist/angular-strap.tpl.min.js +++ b/dist/angular-strap.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/affix.js b/dist/modules/affix.js index 203545243..be4cdf1c1 100644 --- a/dist/modules/affix.js +++ b/dist/modules/affix.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/affix.min.js b/dist/modules/affix.min.js index a122e8b4f..7e8c7e4bd 100644 --- a/dist/modules/affix.min.js +++ b/dist/modules/affix.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.js b/dist/modules/alert.js index 73f728465..0781cb333 100644 --- a/dist/modules/alert.js +++ b/dist/modules/alert.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.min.js b/dist/modules/alert.min.js index fedf21559..6ac77562a 100644 --- a/dist/modules/alert.min.js +++ b/dist/modules/alert.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.tpl.js b/dist/modules/alert.tpl.js index 008f0f657..c6f520a44 100644 --- a/dist/modules/alert.tpl.js +++ b/dist/modules/alert.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/alert.tpl.min.js b/dist/modules/alert.tpl.min.js index 18fa29d4c..8619842c0 100644 --- a/dist/modules/alert.tpl.min.js +++ b/dist/modules/alert.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.js b/dist/modules/aside.js index 1ac253007..51c18d614 100644 --- a/dist/modules/aside.js +++ b/dist/modules/aside.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.min.js b/dist/modules/aside.min.js index 473cdb68d..78afd8bc9 100644 --- a/dist/modules/aside.min.js +++ b/dist/modules/aside.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.tpl.js b/dist/modules/aside.tpl.js index 1c188adf4..4e9509990 100644 --- a/dist/modules/aside.tpl.js +++ b/dist/modules/aside.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/aside.tpl.min.js b/dist/modules/aside.tpl.min.js index b80b21eb4..23b076936 100644 --- a/dist/modules/aside.tpl.min.js +++ b/dist/modules/aside.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/button.js b/dist/modules/button.js index 8dc73398f..f88a97347 100644 --- a/dist/modules/button.js +++ b/dist/modules/button.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/button.min.js b/dist/modules/button.min.js index 084edec60..1822eab13 100644 --- a/dist/modules/button.min.js +++ b/dist/modules/button.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/collapse.js b/dist/modules/collapse.js index 9937f5c63..8a0272ad7 100644 --- a/dist/modules/collapse.js +++ b/dist/modules/collapse.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/collapse.min.js b/dist/modules/collapse.min.js index c9a5f8f35..8f890d0af 100644 --- a/dist/modules/collapse.min.js +++ b/dist/modules/collapse.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/compiler.js b/dist/modules/compiler.js index c2e8917eb..4ceab7ea3 100644 --- a/dist/modules/compiler.js +++ b/dist/modules/compiler.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/compiler.min.js b/dist/modules/compiler.min.js index 9403bc571..179135101 100644 --- a/dist/modules/compiler.min.js +++ b/dist/modules/compiler.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';function bsCompilerService(e,t,n,l,r,a){function o(e,t){return angular.element((t||document).querySelectorAll(e))}function i(e){return c[e]?c[e]:c[e]=t.get(e,{cache:a}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var a=t.templateUrl,c=t.template||'',m=t.controller,u=t.controllerAs,p=angular.copy(t.resolve||{}),s=angular.copy(t.locals||{}),g=t.transformTemplate||angular.identity,d=t.bindToController;return angular.forEach(p,function(e,t){p[t]=angular.isString(e)?n.get(e):n.invoke(e)}),angular.extend(p,s),p.$template=a?i(a):e.when(c),t.contentTemplate&&(p.$template=e.all([p.$template,i(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),l=o('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||l.next().remove(),n[0].outerHTML})),e.all(p).then(function(e){var n=g(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),o=l(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,m){var n=r(m,e,!0);d&&angular.extend(n.instance,e);var l=angular.isObject(n)?n:n();a.data('$ngControllerController',l),a.children().data('$ngControllerController',l),u&&(t[u]=l)}return o.apply(null,arguments)}}})};var c={}}angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',bsCompilerService),bsCompilerService.$inject=['$q','$http','$injector','$compile','$controller','$templateCache']; +'use strict';function bsCompilerService(e,t,n,l,r,a){function o(e,t){return angular.element((t||document).querySelectorAll(e))}function i(e){return c[e]?c[e]:c[e]=t.get(e,{cache:a}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var a=t.templateUrl,c=t.template||'',m=t.controller,p=t.controllerAs,u=angular.copy(t.resolve||{}),s=angular.copy(t.locals||{}),g=t.transformTemplate||angular.identity,d=t.bindToController;return angular.forEach(u,function(e,t){angular.isString(e)?u[t]=n.get(e):u[t]=n.invoke(e)}),angular.extend(u,s),a?u.$template=i(a):u.$template=e.when(c),t.contentTemplate&&(u.$template=e.all([u.$template,i(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),l=o('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||l.next().remove(),n[0].outerHTML})),e.all(u).then(function(e){var n=g(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),o=l(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,m){var n=r(m,e,!0);d&&angular.extend(n.instance,e);var l=angular.isObject(n)?n:n();a.data('$ngControllerController',l),a.children().data('$ngControllerController',l),p&&(t[p]=l)}return o.apply(null,arguments)}}})};var c={}}angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',bsCompilerService),bsCompilerService.$inject=['$q','$http','$injector','$compile','$controller','$templateCache']; //# sourceMappingURL=../modules/compiler.min.js.map \ No newline at end of file diff --git a/dist/modules/compiler.min.js.map b/dist/modules/compiler.min.js.map index 2302dd806..ccc99eb7e 100644 --- a/dist/modules/compiler.min.js.map +++ b/dist/modules/compiler.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/compiler.js"],"names":["templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","$http","get","bsCompilerService","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","service","$inject"],"mappings":"AAOA,YAIA,SAmEQA,mBAAcC,EAAQD,EAAAA,EAAAA,EAAAA,EAAAA,GAF5B,QA4FyDE,GAAOC,EAAAA,GA3F9D,MA4FGC,SAAKC,SAASC,GAAAA,UAAAA,iBAAAA,IAzFnB,QAASC,GAAcC,GACrB,MAAIC,GAAcD,GAAkBC,EAAcD,GAC3CC,EAAcD,GAAYE,EAAMC,IAAIH,GA6F/CI,MAAAA,IA3FOR,KAAK,SAASE,GACf,MAAOA,GAAIO,OAzEfC,KAmEEC,QAAIP,SAAWP,GACXe,EAAAA,UAAaf,UAAQe,KAAAA,EAAAA,YACzBC,QAAIC,KAAAA,oGACJjB,EAAIkB,YAAkBC,EAAKnB,SAC3BA,EAAIoB,SAAiBD,GAErB,IAAIE,GAAAA,EAAmBrB,YAKvBsB,EAAQC,EAAQL,UAAkBM,GAChCT,EAAYU,EAASD,WACnBN,EAAeQ,EAAAA,aAtEfR,EAuEKI,QAAAH,KAAAnB,EAAAkB,aACLA,EAAQS,QAAOD,KAAAA,EAAUE,YAtEzBC,EAAoB7B,EAAQ6B,mBAAqBP,QAAQQ,SACzDT,EAAmBrB,EAAQqB,gBAsB/B,OAoDAC,SAAQS,QAAOb,EAASE,SAAAA,EAAAA,GAGtBF,EAAQc,GADNjC,QAAAA,SAAayB,GACPQ,EAAY1B,IAAAA,GAEZ0B,EAAeC,OAAK1B,KAvE9Be,QA4EEJ,OAAQc,EAAYE,GA1EpBhB,EA6EQiB,UADJpC,EACgBqC,EAAYrC,GAGVmC,EAAGG,KAAAA,GA5EvBrC,EAAQsC,kBAiFZpB,EAAUqB,UAAIrB,EAASf,KAAKe,EAASE,UAAAA,EAAAA,EAAAA,mBAAAA,KAAAA,SAAAA,GAEnC,GAAIb,GAAWsB,QAAAA,QAAkBT,EAAOY,IACpChC,EAAcoC,EAAA,sBAAAI,EAAA,IAAAC,WAAA,WAAAC,KAAAC,EAAA,GA/EhB,OAgFApC,GAAWA,aAASqC,EAAQC,OAAeC,SAhFpCN,EAAW,GAAGH,aAuFvBH,EAAAK,IAAArB,GAAAf,KAAA,SAAAiB,GAnFA,GAoFEA,GAAQA,EAAAA,EAAAA,UACRhB,GAASA,OACT2C,EAAMxC,EAAcyC,QAAAA,cAAAA,kBAlFtB,IAsFI5C,GAAIW,QAAYX,QAAA,SAAAsC,KAAAnC,EAAA0C,QAAAC,WArFhBC,EAsFMC,EAAAA,EArFV,QACEhC,OAsFME,EArFNlB,QAASA,EACT2C,KAuFI,SAAWzB,GArFb,GADAF,EAwFEhB,OAAa4C,EACb5C,EAAQiD,CAER,GAAIpC,GAAAA,EAAcF,EAAAK,GAAA,EAChB4B,IAxFA1B,QAAQS,OAAOqB,EAAWE,SAAUlC,EA4FxC,IAAAmC,GAAOJ,QAAaK,SAAMC,GAAAA,EAAAA,GAzFxBrD,GAAQQ,KAAK,0BAA2B2C,GACxCnD,EAAQiD,WAAWzC,KAAK,0BAA2B2C,GAC/CtC,IACF+B,EAAM/B,GAAgBsC,GAG1B,MAAOJ,GAAOO,MAAM,KAAMD,eAQlC,IAAIjD,MAtENc,QAkEMtB,OAAQO,0BAAWoD,QAAA,cAAAhD,mBAezBA,kBAAkBiD,SAAY,KAAM,QAAS,YAAa,WAAY,cAAe","file":"modules/compiler.min.js","sourcesContent":["'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/compiler.js"],"names":["templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","$http","get","bsCompilerService","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","service","$inject"],"mappings":"AAOA,YAIA,SAmEQA,mBAAcC,EAAQD,EAAAA,EAAAA,EAAAA,EAAAA,GAF5B,QA4FyDE,GAAOC,EAAAA,GA3F9D,MA4FGC,SAAKC,SAASC,GAAAA,UAAAA,iBAAAA,IAzFnB,QAASC,GAAcC,GACrB,MAAIC,GAAcD,GAAkBC,EAAcD,GAC3CC,EAAcD,GAAYE,EAAMC,IAAIH,GA6F/CI,MAAAA,IA3FOR,KAAK,SAASE,GACf,MAAOA,GAAIO,OAzEfC,KAmEEC,QAAIP,SAAWP,GACXe,EAAAA,UAAaf,UAAQe,KAAAA,EAAAA,YACzBC,QAAIC,KAAAA,oGACJjB,EAAIkB,YAAkBC,EAAKnB,SAC3BA,EAAIoB,SAAiBD,GAErB,IAAIE,GAAAA,EAAmBrB,YAKvBsB,EAAQC,EAAQL,UAAkBM,GAChCT,EAAYU,EAASD,WACnBN,EAAeQ,EAAAA,aAtEfR,EAuEKI,QAAAH,KAAAnB,EAAAkB,aACLA,EAAQS,QAAOD,KAAAA,EAAUE,YAtEzBC,EAAoB7B,EAAQ6B,mBAAqBP,QAAQQ,SACzDT,EAAmBrB,EAAQqB,gBAsB/B,OAoDAC,SAAQS,QAAOb,EAASE,SAAAA,EAAAA,GAEpBrB,QAAAA,SAAayB,GACfN,EAAQc,GAAAA,EAAY1B,IAAAA,GAEpBY,EAAQc,GAAAA,EAAeC,OAAK1B,KAvE9Be,QA4EEJ,OAAQc,EAAYE,GAEhBnC,EA5EJmB,EA6EQiB,UAAYC,EAAYrC,GA3EhCmB,EA8EIc,UAAkBE,EAAGG,KAAAA,GA5EvBrC,EAAQsC,kBAiFZpB,EAAUqB,UAAIrB,EAASf,KAAKe,EAASE,UAAAA,EAAAA,EAAAA,mBAAAA,KAAAA,SAAAA,GAEnC,GAAIb,GAAWsB,QAAAA,QAAkBT,EAAOY,IACpChC,EAAcoC,EAAA,sBAAAI,EAAA,IAAAC,WAAA,WAAAC,KAAAC,EAAA,GA/EhB,OAgFApC,GAAWA,aAASqC,EAAQC,OAAeC,SAhFpCN,EAAW,GAAGH,aAuFvBH,EAAAK,IAAArB,GAAAf,KAAA,SAAAiB,GAnFA,GAoFEA,GAAQA,EAAAA,EAAAA,UACRhB,GAASA,OACT2C,EAAMxC,EAAcyC,QAAAA,cAAAA,kBAlFtB,IAsFI5C,GAAIW,QAAYX,QAAA,SAAAsC,KAAAnC,EAAA0C,QAAAC,WArFhBC,EAsFMC,EAAAA,EArFV,QACEhC,OAsFME,EArFNlB,QAASA,EACT2C,KAuFI,SAAWzB,GArFb,GADAF,EAwFEhB,OAAa4C,EACb5C,EAAQiD,CAER,GAAIpC,GAAAA,EAAcF,EAAAK,GAAA,EAChB4B,IAxFA1B,QAAQS,OAAOqB,EAAWE,SAAUlC,EA4FxC,IAAAmC,GAAOJ,QAAaK,SAAMC,GAAAA,EAAAA,GAzFxBrD,GAAQQ,KAAK,0BAA2B2C,GACxCnD,EAAQiD,WAAWzC,KAAK,0BAA2B2C,GAC/CtC,IACF+B,EAAM/B,GAAgBsC,GAG1B,MAAOJ,GAAOO,MAAM,KAAMD,eAQlC,IAAIjD,MAtENc,QAkEMtB,OAAQO,0BAAWoD,QAAA,cAAAhD,mBAezBA,kBAAkBiD,SAAY,KAAM,QAAS,YAAa,WAAY,cAAe","file":"modules/compiler.min.js","sourcesContent":["'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/date-formatter.js b/dist/modules/date-formatter.js index 04af0da1f..71d82e647 100644 --- a/dist/modules/date-formatter.js +++ b/dist/modules/date-formatter.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-formatter.min.js b/dist/modules/date-formatter.min.js index 42169d220..00f97bc62 100644 --- a/dist/modules/date-formatter.min.js +++ b/dist/modules/date-formatter.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-parser.js b/dist/modules/date-parser.js index f4ee82b92..9ef3d5a4b 100644 --- a/dist/modules/date-parser.js +++ b/dist/modules/date-parser.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/date-parser.min.js b/dist/modules/date-parser.min.js index e182b4025..63d0194b4 100644 --- a/dist/modules/date-parser.min.js +++ b/dist/modules/date-parser.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(t){function e(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function s(t){return!isNaN(parseFloat(t))&&isFinite(t)}function r(t,e){for(var n=t.length,s=e.toString().toLowerCase(),r=0;n>r;r++)if(t[r].toLowerCase()===s)return r;return-1}e.prototype.setMilliseconds=function(t){this.milliseconds=t},e.prototype.setSeconds=function(t){this.seconds=t},e.prototype.setMinutes=function(t){this.minutes=t},e.prototype.setHours=function(t){this.hours=t},e.prototype.getHours=function(){return this.hours},e.prototype.setDate=function(t){this.day=t},e.prototype.setMonth=function(t){this.month=t},e.prototype.setFullYear=function(t){this.year=t},e.prototype.fromDate=function(t){return this.year=t.getFullYear(),this.month=t.getMonth(),this.day=t.getDate(),this.hours=t.getHours(),this.minutes=t.getMinutes(),this.seconds=t.getSeconds(),this.milliseconds=t.getMilliseconds(),this},e.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=e.prototype,o=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(t,a){var u=function(u){function h(t){var e,n=Object.keys(d),s=[],r=[],i=t;for(e=0;e1){var o=i.search(n[e]);t=t.split(n[e]).join(''),d[n[e]]&&(s[o]=d[n[e]])}return angular.forEach(s,function(t){t&&r.push(t)}),r}function l(t){return t.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function c(t){var e,n=Object.keys(p),s=t;for(e=0;e=1*t&&2===t.length?2e3+1*t:1*t)}};return m.init=function(){m.$format=t.DATETIME_FORMATS[g.format]||g.format,f=c(m.$format),M=h(m.$format)},m.isValid=function(t){return angular.isDate(t)?!isNaN(t.getTime()):f.test(t)},m.parse=function(n,s,r,i){r&&(r=t.DATETIME_FORMATS[r]||r),angular.isDate(n)&&(n=a(n,r||m.$format,i));var o=r?c(r):f,u=r?h(r):M,l=o.exec(n);if(!l)return!1;for(var g=(new e).fromDate(s&&!isNaN(s.getTime())?s:new Date(1970,0,1,0)),p=0;p12?t.getHours()+2:0),t):null},m.timezoneOffsetAdjust=function(t,e,n){return t?(e&&'UTC'===e&&(t=new Date(t.getTime()),t.setMinutes(t.getMinutes()+(n?-1:1)*t.getTimezoneOffset())),t):null},m.init(),m};return u}]}]); +'use strict';angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(t){function e(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function s(t){return!isNaN(parseFloat(t))&&isFinite(t)}function r(t,e){for(var n=t.length,s=e.toString().toLowerCase(),r=0;n>r;r++)if(t[r].toLowerCase()===s)return r;return-1}e.prototype.setMilliseconds=function(t){this.milliseconds=t},e.prototype.setSeconds=function(t){this.seconds=t},e.prototype.setMinutes=function(t){this.minutes=t},e.prototype.setHours=function(t){this.hours=t},e.prototype.getHours=function(){return this.hours},e.prototype.setDate=function(t){this.day=t},e.prototype.setMonth=function(t){this.month=t},e.prototype.setFullYear=function(t){this.year=t},e.prototype.fromDate=function(t){return this.year=t.getFullYear(),this.month=t.getMonth(),this.day=t.getDate(),this.hours=t.getHours(),this.minutes=t.getMinutes(),this.seconds=t.getSeconds(),this.milliseconds=t.getMilliseconds(),this},e.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=e.prototype,o=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(t,a){var u=function(u){function h(t){var e,n=Object.keys(D),s=[],r=[],i=t;for(e=0;e1){var o=i.search(n[e]);t=t.split(n[e]).join(''),D[n[e]]&&(s[o]=D[n[e]])}return angular.forEach(s,function(t){t&&r.push(t)}),r}function l(t){return t.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function c(t){var e,n=Object.keys(p),s=t;for(e=0;e=1*t&&2===t.length?this.setFullYear(2e3+1*t):this.setFullYear(1*t)}};return m.init=function(){m.$format=t.DATETIME_FORMATS[g.format]||g.format,f=c(m.$format),M=h(m.$format)},m.isValid=function(t){return angular.isDate(t)?!isNaN(t.getTime()):f.test(t)},m.parse=function(n,s,r,i){r&&(r=t.DATETIME_FORMATS[r]||r),angular.isDate(n)&&(n=a(n,r||m.$format,i));var o=r?c(r):f,u=r?h(r):M,l=o.exec(n);if(!l)return!1;for(var g=s&&!isNaN(s.getTime())?(new e).fromDate(s):(new e).fromDate(new Date(1970,0,1,0)),p=0;p12?t.getHours()+2:0),t):null},m.timezoneOffsetAdjust=function(t,e,n){return t?(e&&'UTC'===e&&(t=new Date(t.getTime()),t.setMinutes(t.getMinutes()+(n?-1:1)*t.getTimezoneOffset())),t):null},m.init(),m};return u}]}]); //# sourceMappingURL=../modules/date-parser.min.js.map \ No newline at end of file diff --git a/dist/modules/date-parser.min.js.map b/dist/modules/date-parser.min.js.map index 1d05ed740..adb84a6bc 100644 --- a/dist/modules/date-parser.min.js.map +++ b/dist/modules/date-parser.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/date-parser.js"],"names":["angular","this","seconds","provider","$localeProvider","milliseconds","year","ParseDate","prototype","hours","value","array","isNumeric","i","isNaN","parseFloat","n","isFinite","indexOfCaseInsensitive","defaults","len","length","str","toString","toLowerCase","format","strict","DateParserFactory","minutes","day","month","getFullYear","getHours","getMilliseconds","getMonth","Date","getMinutes","proto","noop","toDate","$dateParser","regExpMap","sss","$get","options","$locale","dateFilter","mm","config","split","keys","setFnMap","map","index","clonedFormat","forEach","search","v","sortedMap","push","regExpForFormat","re","join","text","replace","Object","escapeReservedSymbols","RegExp","regex","m","extend","HH","H","hh","h","a","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","match","setFullYear","setMap","init","$format","setMapForFormat","test","baseDate","formatRegex","formatSetMap","matches","date","getTime","timezone","newDate","parseInt","exec","fromDate","call","getDate","today","getDateForAttribute","key","isString","substr","getTimeForAttribute","time","daylightSavingAdjust","Infinity","parse","timezoneOffsetAdjust","undo"],"mappings":"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","file":"modules/date-parser.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/date-parser.js"],"names":["angular","this","seconds","provider","$localeProvider","milliseconds","year","ParseDate","prototype","hours","value","array","isNumeric","i","isNaN","parseFloat","n","isFinite","indexOfCaseInsensitive","defaults","len","length","str","toString","toLowerCase","format","strict","DateParserFactory","minutes","day","month","getFullYear","getHours","getMilliseconds","getMonth","Date","getMinutes","proto","noop","toDate","$dateParser","regExpMap","sss","$get","options","$locale","dateFilter","mm","config","split","keys","setFnMap","map","index","clonedFormat","forEach","search","v","sortedMap","push","regExpForFormat","re","join","text","replace","Object","escapeReservedSymbols","RegExp","regex","m","extend","HH","H","hh","h","a","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","match","setFullYear","setMap","init","setMapForFormat","$format","test","baseDate","formatRegex","formatSetMap","matches","date","getTime","timezone","newDate","parseInt","exec","fromDate","call","getDate","today","getDateForAttribute","key","isString","substr","getTimeForAttribute","time","daylightSavingAdjust","Infinity","parse","timezoneOffsetAdjust","undo"],"mappings":"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","file":"modules/date-parser.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/datepicker.js b/dist/modules/datepicker.js index a00a8654b..e77ad5aad 100644 --- a/dist/modules/datepicker.js +++ b/dist/modules/datepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.min.js b/dist/modules/datepicker.min.js index e66de4e60..9214cbcd0 100644 --- a/dist/modules/datepicker.min.js +++ b/dist/modules/datepicker.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$datepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','datepickerViews','$tooltip','$timeout',function(t,a,n,i,o,r,d,s){function l(t,a,n){function i(e){e.selected=l.$isSelected(e.date)}function o(){t[0].focus()}var l=d(t,angular.extend({},e,n)),g=n.scope,m=l.$options,f=l.$scope;m.startView&&(m.startView-=m.minView);var $=r(l);l.$views=$.views;var h=$.viewDate;f.$mode=m.startView,f.$iconLeft=m.iconLeft,f.$iconRight=m.iconRight;var D=l.$views[f.$mode];f.$select=function(e){l.select(e)},f.$selectPane=function(e){l.$selectPane(e)},f.$toggleMode=function(){l.setMode((f.$mode+1)%l.$views.length)},l.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(l.$date=e,D.update.call(D,e)),l.$build(!0)},l.updateDisabledDates=function(e){m.disabledDateRanges=e;for(var t=0,a=f.rows.length;a>t;t++)angular.forEach(f.rows[t],l.$setDisabledEl)},l.select=function(e,t){angular.isDate(a.$dateValue)||(a.$dateValue=new Date(e)),!f.$mode||t?(a.$setViewValue(angular.copy(e)),a.$render(),m.autoclose&&!t&&s(function(){l.hide(!0)})):(angular.extend(h,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),l.setMode(f.$mode-1),l.$build())},l.setMode=function(e){f.$mode=e,D=l.$views[f.$mode],l.$build()},l.$build=function(e){e===!0&&D.built||(e!==!1||D.built)&&D.build.call(D)},l.$updateSelected=function(){for(var e=0,t=f.rows.length;t>e;e++)angular.forEach(f.rows[e],i)},l.$isSelected=function(e){return D.isSelected(e)},l.$setDisabledEl=function(e){e.disabled=D.isDisabled(e.date)},l.$selectPane=function(e){var t=D.steps,a=new Date(Date.UTC(h.year+(t.year||0)*e,h.month+(t.month||0)*e,1));angular.extend(h,{year:a.getUTCFullYear(),month:a.getUTCMonth(),date:a.getUTCDate()}),l.$build()},l.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},l.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return f.$mode?f.$apply(function(){l.setMode(f.$mode-1)}):l.hide(!0);D.onKeyDown(e),g.$digest()}};var p=l.init;l.init=function(){return u&&m.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',o)),void p())};var y=l.destroy;l.destroy=function(){u&&m.useNative&&t.off('click',o),y()};var w=l.show;l.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(w(),s(function(){l.$isShown&&(l.$element.on(c?'touchstart':'mousedown',l.$onMouseDown),m.keyboard&&t.on('keydown',l.$onKeyDown))},0,!1))};var b=l.hide;return l.hide=function(e){l.$isShown&&(l.$element.off(c?'touchstart':'mousedown',l.$onMouseDown),m.keyboard&&t.off('keydown',l.$onKeyDown),b(e))},l}var u=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),c='createTouch'in t.document&&u;return e.lang||(e.lang=o.getDefaultLocale()),l.defaults=e,l}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,a,n,i,o){var r=(o.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,a,d){function s(e){return e&&e.length?e:null}function l(e){if(angular.isDate(e)){var t=isNaN(m.$options.minDate)||e.getTime()>=m.$options.minDate,a=isNaN(m.$options.maxDate)||e.getTime()<=m.$options.maxDate,n=t&&a;d.$setValidity('date',n),d.$setValidity('min',t),d.$setValidity('max',a),n&&(d.$dateValue=e)}}function u(){return!d.$dateValue||isNaN(d.$dateValue.getTime())?'':$(d.$dateValue,c.dateFormat)}var c={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(c[e]=a[e])});var g=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(a[e])&&g.test(a[e])&&(c[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){m&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?m.show():m.hide())});var m=o(t,d,c);c=m.$options,r&&c.useNative&&(c.dateFormat='yyyy-MM-dd');var f=c.lang,$=function(e,t){return n.formatDate(e,t,f)},h=i({format:c.dateFormat,lang:f,strict:c.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){m.$options[e]=h.getDateForAttribute(e,t),!isNaN(m.$options[e])&&m.$build(!1),l(d.$dateValue)})}),e.$watch(a.ngModel,function(e,t){m.update(d.$dateValue)},!0),angular.isDefined(a.disabledDates)&&e.$watch(a.disabledDates,function(e,t){e=s(e),t=s(t),e&&m.updateDisabledDates(e)}),d.$parsers.unshift(function(e){var t;if(!e)return d.$setValidity('date',!0),null;var a=h.parse(e,d.$dateValue);return!a||isNaN(a.getTime())?void d.$setValidity('date',!1):(l(a),'string'===c.dateType?(t=h.timezoneOffsetAdjust(a,c.timezone,!0),$(t,c.modelDateFormat||c.dateFormat)):(t=h.timezoneOffsetAdjust(d.$dateValue,c.timezone,!0),'number'===c.dateType?t.getTime():'unix'===c.dateType?t.getTime()/1e3:'iso'===c.dateType?t.toISOString():new Date(t)))}),d.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===c.dateType?h.parse(e,null,c.modelDateFormat):new Date('unix'===c.dateType?1e3*e:e),d.$dateValue=h.timezoneOffsetAdjust(t,c.timezone),u()}),d.$render=function(){t.val(u())},e.$on('$destroy',function(){m&&m.destroy(),c=null,m=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var a=[];e.length>0;)a.push(e.splice(0,t));return a}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(a,n,i){return function(o){var r=o.$scope,d=o.$options,s=d.lang,l=function(e,t){return a.formatDate(e,t,s)},u=n({format:d.dateFormat,lang:s,strict:d.strictFormat}),c=a.weekdaysShort(s),g=c.slice(d.startWeek).concat(c.slice(0,d.startWeek)),m=i.trustAsHtml(''+g.join('')+''),f=o.$date||(d.startDate?u.getDateForAttribute('startDate',d.startDate):new Date),$={year:f.getFullYear(),month:f.getMonth(),date:f.getDate()},h=[{format:d.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==$.year||e.getMonth()!==$.month?(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build()):(e.getDate()!==$.date||1===e.getDate())&&($.date=o.$date.getDate(),o.$updateSelected())},build:function(){var a=new Date($.year,$.month,1),n=a.getTimezoneOffset(),i=new Date(+a-864e5*t(a.getDay()-d.startWeek,7)),s=i.getTimezoneOffset(),c=u.timezoneOffsetAdjust(new Date,d.timezone).toDateString();s!==n&&(i=new Date(+i+6e4*(s-n)));for(var g,f=[],h=0;42>h;h++)g=u.daylightSavingAdjust(new Date(i.getFullYear(),i.getMonth(),i.getDate()+h)),f.push({date:g,isToday:g.toDateString()===c,label:l(g,this.format),selected:o.$date&&this.isSelected(g),muted:g.getMonth()!==$.month,disabled:this.isDisabled(g)});r.title=l(a,d.monthTitleFormat),r.showLabels=!0,r.labels=m,r.rows=e(f,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()&&e.getMonth()===o.$date.getMonth()&&e.getDate()===o.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(td.maxDate)return!0;if(-1!==d.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(d.disabledDateRanges)for(var a=0;a=d.disabledDateRanges[a].start&&t<=d.disabledDateRanges[a].end)return!0;return!1},onKeyDown:function(e){if(o.$date){var t,a=o.$date.getTime();37===e.keyCode?t=new Date(a-864e5):38===e.keyCode?t=new Date(a-6048e5):39===e.keyCode?t=new Date(a+864e5):40===e.keyCode&&(t=new Date(a+6048e5)),this.isDisabled(t)||o.select(t,!0)}}},{name:'month',format:d.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===$.year?e.getMonth()!==$.month&&(angular.extend($,{month:o.$date.getMonth(),date:o.$date.getDate()}),o.$updateSelected()):(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build())},build:function(){for(var t,a=(new Date($.year,0,1),[]),n=0;12>n;n++)t=new Date($.year,n,1),a.push({date:t,label:l(t,this.format),selected:o.$isSelected(t),disabled:this.isDisabled(t)});r.title=l(t,d.yearTitleFormat),r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()&&e.getMonth()===o.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return td.maxDate},onKeyDown:function(e){if(o.$date){var t=o.$date.getMonth(),a=new Date(o.$date);37===e.keyCode?a.setMonth(t-1):38===e.keyCode?a.setMonth(t-4):39===e.keyCode?a.setMonth(t+1):40===e.keyCode&&a.setMonth(t+4),this.isDisabled(a)||o.select(a,!0)}}},{name:'year',format:d.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt($.year/20,10)?(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build()):e.getFullYear()!==$.year&&(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$updateSelected())},build:function(){for(var t,a=$.year-$.year%(3*this.split),n=[],i=0;12>i;i++)t=new Date(a+i,0,1),n.push({date:t,label:l(t,this.format),selected:o.$isSelected(t),disabled:this.isDisabled(t)});r.title=n[0].label+'-'+n[n.length-1].label,r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return td.maxDate},onKeyDown:function(e){if(o.$date){var t=o.$date.getFullYear(),a=new Date(o.$date);37===e.keyCode?a.setYear(t-1):38===e.keyCode?a.setYear(t-4):39===e.keyCode?a.setYear(t+1):40===e.keyCode&&a.setYear(t+4),this.isDisabled(a)||o.select(a,!0)}}}];return{views:d.minView?Array.prototype.slice.call(h,d.minView):h,viewDate:$}}}]}); +'use strict';angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$datepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','datepickerViews','$tooltip','$timeout',function(t,a,n,i,o,r,d,s){function l(t,a,n){function i(e){e.selected=l.$isSelected(e.date)}function o(){t[0].focus()}var l=d(t,angular.extend({},e,n)),g=n.scope,m=l.$options,f=l.$scope;m.startView&&(m.startView-=m.minView);var $=r(l);l.$views=$.views;var h=$.viewDate;f.$mode=m.startView,f.$iconLeft=m.iconLeft,f.$iconRight=m.iconRight;var D=l.$views[f.$mode];f.$select=function(e){l.select(e)},f.$selectPane=function(e){l.$selectPane(e)},f.$toggleMode=function(){l.setMode((f.$mode+1)%l.$views.length)},l.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(l.$date=e,D.update.call(D,e)),l.$build(!0)},l.updateDisabledDates=function(e){m.disabledDateRanges=e;for(var t=0,a=f.rows.length;a>t;t++)angular.forEach(f.rows[t],l.$setDisabledEl)},l.select=function(e,t){angular.isDate(a.$dateValue)||(a.$dateValue=new Date(e)),!f.$mode||t?(a.$setViewValue(angular.copy(e)),a.$render(),m.autoclose&&!t&&s(function(){l.hide(!0)})):(angular.extend(h,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),l.setMode(f.$mode-1),l.$build())},l.setMode=function(e){f.$mode=e,D=l.$views[f.$mode],l.$build()},l.$build=function(e){e===!0&&D.built||(e!==!1||D.built)&&D.build.call(D)},l.$updateSelected=function(){for(var e=0,t=f.rows.length;t>e;e++)angular.forEach(f.rows[e],i)},l.$isSelected=function(e){return D.isSelected(e)},l.$setDisabledEl=function(e){e.disabled=D.isDisabled(e.date)},l.$selectPane=function(e){var t=D.steps,a=new Date(Date.UTC(h.year+(t.year||0)*e,h.month+(t.month||0)*e,1));angular.extend(h,{year:a.getUTCFullYear(),month:a.getUTCMonth(),date:a.getUTCDate()}),l.$build()},l.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},l.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return f.$mode?f.$apply(function(){l.setMode(f.$mode-1)}):l.hide(!0);D.onKeyDown(e),g.$digest()}};var p=l.init;l.init=function(){return u&&m.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',o)),void p())};var y=l.destroy;l.destroy=function(){u&&m.useNative&&t.off('click',o),y()};var w=l.show;l.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(w(),s(function(){l.$isShown&&(l.$element.on(c?'touchstart':'mousedown',l.$onMouseDown),m.keyboard&&t.on('keydown',l.$onKeyDown))},0,!1))};var b=l.hide;return l.hide=function(e){l.$isShown&&(l.$element.off(c?'touchstart':'mousedown',l.$onMouseDown),m.keyboard&&t.off('keydown',l.$onKeyDown),b(e))},l}var u=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),c='createTouch'in t.document&&u;return e.lang||(e.lang=o.getDefaultLocale()),l.defaults=e,l}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,a,n,i,o){var r=(o.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,a,d){function s(e){return e&&e.length?e:null}function l(e){if(angular.isDate(e)){var t=isNaN(m.$options.minDate)||e.getTime()>=m.$options.minDate,a=isNaN(m.$options.maxDate)||e.getTime()<=m.$options.maxDate,n=t&&a;d.$setValidity('date',n),d.$setValidity('min',t),d.$setValidity('max',a),n&&(d.$dateValue=e)}}function u(){return!d.$dateValue||isNaN(d.$dateValue.getTime())?'':$(d.$dateValue,c.dateFormat)}var c={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(c[e]=a[e])});var g=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(a[e])&&g.test(a[e])&&(c[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){m&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?m.show():m.hide())});var m=o(t,d,c);c=m.$options,r&&c.useNative&&(c.dateFormat='yyyy-MM-dd');var f=c.lang,$=function(e,t){return n.formatDate(e,t,f)},h=i({format:c.dateFormat,lang:f,strict:c.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){m.$options[e]=h.getDateForAttribute(e,t),!isNaN(m.$options[e])&&m.$build(!1),l(d.$dateValue)})}),e.$watch(a.ngModel,function(e,t){m.update(d.$dateValue)},!0),angular.isDefined(a.disabledDates)&&e.$watch(a.disabledDates,function(e,t){e=s(e),t=s(t),e&&m.updateDisabledDates(e)}),d.$parsers.unshift(function(e){var t;if(!e)return d.$setValidity('date',!0),null;var a=h.parse(e,d.$dateValue);return!a||isNaN(a.getTime())?void d.$setValidity('date',!1):(l(a),'string'===c.dateType?(t=h.timezoneOffsetAdjust(a,c.timezone,!0),$(t,c.modelDateFormat||c.dateFormat)):(t=h.timezoneOffsetAdjust(d.$dateValue,c.timezone,!0),'number'===c.dateType?t.getTime():'unix'===c.dateType?t.getTime()/1e3:'iso'===c.dateType?t.toISOString():new Date(t)))}),d.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===c.dateType?h.parse(e,null,c.modelDateFormat):'unix'===c.dateType?new Date(1e3*e):new Date(e),d.$dateValue=h.timezoneOffsetAdjust(t,c.timezone),u()}),d.$render=function(){t.val(u())},e.$on('$destroy',function(){m&&m.destroy(),c=null,m=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var a=[];e.length>0;)a.push(e.splice(0,t));return a}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(a,n,i){return function(o){var r=o.$scope,d=o.$options,s=d.lang,l=function(e,t){return a.formatDate(e,t,s)},u=n({format:d.dateFormat,lang:s,strict:d.strictFormat}),c=a.weekdaysShort(s),g=c.slice(d.startWeek).concat(c.slice(0,d.startWeek)),m=i.trustAsHtml(''+g.join('')+''),f=o.$date||(d.startDate?u.getDateForAttribute('startDate',d.startDate):new Date),$={year:f.getFullYear(),month:f.getMonth(),date:f.getDate()},h=[{format:d.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==$.year||e.getMonth()!==$.month?(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build()):(e.getDate()!==$.date||1===e.getDate())&&($.date=o.$date.getDate(),o.$updateSelected())},build:function(){var a=new Date($.year,$.month,1),n=a.getTimezoneOffset(),i=new Date(+a-864e5*t(a.getDay()-d.startWeek,7)),s=i.getTimezoneOffset(),c=u.timezoneOffsetAdjust(new Date,d.timezone).toDateString();s!==n&&(i=new Date(+i+6e4*(s-n)));for(var g,f=[],h=0;42>h;h++)g=u.daylightSavingAdjust(new Date(i.getFullYear(),i.getMonth(),i.getDate()+h)),f.push({date:g,isToday:g.toDateString()===c,label:l(g,this.format),selected:o.$date&&this.isSelected(g),muted:g.getMonth()!==$.month,disabled:this.isDisabled(g)});r.title=l(a,d.monthTitleFormat),r.showLabels=!0,r.labels=m,r.rows=e(f,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()&&e.getMonth()===o.$date.getMonth()&&e.getDate()===o.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(td.maxDate)return!0;if(-1!==d.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(d.disabledDateRanges)for(var a=0;a=d.disabledDateRanges[a].start&&t<=d.disabledDateRanges[a].end)return!0;return!1},onKeyDown:function(e){if(o.$date){var t,a=o.$date.getTime();37===e.keyCode?t=new Date(a-864e5):38===e.keyCode?t=new Date(a-6048e5):39===e.keyCode?t=new Date(a+864e5):40===e.keyCode&&(t=new Date(a+6048e5)),this.isDisabled(t)||o.select(t,!0)}}},{name:'month',format:d.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===$.year?e.getMonth()!==$.month&&(angular.extend($,{month:o.$date.getMonth(),date:o.$date.getDate()}),o.$updateSelected()):(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build())},build:function(){for(var t,a=(new Date($.year,0,1),[]),n=0;12>n;n++)t=new Date($.year,n,1),a.push({date:t,label:l(t,this.format),selected:o.$isSelected(t),disabled:this.isDisabled(t)});r.title=l(t,d.yearTitleFormat),r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()&&e.getMonth()===o.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return td.maxDate},onKeyDown:function(e){if(o.$date){var t=o.$date.getMonth(),a=new Date(o.$date);37===e.keyCode?a.setMonth(t-1):38===e.keyCode?a.setMonth(t-4):39===e.keyCode?a.setMonth(t+1):40===e.keyCode&&a.setMonth(t+4),this.isDisabled(a)||o.select(a,!0)}}},{name:'year',format:d.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt($.year/20,10)?(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$build()):e.getFullYear()!==$.year&&(angular.extend($,{year:o.$date.getFullYear(),month:o.$date.getMonth(),date:o.$date.getDate()}),o.$updateSelected())},build:function(){for(var t,a=$.year-$.year%(3*this.split),n=[],i=0;12>i;i++)t=new Date(a+i,0,1),n.push({date:t,label:l(t,this.format),selected:o.$isSelected(t),disabled:this.isDisabled(t)});r.title=n[0].label+'-'+n[n.length-1].label,r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return o.$date&&e.getFullYear()===o.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return td.maxDate},onKeyDown:function(e){if(o.$date){var t=o.$date.getFullYear(),a=new Date(o.$date);37===e.keyCode?a.setYear(t-1):38===e.keyCode?a.setYear(t-4):39===e.keyCode?a.setYear(t+1):40===e.keyCode&&a.setYear(t+4),this.isDisabled(a)||o.select(a,!0)}}}];return{views:d.minView?Array.prototype.slice.call(h,d.minView):h,viewDate:$}}}]}); //# sourceMappingURL=../modules/datepicker.min.js.map \ No newline at end of file diff --git a/dist/modules/datepicker.min.js.map b/dist/modules/datepicker.min.js.map index 400ebed82..e6d140e7f 100644 --- a/dist/modules/datepicker.min.js.map +++ b/dist/modules/datepicker.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/datepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","$get","bodyEl","isNative","DatepickerFactory","parentScope","config","scope","$datepicker","pickerViews","views","el","selected","date","element","focus","viewDate","options","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","value","$toggleMode","setMode","select","isDate","$build","length","updateDisabledDates","disabledDateRanges","dateRanges","$date","forEach","i","$dateValue","controller","$setViewValue","copy","$render","hide","keep","Date","extend","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","targetEl","$onKeyDown","nodeName","test","keyCode","shiftKey","altKey","$apply","updateSelected","onKeyDown","$digest","prop","init","attr","focusElement","_init","_destroy","destroy","off","_show","show","$timeout","_hide","on","blur","$element","directive","$options","$scope","require","restrict","$window","navigator","userAgent","link","falseValueRegExp","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","viewValue","$setValidity","getDateFormattedString","formatDate","bsShow","newValue","oldValue","isDefined","key","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","$watch","ngModel","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","$formatters","isUndefined","modelValue","NaN","daySplit","arr","mod","n","m","arrays","splice","size","push","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","title","showLabels","labels","time","isSelected","indexOf","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","Array","prototype"],"mappings":"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","file":"modules/datepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/datepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","$get","bodyEl","isNative","DatepickerFactory","parentScope","config","scope","$datepicker","pickerViews","views","el","selected","date","element","focus","viewDate","options","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","value","$toggleMode","setMode","select","isDate","$build","length","updateDisabledDates","disabledDateRanges","dateRanges","$date","forEach","i","$dateValue","controller","$setViewValue","copy","$render","hide","keep","Date","extend","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","targetEl","$onKeyDown","nodeName","test","keyCode","shiftKey","altKey","$apply","updateSelected","onKeyDown","$digest","prop","init","attr","focusElement","_init","_destroy","destroy","off","_show","show","$timeout","_hide","on","blur","$element","directive","$options","$scope","require","restrict","$window","navigator","userAgent","link","falseValueRegExp","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","viewValue","$setValidity","getDateFormattedString","formatDate","bsShow","newValue","oldValue","isDefined","key","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","$watch","ngModel","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","$formatters","isUndefined","modelValue","NaN","daySplit","arr","mod","n","m","arrays","splice","size","push","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","title","showLabels","labels","time","isSelected","indexOf","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","Array","prototype"],"mappings":"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","file":"modules/datepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/datepicker.tpl.js b/dist/modules/datepicker.tpl.js index 6dcaffa9c..31ee61d24 100644 --- a/dist/modules/datepicker.tpl.js +++ b/dist/modules/datepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/datepicker.tpl.min.js b/dist/modules/datepicker.tpl.min.js index 3cd076cc2..c679225c4 100644 --- a/dist/modules/datepicker.tpl.min.js +++ b/dist/modules/datepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/debounce.js b/dist/modules/debounce.js index d4642518d..e32bffbec 100644 --- a/dist/modules/debounce.js +++ b/dist/modules/debounce.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/debounce.min.js b/dist/modules/debounce.min.js index 81bd21576..1a492c73f 100644 --- a/dist/modules/debounce.min.js +++ b/dist/modules/debounce.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dimensions.js b/dist/modules/dimensions.js index e3ae9586c..075384b48 100644 --- a/dist/modules/dimensions.js +++ b/dist/modules/dimensions.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dimensions.min.js b/dist/modules/dimensions.min.js index 10283a71e..f52d6453f 100644 --- a/dist/modules/dimensions.min.js +++ b/dist/modules/dimensions.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dropdown.js b/dist/modules/dropdown.js index ee1737772..a8a8d1536 100644 --- a/dist/modules/dropdown.js +++ b/dist/modules/dropdown.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dropdown.min.js b/dist/modules/dropdown.min.js index 55a5c828b..289157a23 100644 --- a/dist/modules/dropdown.min.js +++ b/dist/modules/dropdown.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(o,n,t,r){function a(o,a){function c(e){return e.target!==o[0]?e.target!==o[0]&&d.hide():void 0}{var d={},s=angular.extend({},e,a);d.$scope=s.scope&&s.scope.$new()||n.$new()}d=t(o,s);var p=o.parent();d.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var o=angular.element(d.$element[0].querySelectorAll('li:not(.divider) a'));if(o.length){var n;angular.forEach(o,function(e,o){i&&i.call(e,':focus')&&(n=o)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n0?n--:40===e.keyCode&&n 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/dropdown.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","placement","bodyEl","matchesSelector","DropdownFactory","$dropdown","options","element","evt","keyCode","onBodyClick","directive","target","hide","stopPropagation","items","$element","querySelectorAll","$rootScope","$new","parentEl","index","forEach","preventDefault","focus","length","show","el","i","$onKeyDown","on","hasClass","$isShown","removeClass","destroy","off","scope","parent","prototype","$window","$sce","restrict","link","falseValueRegExp","attr","transclusion","bsDropdown","$watch","newValue","oldValue","content","dropdown","key","isString","match","bsShow","isDefined","$on"],"mappings":"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","file":"modules/dropdown.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/dropdown.tpl.js b/dist/modules/dropdown.tpl.js index 86ef430d3..2c4b0efac 100644 --- a/dist/modules/dropdown.tpl.js +++ b/dist/modules/dropdown.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/dropdown.tpl.min.js b/dist/modules/dropdown.tpl.min.js index e0b3cef67..ba2b9258d 100644 --- a/dist/modules/dropdown.tpl.min.js +++ b/dist/modules/dropdown.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.js b/dist/modules/modal.js index 4c3ebf5b0..b6c44e220 100644 --- a/dist/modules/modal.js +++ b/dist/modules/modal.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.min.js b/dist/modules/modal.min.js index 043e06341..3026b655f 100644 --- a/dist/modules/modal.min.js +++ b/dist/modules/modal.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.tpl.js b/dist/modules/modal.tpl.js index 29c95a551..2b137cc15 100644 --- a/dist/modules/modal.tpl.js +++ b/dist/modules/modal.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/modal.tpl.min.js b/dist/modules/modal.tpl.min.js index 5160fd001..d787f0a1d 100644 --- a/dist/modules/modal.tpl.min.js +++ b/dist/modules/modal.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/navbar.js b/dist/modules/navbar.js index d47a70002..946d7314b 100644 --- a/dist/modules/navbar.js +++ b/dist/modules/navbar.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/navbar.min.js b/dist/modules/navbar.min.js index d12a75cf5..3b50d9eb9 100644 --- a/dist/modules/navbar.min.js +++ b/dist/modules/navbar.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/parse-options.js b/dist/modules/parse-options.js index 2fc1a059b..4ee321c76 100644 --- a/dist/modules/parse-options.js +++ b/dist/modules/parse-options.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/parse-options.min.js b/dist/modules/parse-options.min.js index f9fdfba0b..33e989ca0 100644 --- a/dist/modules/parse-options.min.js +++ b/dist/modules/parse-options.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.js b/dist/modules/popover.js index fb7b055a4..0ae38375a 100644 --- a/dist/modules/popover.js +++ b/dist/modules/popover.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.min.js b/dist/modules/popover.min.js index 74cf35d31..b177418cb 100644 --- a/dist/modules/popover.min.js +++ b/dist/modules/popover.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var t=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(e){function n(n,a){var o=angular.extend({},t,a),r=e(n,o);return o.content&&(r.$scope.content=o.content),r}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(t,e,n){var a=t.requestAnimationFrame||t.setTimeout;return{restrict:'EAC',scope:!0,link:function(t,o,r){var i={scope:t};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(t){angular.isDefined(r[t])&&(i[t]=r[t])});var l=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(t){angular.isDefined(r[t])&&l.test(r[t])&&(i[t]=!1)});var c=o.attr('data-target');angular.isDefined(c)&&(i.target=l.test(c)?!1:c),angular.forEach(['title','content'],function(n){r[n]&&r.$observe(n,function(o,r){t[n]=e.trustAsHtml(o),angular.isDefined(r)&&a(function(){s&&s.$applyPlacement()})})}),r.bsPopover&&t.$watch(r.bsPopover,function(e,n){angular.isObject(e)?angular.extend(t,e):t.content=e,angular.isDefined(n)&&a(function(){s&&s.$applyPlacement()})},!0),r.bsShow&&t.$watch(r.bsShow,function(t,e){s&&angular.isDefined(t)&&(angular.isString(t)&&(t=!!t.match(/true|,?(popover),?/i)),t===!0?s.show():s.hide())}),r.viewport&&t.$watch(r.viewport,function(t){s&&angular.isDefined(t)&&s.setViewport(t)});var s=n(o,i);t.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var t=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(e){function n(n,a){var o=angular.extend({},t,a),r=e(n,o);return o.content&&(r.$scope.content=o.content),r}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(t,e,n){var a=t.requestAnimationFrame||t.setTimeout;return{restrict:'EAC',scope:!0,link:function(t,o,r){var i={scope:t};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(t){angular.isDefined(r[t])&&(i[t]=r[t])});var l=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(t){angular.isDefined(r[t])&&l.test(r[t])&&(i[t]=!1)});var c=o.attr('data-target');angular.isDefined(c)&&(l.test(c)?i.target=!1:i.target=c),angular.forEach(['title','content'],function(n){r[n]&&r.$observe(n,function(o,r){t[n]=e.trustAsHtml(o),angular.isDefined(r)&&a(function(){s&&s.$applyPlacement()})})}),r.bsPopover&&t.$watch(r.bsPopover,function(e,n){angular.isObject(e)?angular.extend(t,e):t.content=e,angular.isDefined(n)&&a(function(){s&&s.$applyPlacement()})},!0),r.bsShow&&t.$watch(r.bsShow,function(t,e){s&&angular.isDefined(t)&&(angular.isString(t)&&(t=!!t.match(/true|,?(popover),?/i)),t===!0?s.show():s.hide())}),r.viewport&&t.$watch(r.viewport,function(t){s&&angular.isDefined(t)&&s.setViewport(t)});var s=n(o,i);t.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}]); //# sourceMappingURL=../modules/popover.min.js.map \ No newline at end of file diff --git a/dist/modules/popover.min.js.map b/dist/modules/popover.min.js.map index 1d8980e10..12c2e90f9 100644 --- a/dist/modules/popover.min.js.map +++ b/dist/modules/popover.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/popover.js"],"names":["angular","templateUrl","provider","contentTemplate","defaults","trigger","keyboard","html","title","content","delay","autoClose","this","$get","options","$popover","PopoverFactory","element","config","$tooltip","restrict","directive","requestAnimationFrame","$window","link","scope","setTimeout","falseValueRegExp","attr","dataTarget","key","isDefined","forEach","$observe","oldValue","popover","target","test","bsPopover","$watch","isObject","newValue","extend","$applyPlacement","show","hide","setViewport","viewport","$on","destroy"],"mappings":"AAOA,YAEAA,SAMMC,OAAAA,0BAAa,2BAAAC,SAAA,WAAA,WALjB,GAMIC,GAAAA,KAAiBC,UACjBC,UAAS,UACTC,YAAU,GACVC,WAAM,EACNC,QAAO,EACPC,UAAS,QACTC,YAAO,2BACPC,iBAAW,EALbN,QAAS,QAQTO,UAAKC,EAEHN,MAAA,EAPFC,MAUQM,GATRL,QAWQM,GAVRL,MAaOI,EAZPH,WAaMI,EAXRH,MAcMC,MAAOE,WAAAA,SAAAA,GAbX,QAASC,GAAeC,EAASC,GAiB/B,GAAAJ,GAAOE,QAAAA,UAAAA,EAAAA,GAfHD,EAAWI,EAASF,EAASH,EA0BjCM,OALHC,GAAUZ,UAELa,EAAAA,OAAAA,QAAwBC,EAAQD,SAGlCF,EAEAI,MAAMR,OApBTK,UAuBoBI,aAAOA,UAAAA,OAAAA,WAAAA,SAAAA,EAAAA,EAAAA,GAtB5B,GAAIH,GAAwBC,EAAQD,uBAAyBC,EAAQG,UACrE,QACEN,SAsBSpB,MArBTyB,OAAO,EACPD,KAwBQG,SAAAA,EAAmBV,EAAAW,GACvB5B,GAAAA,IACEyB,MAAGzB,EAKLA,SAAI6B,SAAaZ,WAAa,cAAA,aAAA,eAAA,kBAAA,YAAA,YAAA,QAAA,UAAA,OAAA,YAAA,cAAA,YAAA,KAAA,cAAA,eAAA,SAAAa,GAC3B9B,QAAQ+B,UAAUF,EAAAA,MAAaf,EAAAgB,GAAAF,EAAAE,KAzBpC,IAAIH,GAAmB,eAiCrB3B,SAAQgC,SAAS,OAAA,YAAS,aAAqBF,SAAAA,GAC7CF,QAAKE,UAAaG,EAASH,KAAKH,EAAmBO,KAAAA,EAAAA,MAAAA,EAAAA,IAAAA,IA9BvD,IAgCMlC,GAAQ+B,EAAUG,KAAAA,cA/BpBlC,SAgCImC,UAAWA,KA/BsBrB,EAAQsB,OAA3CT,EAAiBU,KAAKR,IAA8B,EAA6BA,GAEvF7B,QAAQgC,SAAU,QAAS,WAAa,SAASF,GAmC/CF,EAAKU,IAAAA,EAAab,SAAMc,EAAOX,SAAKU,EAAWJ,GAC7CT,EAAGzB,GAAQwC,EAAAA,YAAoBC,GAC7BzC,QAAQ0C,UAAOjB,IAAOgB,EAAAA,WAjCtBN,GAkCKA,EAAAQ,wBA9BXf,EAkCMO,WAAWA,EAAQQ,OAAAA,EAAAA,UAAAA,SAAAA,EAAAA,GAjCnB3C,QAAQwC,SAASC,GAmClBzC,QAAA0C,OAAAjB,EAAAgB,GAIDhB,EAAIU,QAAYnC,EAEhByC,QAAAA,UAAaP,IAAeU,EAAiBC,WAnC7CV,GAAWA,EAAQQ,sBAwCnB,GArCJf,EAsCIO,QAAQW,EAAAA,OAAYL,EAAAA,OAAAA,SAAAA,EAAAA,GArCjBN,GAAYnC,QAAQ+B,UAAUU,KAyC/BN,QAAUpB,SAASE,KAASH,IAAAA,EAAAA,MAAAA,wBAGhCW,KAAU,EAAYU,EAAAS,OAAAT,EAAAU,UAxCxBjB,EA0CId,UAAUW,EAAAc,OAAAX,EAAAmB,SAAA,SAAAN,GACVN,GAAUnC,QAAA+B,UAAAU,IAzCZN,EAAQW,YAAYL,IAEtB,IAAIN,GAAUpB,EAASE,EAASH,EAChCW,GAAMuB,IAAI,WAAY,WAChBb,GAASA,EAAQc,UACrBnC,EAAU,KACVqB,EAAU","file":"modules/popover.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/popover.js"],"names":["angular","templateUrl","provider","contentTemplate","defaults","trigger","keyboard","html","title","content","delay","autoClose","this","$get","options","$popover","PopoverFactory","element","config","$tooltip","restrict","directive","requestAnimationFrame","$window","link","scope","setTimeout","falseValueRegExp","attr","dataTarget","key","isDefined","forEach","$observe","oldValue","popover","test","target","bsPopover","$watch","isObject","newValue","extend","$applyPlacement","show","hide","setViewport","viewport","$on","destroy"],"mappings":"AAOA,YAEAA,SAMMC,OAAAA,0BAAa,2BAAAC,SAAA,WAAA,WALjB,GAMIC,GAAAA,KAAiBC,UACjBC,UAAS,UACTC,YAAU,GACVC,WAAM,EACNC,QAAO,EACPC,UAAS,QACTC,YAAO,2BACPC,iBAAW,EALbN,QAAS,QAQTO,UAAKC,EAEHN,MAAA,EAPFC,MAUQM,GATRL,QAWQM,GAVRL,MAaOI,EAZPH,WAaMI,EAXRH,MAcMC,MAAOE,WAAAA,SAAAA,GAbX,QAASC,GAAeC,EAASC,GAiB/B,GAAAJ,GAAOE,QAAAA,UAAAA,EAAAA,GAfHD,EAAWI,EAASF,EAASH,EA0BjCM,OALHC,GAAUZ,UAELa,EAAAA,OAAAA,QAAwBC,EAAQD,SAGlCF,EAEAI,MAAMR,OApBTK,UAuBoBI,aAAOA,UAAAA,OAAAA,WAAAA,SAAAA,EAAAA,EAAAA,GAtB5B,GAAIH,GAAwBC,EAAQD,uBAAyBC,EAAQG,UACrE,QACEN,SAsBSpB,MArBTyB,OAAO,EACPD,KAwBQG,SAAAA,EAAmBV,EAAAW,GACvB5B,GAAAA,IACEyB,MAAGzB,EAKLA,SAAI6B,SAAaZ,WAAa,cAAA,aAAA,eAAA,kBAAA,YAAA,YAAA,QAAA,UAAA,OAAA,YAAA,cAAA,YAAA,KAAA,cAAA,eAAA,SAAAa,GAC3B9B,QAAQ+B,UAAUF,EAAAA,MAAaf,EAAAgB,GAAAF,EAAAE,KAzBpC,IAAIH,GAAmB,eAiCrB3B,SAAQgC,SAAS,OAAA,YAAS,aAAqBF,SAAAA,GAC7CF,QAAKE,UAAaG,EAASH,KAAKH,EAAmBO,KAAAA,EAAAA,MAAAA,EAAAA,IAAAA,IA9BvD,IAgCMlC,GAAQ+B,EAAUG,KAAAA,cA/BpBlC,SAgCImC,UAAWA,KA/BbR,EAAiBS,KAAKP,GAAaf,EAAQuB,QAAS,EAAYvB,EAAQuB,OAASR,GAEvF7B,QAAQgC,SAAU,QAAS,WAAa,SAASF,GAmC/CF,EAAKU,IAAAA,EAAab,SAAMc,EAAOX,SAAKU,EAAWJ,GAC7CT,EAAGzB,GAAQwC,EAAAA,YAAoBC,GAC7BzC,QAAQ0C,UAAOjB,IAAOgB,EAAAA,WAjCtBN,GAkCKA,EAAAQ,wBA9BXf,EAkCMO,WAAWA,EAAQQ,OAAAA,EAAAA,UAAAA,SAAAA,EAAAA,GAjCnB3C,QAAQwC,SAASC,GAmClBzC,QAAA0C,OAAAjB,EAAAgB,GAIDhB,EAAIU,QAAYnC,EAEhByC,QAAAA,UAAaP,IAAeU,EAAiBC,WAnC7CV,GAAWA,EAAQQ,sBAwCnB,GArCJf,EAsCIO,QAAQW,EAAAA,OAAYL,EAAAA,OAAAA,SAAAA,EAAAA,GArCjBN,GAAYnC,QAAQ+B,UAAUU,KAyC/BN,QAAUpB,SAASE,KAASH,IAAAA,EAAAA,MAAAA,wBAGhCW,KAAU,EAAYU,EAAAS,OAAAT,EAAAU,UAxCxBjB,EA0CId,UAAUW,EAAAc,OAAAX,EAAAmB,SAAA,SAAAN,GACVN,GAAUnC,QAAA+B,UAAAU,IAzCZN,EAAQW,YAAYL,IAEtB,IAAIN,GAAUpB,EAASE,EAASH,EAChCW,GAAMuB,IAAI,WAAY,WAChBb,GAASA,EAAQc,UACrBnC,EAAU,KACVqB,EAAU","file":"modules/popover.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/popover.tpl.js b/dist/modules/popover.tpl.js index 12f579058..be1d731f9 100644 --- a/dist/modules/popover.tpl.js +++ b/dist/modules/popover.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/popover.tpl.min.js b/dist/modules/popover.tpl.min.js index 16fef58a3..c5916d15e 100644 --- a/dist/modules/popover.tpl.min.js +++ b/dist/modules/popover.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/raf.js b/dist/modules/raf.js index cd9e99421..d657f756d 100644 --- a/dist/modules/raf.js +++ b/dist/modules/raf.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/raf.min.js b/dist/modules/raf.min.js index 11a8eac16..58c1aadf2 100644 --- a/dist/modules/raf.min.js +++ b/dist/modules/raf.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/scrollspy.js b/dist/modules/scrollspy.js index 6a99cd612..584264c59 100644 --- a/dist/modules/scrollspy.js +++ b/dist/modules/scrollspy.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/scrollspy.min.js b/dist/modules/scrollspy.min.js index bf70d6ce2..095fcad04 100644 --- a/dist/modules/scrollspy.min.js +++ b/dist/modules/scrollspy.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/select.js b/dist/modules/select.js index c8e7a40f3..9f38a1392 100644 --- a/dist/modules/select.js +++ b/dist/modules/select.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/select.min.js b/dist/modules/select.min.js index e0286c862..0d3e54743 100644 --- a/dist/modules/select.min.js +++ b/dist/modules/select.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,l,i){function o(a,o,c){var u={},s=angular.extend({},e,c);u=l(a,s);var d=u.$scope;d.$matches=[],d.$activeIndex=s.multiple?[]:-1,d.$isMultiple=s.multiple,d.$showAllNoneButtons=s.allNoneButtons&&s.multiple,d.$iconCheckmark=s.iconCheckmark,d.$allText=s.allText,d.$noneText=s.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=d.$matches.length?d.$activeIndex=s.multiple?[]:0:o.$modelValue||s.multiple||(d.$activeIndex=-1)},u.$isVisible=function(){return s.minLength&&o?d.$matches.length&&o.$viewValue.length>=s.minLength:d.$matches.length},u.$isActive=function(e){return s.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),r){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),s.multiple&&9===e.keyCode?u.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var $=u.show;u.show=function(){$(),s.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(r?'touchstart':'mousedown',u.$onMouseDown),s.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var m=u.hide;return u.hide=function(){s.multiple||o.$modelValue||(d.$activeIndex=-1),u.$element.off(r?'touchstart':'mousedown',u.$onMouseDown),s.keyboard&&a.off('keydown',u.$onKeyDown),m(!0)},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),r='createTouch'in t.document&&c;return o.defaults=e,o}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,l){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,o){var c={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&r.test(n[e])&&(c[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(c.multiple=r.test(u)?!1:u),'select'===t[0].nodeName.toLowerCase()){var s=t;s.css('display','none'),t=angular.element(''),s.after(t)}var d=l(n.bsOptions),$=a(t,o,c);$.$isIE()&&t[0].addEventListener('blur',$.$selectScrollFix);var m=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(m,function(t,n){d.valuesFn(e,o).then(function(e){$.update(e),o.$render()})}),e.$watch(n.ngModel,function(e,t){$.$updateActiveIndex(),o.$render()},!0),o.$render=function(){var e,n;c.multiple&&angular.isArray(o.$modelValue)?(e=o.$modelValue.map(function(e){return n=$.$getIndex(e),angular.isDefined(n)?$.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(c.maxLength||i.maxLength)?e.length+' '+(c.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=$.$getIndex(o.$modelValue),e=angular.isDefined(n)?$.$scope.$matches[n].label:!1),t.html((e?e:c.placeholder)+(c.caretHtml?c.caretHtml:i.caretHtml))},c.multiple&&(o.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){$&&$.destroy(),c=null,$=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,l,i){function o(a,o,c){var u={},s=angular.extend({},e,c);u=l(a,s);var d=u.$scope;d.$matches=[],s.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=s.multiple,d.$showAllNoneButtons=s.allNoneButtons&&s.multiple,d.$iconCheckmark=s.iconCheckmark,d.$allText=s.allText,d.$noneText=s.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e=d.$matches.length?d.$activeIndex=s.multiple?[]:0:o.$modelValue||s.multiple||(d.$activeIndex=-1)},u.$isVisible=function(){return s.minLength&&o?d.$matches.length&&o.$viewValue.length>=s.minLength:d.$matches.length},u.$isActive=function(e){return s.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),r){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),s.multiple&&9===e.keyCode?u.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var $=u.show;u.show=function(){$(),s.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(r?'touchstart':'mousedown',u.$onMouseDown),s.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var m=u.hide;return u.hide=function(){s.multiple||o.$modelValue||(d.$activeIndex=-1),u.$element.off(r?'touchstart':'mousedown',u.$onMouseDown),s.keyboard&&a.off('keydown',u.$onKeyDown),m(!0)},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),r='createTouch'in t.document&&c;return o.defaults=e,o}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,l){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,o){var c={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&r.test(n[e])&&(c[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(r.test(u)?c.multiple=!1:c.multiple=u),'select'===t[0].nodeName.toLowerCase()){var s=t;s.css('display','none'),t=angular.element(''),s.after(t)}var d=l(n.bsOptions),$=a(t,o,c);$.$isIE()&&t[0].addEventListener('blur',$.$selectScrollFix);var m=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(m,function(t,n){d.valuesFn(e,o).then(function(e){$.update(e),o.$render()})}),e.$watch(n.ngModel,function(e,t){$.$updateActiveIndex(),o.$render()},!0),o.$render=function(){var e,n;c.multiple&&angular.isArray(o.$modelValue)?(e=o.$modelValue.map(function(e){return n=$.$getIndex(e),angular.isDefined(n)?$.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(c.maxLength||i.maxLength)?e.length+' '+(c.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=$.$getIndex(o.$modelValue),e=angular.isDefined(n)?$.$scope.$matches[n].label:!1),t.html((e?e:c.placeholder)+(c.caretHtml?c.caretHtml:i.caretHtml))},c.multiple&&(o.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){$&&$.destroy(),c=null,$=null})}}}]); //# sourceMappingURL=../modules/select.min.js.map \ No newline at end of file diff --git a/dist/modules/select.min.js.map b/dist/modules/select.min.js.map index d1a459336..3eb7dac09 100644 --- a/dist/modules/select.min.js.map +++ b/dist/modules/select.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/select.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","bodyEl","isNative","isTouch","SelectFactory","$select","$tooltip","element","options","scope","$activeIndex","config","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","activate","index","$$postDigest","select","evt","$isActive","$isVisible","i","$selectNone","$matches","length","matches","$updateActiveIndex","b","a","controller","value","$apply","$setViewValue","hide","prefixEvent","$modelValue","$emit","map","$getIndex","minLength","$viewValue","l","indexOf","preventDefault","stopPropagation","targetEl","$onMouseDown","keyCode","$onKeyDown","test","$digest","isUndefined","$selectScrollFix","$isIE","stopImmediatePropagation","target","focus","ua","_show","show","activeElement","tagName","e","$element","addClass","$timeout","_hide","on","off","directive","$scope","$window","document","link","require","restrict","forEach","attr","falseValueRegExp","isDefined","dataMultiple","key","nodeName","toLowerCase","inputEl","after","css","addEventListener","watchedOptions","parsedOptions","valuesFn","update","values","ngModel","$match","newValue","oldValue","$render","selected","isArray","join","label","$isEmpty","$on","destroy"],"mappings":"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","file":"modules/select.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/select.js"],"names":["angular","trigger","provider","container","this","defaults","keyboard","html","delay","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","bodyEl","isNative","isTouch","SelectFactory","$select","$tooltip","element","options","scope","$activeIndex","config","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","activate","index","$$postDigest","select","evt","$isActive","$isVisible","i","$selectNone","$matches","length","matches","$updateActiveIndex","b","a","controller","value","$apply","$setViewValue","hide","prefixEvent","$modelValue","$emit","map","$getIndex","minLength","$viewValue","l","indexOf","preventDefault","stopPropagation","targetEl","$onMouseDown","keyCode","$onKeyDown","test","$digest","isUndefined","$selectScrollFix","$isIE","stopImmediatePropagation","target","focus","ua","_show","show","activeElement","tagName","e","$element","addClass","$timeout","_hide","on","off","directive","$scope","$window","document","link","require","restrict","forEach","attr","falseValueRegExp","isDefined","dataMultiple","key","nodeName","toLowerCase","inputEl","after","css","addEventListener","watchedOptions","parsedOptions","valuesFn","update","values","ngModel","$match","newValue","oldValue","$render","selected","isArray","join","label","$isEmpty","$on","destroy"],"mappings":"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","file":"modules/select.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n } else if(!controller.$modelValue && !options.multiple) {\n scope.$activeIndex = -1;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function() {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function(e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/select.tpl.js b/dist/modules/select.tpl.js index 92b053849..3f3839794 100644 --- a/dist/modules/select.tpl.js +++ b/dist/modules/select.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/select.tpl.min.js b/dist/modules/select.tpl.min.js index fbf53bde6..4e3932ba5 100644 --- a/dist/modules/select.tpl.min.js +++ b/dist/modules/select.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.js b/dist/modules/tab.js index a57e99dfc..d8898fbea 100644 --- a/dist/modules/tab.js +++ b/dist/modules/tab.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.min.js b/dist/modules/tab.min.js index fb590a2b8..e22febd4f 100644 --- a/dist/modules/tab.min.js +++ b/dist/modules/tab.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.tpl.js b/dist/modules/tab.tpl.js index 85f3abfe3..9cb4eb65d 100644 --- a/dist/modules/tab.tpl.js +++ b/dist/modules/tab.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tab.tpl.min.js b/dist/modules/tab.tpl.min.js index 86479db76..bf7614eca 100644 --- a/dist/modules/tab.tpl.min.js +++ b/dist/modules/tab.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/timepicker.js b/dist/modules/timepicker.js index 46e3d4748..045b1f3b5 100644 --- a/dist/modules/timepicker.js +++ b/dist/modules/timepicker.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/timepicker.min.js b/dist/modules/timepicker.min.js index 502fbf51e..37f2b8708 100644 --- a/dist/modules/timepicker.min.js +++ b/dist/modules/timepicker.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,i,o,r,s){function u(t,n,a){function i(e){var t=6e4*p.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function u(e,n){var a=e+n;if(t[0].createTextRange){var i=t[0].createTextRange();i.collapse(!0),i.moveStart('character',e),i.moveEnd('character',a),i.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function c(){t[0].focus()}var m=r(t,angular.extend({},e,a)),g=a.scope,p=m.$options,$=m.$scope,f=p.lang,h=function(e,t,n){return o.formatDate(e,t,f,n)},v=0,w=p.roundDisplay?i(new Date):new Date,S=n.$dateValue||w,y={hour:S.getHours(),meridian:S.getHours()<12,minute:S.getMinutes(),second:S.getSeconds(),millisecond:S.getMilliseconds()},D=o.getDatetimeFormat(p.timeFormat,f),T=o.hoursFormat(D),V=o.timeSeparator(D),b=o.minutesFormat(D),k=o.secondsFormat(D),M=o.showSeconds(D),x=o.showAM(D);$.$iconUp=p.iconUp,$.$iconDown=p.iconDown,$.$select=function(e,t){m.select(e,t)},$.$moveIndex=function(e,t){m.$moveIndex(e,t)},$.$switchMeridian=function(e){m.switchMeridian(e)},m.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(m.$date=e,angular.extend(y,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),m.$build()):m.$isBuilt||m.$build()},m.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),p.autoclose&&!a&&s(function(){m.hide(!0)})},m.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},m.$build=function(){var e,t,n=$.midIndex=parseInt(p.length/2,10),a=[];for(e=0;e1*p.maxTime},$.$arrowAction=function(e,t){'picker'===p.arrowBehavior?m.$setTimeByStep(e,t):m.$moveIndex(e,t)},m.$setTimeByStep=function(e,t){var n=new Date(m.$date||S),a=n.getHours(),i=n.getMinutes(),o=n.getSeconds();0===t?n.setHours(a-parseInt(p.hourStep,10)*e):1===t?n.setMinutes(i-parseInt(p.minuteStep,10)*e):2===t&&n.setSeconds(o-parseInt(p.secondStep,10)*e),m.select(n,t,!0)},m.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*p.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*p.length*p.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*p.length*p.secondStep),angular.extend(y,{second:n.getSeconds()})),m.$build()},m.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},m.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void m.hide(!0);var t=new Date(m.$date),n=t.getHours(),a=h(t,T).length,i=t.getMinutes(),o=h(t,b).length,r=t.getSeconds(),s=h(t,k).length,l=1,d=/(37|39)/.test(e.keyCode),c=2+1*M+1*x;d&&(37===e.keyCode?v=1>v?c-1:v-1:39===e.keyCode&&(v=c-1>v?v+1:0));var $=[0,a],f=0;38===e.keyCode&&(f=-1),40===e.keyCode&&(f=1);var w=2===v&&M,S=2===v&&!M||3===v&&M;0===v?(t.setHours(n+f*parseInt(p.hourStep,10)),a=h(t,T).length,$=[0,a]):1===v?(t.setMinutes(i+f*parseInt(p.minuteStep,10)),o=h(t,b).length,$=[a+l,o]):w?(t.setSeconds(r+f*parseInt(p.secondStep,10)),s=h(t,k).length,$=[a+l+o+l,s]):S&&(d||m.switchMeridian(),$=[a+l+o+l+(s+l)*M,2]),m.select(t,v,!0),u($[0],$[1]),g.$digest()}};var N=m.init;m.init=function(){return l&&p.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',c)),void N())};var F=m.destroy;m.destroy=function(){l&&p.useNative&&t.off('click',c),F()};var H=m.show;m.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(H(),s(function(){m.$element&&m.$element.on(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.on('keydown',m.$onKeyDown)},0,!1))};var I=m.hide;return m.hide=function(e){m.$isShown&&(m.$element&&m.$element.off(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.off('keydown',m.$onKeyDown),I(e))},m}var l=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),d='createTouch'in t.document&&l;return e.lang||(e.lang=o.getDefaultLocale()),u.defaults=e,u}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,i,o){var r=o.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,n,u){function l(e){if(angular.isDate(e)){var t=isNaN(c.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=c.minTime,n=isNaN(c.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=c.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,c.timeFormat)}var c={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var m=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&m.test(n[e])&&(c[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),s&&(c.useNative||r.useNative)&&(c.timeFormat='HH:mm');var g=o(t,u,c);c=g.$options;var p=c.lang,$=function(e,t,n){return a.formatDate(e,t,p,n)},f=i({format:c.timeFormat,lang:p});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){g.$options[e]=f.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),l(u.$dateValue)})}),e.$watch(n.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var n=angular.isDate(e)?e:f.parse(e,u.$dateValue);return!n||isNaN(n.getTime())?void u.$setValidity('date',!1):(l(n),'string'===c.timeType?(t=f.timezoneOffsetAdjust(n,c.timezone,!0),$(t,c.modelTimeFormat||c.timeFormat)):(t=f.timezoneOffsetAdjust(u.$dateValue,c.timezone,!0),'number'===c.timeType?t.getTime():'unix'===c.timeType?t.getTime()/1e3:'iso'===c.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===c.timeType?f.parse(e,null,c.modelTimeFormat):new Date('unix'===c.timeType?1e3*e:e),u.$dateValue=f.timezoneOffsetAdjust(t,c.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),c=null,g=null})}}}]); +'use strict';angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,i,o,r,s){function u(t,n,a){function i(e){var t=6e4*p.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function u(e,n){var a=e+n;if(t[0].createTextRange){var i=t[0].createTextRange();i.collapse(!0),i.moveStart('character',e),i.moveEnd('character',a),i.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function c(){t[0].focus()}var m=r(t,angular.extend({},e,a)),g=a.scope,p=m.$options,$=m.$scope,f=p.lang,h=function(e,t,n){return o.formatDate(e,t,f,n)},v=0,w=p.roundDisplay?i(new Date):new Date,S=n.$dateValue||w,y={hour:S.getHours(),meridian:S.getHours()<12,minute:S.getMinutes(),second:S.getSeconds(),millisecond:S.getMilliseconds()},D=o.getDatetimeFormat(p.timeFormat,f),T=o.hoursFormat(D),V=o.timeSeparator(D),b=o.minutesFormat(D),k=o.secondsFormat(D),N=o.showSeconds(D),M=o.showAM(D);$.$iconUp=p.iconUp,$.$iconDown=p.iconDown,$.$select=function(e,t){m.select(e,t)},$.$moveIndex=function(e,t){m.$moveIndex(e,t)},$.$switchMeridian=function(e){m.switchMeridian(e)},m.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(m.$date=e,angular.extend(y,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),m.$build()):m.$isBuilt||m.$build()},m.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),p.autoclose&&!a&&s(function(){m.hide(!0)})},m.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},m.$build=function(){var e,t,n=$.midIndex=parseInt(p.length/2,10),a=[];for(e=0;e1*p.maxTime},$.$arrowAction=function(e,t){'picker'===p.arrowBehavior?m.$setTimeByStep(e,t):m.$moveIndex(e,t)},m.$setTimeByStep=function(e,t){var n=new Date(m.$date||S),a=n.getHours(),i=n.getMinutes(),o=n.getSeconds();0===t?n.setHours(a-parseInt(p.hourStep,10)*e):1===t?n.setMinutes(i-parseInt(p.minuteStep,10)*e):2===t&&n.setSeconds(o-parseInt(p.secondStep,10)*e),m.select(n,t,!0)},m.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*p.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*p.length*p.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*p.length*p.secondStep),angular.extend(y,{second:n.getSeconds()})),m.$build()},m.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},m.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void m.hide(!0);var t=new Date(m.$date),n=t.getHours(),a=h(t,T).length,i=t.getMinutes(),o=h(t,b).length,r=t.getSeconds(),s=h(t,k).length,l=1,d=/(37|39)/.test(e.keyCode),c=2+1*N+1*M;d&&(37===e.keyCode?v=1>v?c-1:v-1:39===e.keyCode&&(v=c-1>v?v+1:0));var $=[0,a],f=0;38===e.keyCode&&(f=-1),40===e.keyCode&&(f=1);var w=2===v&&N,S=2===v&&!N||3===v&&N;0===v?(t.setHours(n+f*parseInt(p.hourStep,10)),a=h(t,T).length,$=[0,a]):1===v?(t.setMinutes(i+f*parseInt(p.minuteStep,10)),o=h(t,b).length,$=[a+l,o]):w?(t.setSeconds(r+f*parseInt(p.secondStep,10)),s=h(t,k).length,$=[a+l+o+l,s]):S&&(d||m.switchMeridian(),$=[a+l+o+l+(s+l)*N,2]),m.select(t,v,!0),u($[0],$[1]),g.$digest()}};var x=m.init;m.init=function(){return l&&p.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',c)),void x())};var F=m.destroy;m.destroy=function(){l&&p.useNative&&t.off('click',c),F()};var H=m.show;m.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(H(),s(function(){m.$element&&m.$element.on(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.on('keydown',m.$onKeyDown)},0,!1))};var I=m.hide;return m.hide=function(e){m.$isShown&&(m.$element&&m.$element.off(d?'touchstart':'mousedown',m.$onMouseDown),p.keyboard&&t&&t.off('keydown',m.$onKeyDown),I(e))},m}var l=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),d='createTouch'in t.document&&l;return e.lang||(e.lang=o.getDefaultLocale()),u.defaults=e,u}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,i,o){var r=o.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,n,u){function l(e){if(angular.isDate(e)){var t=isNaN(c.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=c.minTime,n=isNaN(c.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=c.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,c.timeFormat)}var c={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(c[e]=n[e])});var m=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(n[e])&&m.test(n[e])&&(c[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),s&&(c.useNative||r.useNative)&&(c.timeFormat='HH:mm');var g=o(t,u,c);c=g.$options;var p=c.lang,$=function(e,t,n){return a.formatDate(e,t,p,n)},f=i({format:c.timeFormat,lang:p});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){g.$options[e]=f.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),l(u.$dateValue)})}),e.$watch(n.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var n=angular.isDate(e)?e:f.parse(e,u.$dateValue);return!n||isNaN(n.getTime())?void u.$setValidity('date',!1):(l(n),'string'===c.timeType?(t=f.timezoneOffsetAdjust(n,c.timezone,!0),$(t,c.modelTimeFormat||c.timeFormat)):(t=f.timezoneOffsetAdjust(u.$dateValue,c.timezone,!0),'number'===c.timeType?t.getTime():'unix'===c.timeType?t.getTime()/1e3:'iso'===c.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===c.timeType?f.parse(e,null,c.modelTimeFormat):'unix'===c.timeType?new Date(1e3*e):new Date(e),u.$dateValue=f.timezoneOffsetAdjust(t,c.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),c=null,g=null})}}}]); //# sourceMappingURL=../modules/timepicker.min.js.map \ No newline at end of file diff --git a/dist/modules/timepicker.min.js.map b/dist/modules/timepicker.min.js.map index 81fc8e160..890f57660 100644 --- a/dist/modules/timepicker.min.js.map +++ b/dist/modules/timepicker.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["modules/timepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","length","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$get","$timepicker","$tooltip","element","extend","config","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","select","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","focus","_init","init","parentScope","floorMinutes","time","options","scope","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","controller","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$select","$moveIndex","value","index","$switchMeridian","switchMeridian","isDate","isNaN","getMinutes","getTime","$build","minute","$setViewValue","$timeout","keep","hide","Date","setHours","setMinutes","setSeconds","copy","$render","hours","midIndex","push","label","selected","$isSelected","disabled","i","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","parseInt","targetDate","$onMouseDown","evt","target","nodeName","stopPropagation","targetEl","triggerHandler","preventDefault","isTouch","$onKeyDown","test","keyCode","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","$digest","createTextRange","prop","attr","_destroy","destroy","off","_show","show","_hide","blur","$element","directive","$options","require","restrict","$window","navigator","userAgent","link","falseValueRegExp","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","bsShow","newValue","oldValue","timepicker","isDefined","key","forEach","dateParser","$dateParser","$observe","validateAgainstMinMaxTime","$watch","ngModel","getTimeForAttribute","parse","timezoneOffsetAdjust","$formatters","modelValue","NaN","$on"],"mappings":"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","file":"modules/timepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/timepicker.js"],"names":["angular","container","provider","keyboard","this","defaults","html","delay","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","length","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$get","$timepicker","$tooltip","element","extend","config","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","select","end","start","setSelectionRange","isUndefined","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","focus","_init","init","parentScope","floorMinutes","time","options","scope","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","controller","$dateValue","hoursFormat","$dateFormatter","$iconUp","$iconDown","$select","$moveIndex","value","index","$switchMeridian","switchMeridian","isDate","isNaN","getMinutes","getTime","$build","minute","$setViewValue","$timeout","keep","hide","Date","setHours","setMinutes","setSeconds","copy","$render","hours","midIndex","push","label","selected","$isSelected","disabled","i","minutes","seconds","minutesFormat","rows","showSeconds","secondsFormat","$isDisabled","showAM","timeSeparator","$date","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","parseInt","targetDate","$onMouseDown","evt","target","nodeName","stopPropagation","targetEl","triggerHandler","preventDefault","isTouch","$onKeyDown","test","keyCode","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","$digest","createTextRange","prop","attr","_destroy","destroy","off","_show","show","_hide","blur","$element","directive","$options","require","restrict","$window","navigator","userAgent","link","falseValueRegExp","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","bsShow","newValue","oldValue","timepicker","isDefined","key","forEach","dateParser","$dateParser","$observe","validateAgainstMinMaxTime","$watch","ngModel","getTimeForAttribute","parse","timezoneOffsetAdjust","$formatters","modelValue","NaN","$on"],"mappings":"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","file":"modules/timepicker.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/timepicker.tpl.js b/dist/modules/timepicker.tpl.js index f0d4920ed..114d7c3c6 100644 --- a/dist/modules/timepicker.tpl.js +++ b/dist/modules/timepicker.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/timepicker.tpl.min.js b/dist/modules/timepicker.tpl.min.js index a80a56900..f86e4367b 100644 --- a/dist/modules/timepicker.tpl.min.js +++ b/dist/modules/timepicker.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tooltip.js b/dist/modules/tooltip.js index 86df4aa8b..278b0b933 100644 --- a/dist/modules/tooltip.js +++ b/dist/modules/tooltip.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tooltip.min.js b/dist/modules/tooltip.min.js index 98a2640b8..0ce124596 100644 --- a/dist/modules/tooltip.min.js +++ b/dist/modules/tooltip.min.js @@ -1,9 +1,9 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -'use strict';angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var t=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(e,o,n,i,r,l,a,s,f,c,u){function p(i,r){function l(){U.$emit(A.prefixEvent+'.show',F)}function p(){if(U.$emit(A.prefixEvent+'.hide',F),q===j){if(V&&'focus'===A.trigger)return i[0].blur();P()}}function $(){var t=A.trigger.split(' ');angular.forEach(t,function(t){'click'===t?i.on('click',F.toggle):'manual'!==t&&(i.on('hover'===t?'mouseenter':'focus',F.enter),i.on('hover'===t?'mouseleave':'blur',F.leave),'button'===H&&'hover'!==t&&i.on(g?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function v(){for(var t=A.trigger.split(' '),e=t.length;e--;){var o=t[e];'click'===o?i.off('click',F.toggle):'manual'!==o&&(i.off('hover'===o?'mouseenter':'focus',F.enter),i.off('hover'===o?'mouseleave':'blur',F.leave),'button'===H&&'hover'!==o&&i.off(g?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function w(){'focus'!==A.trigger?q.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==A.trigger?q.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function y(){u(function(){q.on('click',E),m.on('click',F.hide),L=!0},0,!1)}function k(){L&&(q.off('click',E),m.off('click',F.hide),L=!1)}function E(t){t.stopPropagation()}function C(t){t=t||A.target||i;var o=t[0],n='BODY'===o.tagName,r=o.getBoundingClientRect(),l={};for(var a in r)l[a]=r[a];null===l.width&&(l=angular.extend({},l,{width:r.right-r.left,height:r.bottom-r.top}));var s=n?{top:0,left:0}:f.offset(o),c={scroll:n?document.documentElement.scrollTop||document.body.scrollTop:t.prop('scrollTop')||0},u=n?{width:document.documentElement.clientWidth,height:e.innerHeight}:null;return angular.extend({},l,c,u,s)}function S(t,e,o,n){var i,r=t.split('-');switch(r[0]){case'right':i={top:e.top+e.height/2-n/2,left:e.left+e.width};break;case'bottom':i={top:e.top+e.height,left:e.left+e.width/2-o/2};break;case'left':i={top:e.top+e.height/2-n/2,left:e.left-o};break;default:i={top:e.top-n,left:e.left+e.width/2-o/2}}if(!r[1])return i;if('top'===r[0]||'bottom'===r[0])switch(r[1]){case'left':i.left=e.left;break;case'right':i.left=e.left+e.width-o}else if('left'===r[0]||'right'===r[0])switch(r[1]){case'top':i.top=e.top-n;break;case'bottom':i.top=e.top+e.height}return i}function D(t,e){var o=q[0],n=o.offsetWidth,i=o.offsetHeight,r=parseInt(f.css(o,'margin-top'),10),l=parseInt(f.css(o,'margin-left'),10);isNaN(r)&&(r=0),isNaN(l)&&(l=0),t.top=t.top+r,t.left=t.left+l,f.setOffset(o,angular.extend({using:function(t){q.css({top:Math.round(t.top)+'px',left:Math.round(t.left)+'px',right:''})}},t),0);var a=o.offsetWidth,s=o.offsetHeight;if('top'===e&&s!==i&&(t.top=t.top+i-s),!/top-left|top-right|bottom-left|bottom-right/.test(e)){var c=x(e,t,a,s);if(c.left?t.left+=c.left:t.top+=c.top,f.setOffset(o,t),/top|right|bottom|left/.test(e)){var u=/top|bottom/.test(e),p=u?2*c.left-n+a:2*c.top-i+s,h=u?'offsetWidth':'offsetHeight';T(p,o[h],u)}}}function x(t,e,o,n){var i={top:0,left:0};if(!F.$viewport)return i;var r=A.viewport&&A.viewport.padding||0,l=C(F.$viewport);if(/right|left/.test(t)){var a=e.top-r-l.scroll,s=e.top+r-l.scroll+n;al.top+l.height&&(i.top=l.top+l.height-s)}else{var f=e.left-r,c=e.left+r+o;fl.right&&(i.left=l.left+l.width-c)}return i}function T(t,e,o){var n=d('.tooltip-arrow, .arrow',q[0]);n.css(o?'left':'top',50*(1-t/e)+'%').css(o?'top':'left','')}function P(){clearTimeout(K),F.$isShown&&null!==q&&(A.autoClose&&k(),A.keyboard&&b()),I&&(I.$destroy(),I=null),q&&(q.remove(),q=F.$element=null)}var F={},A=F.$options=angular.extend({},t,r),O=F.$promise=n.compile(A),U=F.$scope=A.scope&&A.scope.$new()||o.$new(),H=i[0].nodeName.toLowerCase();if(A.delay&&angular.isString(A.delay)){var N=A.delay.split(',').map(parseFloat);A.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=A.id||i.attr('id')||'',A.title&&(U.title=s.trustAsHtml(A.title)),U.$setEnabled=function(t){U.$$postDigest(function(){F.setEnabled(t)})},U.$hide=function(){U.$$postDigest(function(){F.hide()})},U.$show=function(){U.$$postDigest(function(){F.show()})},U.$toggle=function(){U.$$postDigest(function(){F.toggle()})},F.$isShown=U.$isShown=!1;var K,M,W,q,B,I;O.then(function(t){W=t,F.init()}),F.init=function(){A.delay&&angular.isNumber(A.delay)&&(A.delay={show:A.delay,hide:A.delay}),'self'===A.container?B=i:angular.isElement(A.container)?B=A.container:A.container&&(B=d(A.container)),$(),A.target&&(A.target=angular.isElement(A.target)?A.target:d(A.target)),A.show&&U.$$postDigest(function(){'focus'===A.trigger?i[0].focus():F.show()})},F.destroy=function(){v(),P(),U.$destroy()},F.enter=function(){return clearTimeout(K),M='in',A.delay&&A.delay.show?void(K=setTimeout(function(){'in'===M&&F.show()},A.delay.show)):F.show()},F.show=function(){if(A.bsEnabled&&!F.$isShown){U.$emit(A.prefixEvent+'.show.before',F);var t,e;A.container?(t=B,e=B[0].lastChild?angular.element(B[0].lastChild):null):(t=null,e=i),q&&P(),I=F.$scope.$new(),q=F.$element=W.link(I,function(t,e){}),q.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),A.animation&&q.addClass(A.animation),A.type&&q.addClass(A.prefixClass+'-'+A.type),A.customClass&&q.addClass(A.customClass),e?e.after(q):t.prepend(q),F.$isShown=U.$isShown=!0,h(U),F.$applyPlacement(),angular.version.minor<=2?a.enter(q,t,e,l):a.enter(q,t,e).then(l),h(U),c(function(){q&&q.css({visibility:'visible'})}),A.keyboard&&('focus'!==A.trigger&&F.focus(),w()),A.autoClose&&y()}},F.leave=function(){return clearTimeout(K),M='out',A.delay&&A.delay.hide?void(K=setTimeout(function(){'out'===M&&F.hide()},A.delay.hide)):F.hide()};var V,j;F.hide=function(t){F.$isShown&&(U.$emit(A.prefixEvent+'.hide.before',F),V=t,j=q,angular.version.minor<=2?a.leave(q,p):a.leave(q).then(p),F.$isShown=U.$isShown=!1,h(U),A.keyboard&&null!==q&&b(),A.autoClose&&null!==q&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){q[0].focus()},F.setEnabled=function(t){A.bsEnabled=t},F.setViewport=function(t){A.viewport=t},F.$applyPlacement=function(){if(q){var e=A.placement,o=/\s?auto?\s?/i,n=o.test(e);n&&(e=e.replace(o,'')||t.placement),q.addClass(A.placement);var i=C(),r=q.prop('offsetWidth'),l=q.prop('offsetHeight');if(F.$viewport=A.viewport&&d(A.viewport.selector||A.viewport),n){var a=e,s=C(F.$viewport);a.indexOf('bottom')>=0&&i.bottom+l>s.bottom?e=a.replace('bottom','top'):a.indexOf('top')>=0&&i.top-ls.width?e='right'===a?'left':e.replace('left','right'):('left'===a||'bottom-right'===a||'top-right'===a)&&i.left-rl.top+l.height&&(i.top=l.top+l.height-s)}else{var f=e.left-r,c=e.left+r+o;fl.right&&(i.left=l.left+l.width-c)}return i}function T(t,e,o){var n=d('.tooltip-arrow, .arrow',q[0]);n.css(o?'left':'top',50*(1-t/e)+'%').css(o?'top':'left','')}function P(){clearTimeout(K),F.$isShown&&null!==q&&(A.autoClose&&E(),A.keyboard&&b()),I&&(I.$destroy(),I=null),q&&(q.remove(),q=F.$element=null)}var F={},A=F.$options=angular.extend({},t,r),O=F.$promise=n.compile(A),U=F.$scope=A.scope&&A.scope.$new()||o.$new(),H=i[0].nodeName.toLowerCase();if(A.delay&&angular.isString(A.delay)){var N=A.delay.split(',').map(parseFloat);A.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=A.id||i.attr('id')||'',A.title&&(U.title=s.trustAsHtml(A.title)),U.$setEnabled=function(t){U.$$postDigest(function(){F.setEnabled(t)})},U.$hide=function(){U.$$postDigest(function(){F.hide()})},U.$show=function(){U.$$postDigest(function(){F.show()})},U.$toggle=function(){U.$$postDigest(function(){F.toggle()})},F.$isShown=U.$isShown=!1;var K,M,W,q,B,I;O.then(function(t){W=t,F.init()}),F.init=function(){A.delay&&angular.isNumber(A.delay)&&(A.delay={show:A.delay,hide:A.delay}),'self'===A.container?B=i:angular.isElement(A.container)?B=A.container:A.container&&(B=d(A.container)),$(),A.target&&(A.target=angular.isElement(A.target)?A.target:d(A.target)),A.show&&U.$$postDigest(function(){'focus'===A.trigger?i[0].focus():F.show()})},F.destroy=function(){v(),P(),U.$destroy()},F.enter=function(){return clearTimeout(K),M='in',A.delay&&A.delay.show?void(K=setTimeout(function(){'in'===M&&F.show()},A.delay.show)):F.show()},F.show=function(){if(A.bsEnabled&&!F.$isShown){U.$emit(A.prefixEvent+'.show.before',F);var t,e;A.container?(t=B,e=B[0].lastChild?angular.element(B[0].lastChild):null):(t=null,e=i),q&&P(),I=F.$scope.$new(),q=F.$element=W.link(I,function(t,e){}),q.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),A.animation&&q.addClass(A.animation),A.type&&q.addClass(A.prefixClass+'-'+A.type),A.customClass&&q.addClass(A.customClass),e?e.after(q):t.prepend(q),F.$isShown=U.$isShown=!0,h(U),F.$applyPlacement(),angular.version.minor<=2?a.enter(q,t,e,l):a.enter(q,t,e).then(l),h(U),c(function(){q&&q.css({visibility:'visible'})}),A.keyboard&&('focus'!==A.trigger&&F.focus(),w()),A.autoClose&&y()}},F.leave=function(){return clearTimeout(K),M='out',A.delay&&A.delay.hide?void(K=setTimeout(function(){'out'===M&&F.hide()},A.delay.hide)):F.hide()};var V,j;F.hide=function(t){F.$isShown&&(U.$emit(A.prefixEvent+'.hide.before',F),V=t,j=q,angular.version.minor<=2?a.leave(q,p):a.leave(q).then(p),F.$isShown=U.$isShown=!1,h(U),A.keyboard&&null!==q&&b(),A.autoClose&&null!==q&&E())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){q[0].focus()},F.setEnabled=function(t){A.bsEnabled=t},F.setViewport=function(t){A.viewport=t},F.$applyPlacement=function(){if(q){var e=A.placement,o=/\s?auto?\s?/i,n=o.test(e);n&&(e=e.replace(o,'')||t.placement),q.addClass(A.placement);var i=C(),r=q.prop('offsetWidth'),l=q.prop('offsetHeight');if(F.$viewport=A.viewport&&d(A.viewport.selector||A.viewport),n){var a=e,s=C(F.$viewport);a.indexOf('bottom')>=0&&i.bottom+l>s.bottom?e=a.replace('bottom','top'):a.indexOf('top')>=0&&i.top-ls.width?e='right'===a?'left':e.replace('left','right'):('left'===a||'bottom-right'===a||'top-right'===a)&&i.left-r 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["modules/tooltip.js"],"names":["angular","target","provider","placement","this","defaults","templateUrl","template","contentTemplate","trigger","keyboard","html","show","title","type","delay","autoClose","bsEnabled","viewport","selector","padding","$get","String","htmlReplaceRegExp","$body","options","$tooltip","extend","config","split","enterAnimateCallback","scope","$emit","prefixEvent","leaveAnimateCallback","_tipToHide","leave","$isShown","element","blur","tipElement","nodeName","forEach","triggers","on","toggle","unbindTriggerEvents","enter","i","length","off","bindKeyboardEvents","$onKeyUp","isTouch","$onFocusElementMouseDown","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$timeout","hide","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","$element","rect","stopPropagation","width","elRect","height","p","top","left","dimensions","offset","el","scroll","isBody","document","documentElement","$window","getCalculatedOffset","position","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","parseInt","using","props","css","isNaN","right","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","test","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","findElement","$arrow","clearTimeout","timeout","tipScope","$destroy","$$phase","$options","$promise","$bsCompiler","compile","$scope","$new","$rootScope","toLowerCase","$id","attr","map","parseFloat","$sce","trustAsHtml","$setEnabled","$$postDigest","id","$hide","setEnabled","isEnabled","compileData","promise","then","init","container","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","link","clonedElement","safeDigest","version","minor","addClass","animation","$animate","customClass","$$rAF","$applyPlacement","focus","_blur","replace","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","indexOf","tipHeight","removeClass","tipPosition","applyPlacement","tipWidth","evt","preventDefault","fetchTemplate","fetchPromises","cache","$templateCache","res","isString","directive","$location","restrict","falseValueRegExp","transclusion","dataTarget","key","isDefined","hasOwnProperty","oldValue","tooltip","$observe","newValue","bsTooltip","$watch","isObject","bsShow","match","setViewport","$on","destroy"],"mappings":"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","file":"modules/tooltip.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/modules/tooltip.tpl.js b/dist/modules/tooltip.tpl.js index 42c6da53b..04b9a5145 100644 --- a/dist/modules/tooltip.tpl.js +++ b/dist/modules/tooltip.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/tooltip.tpl.min.js b/dist/modules/tooltip.tpl.min.js index d6f447c0f..2aa847ae8 100644 --- a/dist/modules/tooltip.tpl.min.js +++ b/dist/modules/tooltip.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.js b/dist/modules/typeahead.js index 0a46699ac..d335d62ae 100644 --- a/dist/modules/typeahead.js +++ b/dist/modules/typeahead.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.min.js b/dist/modules/typeahead.min.js index 4deff1e12..308197971 100644 --- a/dist/modules/typeahead.min.js +++ b/dist/modules/typeahead.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.tpl.js b/dist/modules/typeahead.tpl.js index 869bbe10f..4081d5c3d 100644 --- a/dist/modules/typeahead.tpl.js +++ b/dist/modules/typeahead.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/dist/modules/typeahead.tpl.min.js b/dist/modules/typeahead.tpl.min.js index 521f43610..b27eaf281 100644 --- a/dist/modules/typeahead.tpl.min.js +++ b/dist/modules/typeahead.tpl.min.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.2 - 2015-09-15 + * @version v2.3.3 - 2015-09-24 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT diff --git a/package.json b/package.json index e9c6dbbb1..e3c813463 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "angular-strap", "description": "AngularStrap - AngularJS directives for Bootstrap", - "version": "2.3.2", + "version": "2.3.3", "keywords": [ "angular", "bootstrap"