{"version":3,"sources":["angular-strap.js","tooltip/tooltip.js","helpers/compiler.js","navbar/navbar.js","typeahead/typeahead.js","tab/tab.js","timepicker/timepicker.js","scrollspy/scrollspy.js","select/select.js","popover/popover.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","modal/modal.js","dropdown/dropdown.js","aside/aside.js","datepicker/datepicker.js","collapse/collapse.js","button/button.js","alert/alert.js","affix/affix.js","module.js"],"names":["prefixEvent","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","defaults","this","activeClass","data","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","contentEl","findElement","contentTemplate","removeAttr","html","templates","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","target","provider","placement","trigger","keyboard","show","title","type","delay","autoClose","bsEnabled","viewport","selector","padding","$get","String","htmlReplaceRegExp","$body","$tooltip","config","split","enterAnimateCallback","$emit","leaveAnimateCallback","_tipToHide","leave","$isShown","blur","tipElement","nodeName","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","$arrow","clearTimeout","timeout","tipScope","$destroy","$$phase","$options","$promise","$bsCompiler","$scope","$new","$rootScope","toLowerCase","$id","attr","map","parseFloat","$sce","trustAsHtml","$setEnabled","$$postDigest","id","$hide","setEnabled","isEnabled","compileData","promise","init","container","tipContainer","bindTriggerEvents","isElement","destroyTipElement","hoverState","parent","after","lastChild","display","visibility","clonedElement","safeDigest","version","minor","addClass","animation","$animate","customClass","$$rAF","$applyPlacement","focus","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","tipHeight","tipWidth","removeClass","tipPosition","applyPlacement","evt","preventDefault","directive","$location","restrict","falseValueRegExp","transclusion","dataTarget","isDefined","hasOwnProperty","oldValue","tooltip","$observe","newValue","bsTooltip","$watch","bsShow","match","setViewport","$on","destroy","minLength","filter","limit","autoSelect","comparator","trimValue","bodyEl","$typeahead","$matches","$resetMatches","activate","$activeIndex","select","index","$select","matches","$isVisible","update","$render","parentScope","l","$viewValue","keyCode","$digest","$onMouseDown","$onKeyDown","TypeaheadFactory","array","isFunction","body","$filter","expression","results","require","bsOptions","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","ngModel","$modelValue","valuesFn","selectMode","$setViewValue","substring","displayValue","slice","$formatters","push","modelValue","selected","val","label","toString","self","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","isUndefined","$active","$attrs","$navClass","$remove","active","activeIndex","indexOf","splice","$setActive","name","fn","$pane","$tab","transclude","postLink","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","render","$isActive","disabled","prefixClass","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","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","keep","Date","setHours","setMinutes","setSeconds","hours","midIndex","$isSelected","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","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","activeElement","source","$getTrackedElement","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","scrollspy","childEl","querySelectorAll","child","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","$apply","isArray","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","tagName","e","dataMultiple","inputEl","addEventListener","join","$isEmpty","content","$popover","PopoverFactory","requestAnimationFrame","popover","bsPopover","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","$values","regexp","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","literalRegex","formatParts","escapedLiteralFormat","dateElements","keys","escapedFormat","isFormatStringLiteral","part","trimLiteralEscapeChars","dateRegexParts","escapeReservedSymbols","text","re","abstractRegex","buildDateParseRegex","setMapForFormat","buildDateAbstractRegex","buildDateParseValuesMap","Object","valuesMatch","keyIndex","valuesFunctionMap","valuesRegex","valueKey","valueFunction","setFnMap","exec","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","regExpForFormat","$format","baseDate","formatRegex","formatSetMap","fromDate","getDate","today","getDateForAttribute","substr","daylightSavingAdjust","undo","getTimezoneOffset","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","backdrop","bodyElement","backdropCount","backdropBaseZindex","ModalFactory","$modal","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","destroyModalElement","modalScope","$show","bottom","z-index","defaultPrevented","backdropAnimation","bindBackdropEvents","which","$root","query","dialogBaseZindex","bsModal","modal","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","tAttrs","nextSibling","nodeType","parentNode","removeChild","bsDropdown","dropdown","AsideFactory","$aside","bsAside","aside","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","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","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: 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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\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 if (/top/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('top', 'bottom');\n } else if (/bottom/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('bottom', 'top');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = 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 + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\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: 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 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: 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: 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: 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: 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(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\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 && angular.isUndefined(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.$watch(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 }, true);\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: 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: 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 regExpForFormat(format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex(format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n }\n else {\n // Abstract replaces to avoid collisions\n for(var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral(text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars(text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex(abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for(var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat(format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap(abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch, keyIndex, valueKey, valueFunction;\n var valuesFunctionMap = [];\n\n while((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\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 (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\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: 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 var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\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'});\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(options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\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(options.backdrop) {\n // decrement number of modals\n backdropCount--;\n }\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: 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 compile: function(tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling.classList.contains('dropdown-menu')) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function(key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[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\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: 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 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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\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\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 // 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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: 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.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 // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\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 if (/top/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('top', 'bottom');\n } else if (/bottom/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('bottom', 'top');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = 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 + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\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\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 (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\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.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.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 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\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.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.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.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(options.multiple) {\n if(angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if(angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\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 && angular.isUndefined(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.$watch(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 }, true);\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.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\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 regExpForFormat(format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex(format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n }\n else {\n // Abstract replaces to avoid collisions\n for(var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral(text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars(text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex(abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for(var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat(format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap(abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch, keyIndex, valueKey, valueFunction;\n var valuesFunctionMap = [];\n\n while((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\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.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 var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\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'});\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(options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\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(options.backdrop) {\n // decrement number of modals\n backdropCount--;\n }\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\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 compile: function(tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling.classList.contains('dropdown-menu')) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function(key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[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","'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.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 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 $datepicker.hide(true);\n } else {\n scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\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\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 // 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 // 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 // Observe date format\n angular.isDefined(attr.dateFormat) && attr.$observe('dateFormat', function(newValue) {\n datepicker.$options.dateFormat = newValue;\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\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/"}