rails-angular-strap 2.3.1 → 2.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,11 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.1 - 2015-07-19
3
+ * @version v2.3.7 - 2016-01-16
4
4
  * @link http://mgcrea.github.io/angular-strap
5
5
  * @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
6
6
  * @license MIT License, http://www.opensource.org/licenses/MIT
7
7
  */
8
- !function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){d[t]=angular.isString(e)?a.get(e):a.invoke(e)}),angular.extend(d,f),d.$template=n?l(n):e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('<div>').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse']),angular.module('mgcrea.ngStrap.affix',['mgcrea.ngStrap.helpers.dimensions','mgcrea.ngStrap.helpers.debounce']).provider('$affix',function(){var e=this.defaults={offsetTop:'auto',inlineStyles:!0};this.$get=['$window','debounce','dimensions',function(t,n,a){function o(o,s){function l(e,t,n){var a=u(),o=c();return v>=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')),'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap.alert',['mgcrea.ngStrap.modal']).provider('$alert',function(){var e=this.defaults={animation:'am-fade',prefixClass:'alert',prefixEvent:'alert',placement:null,templateUrl:'alert/alert.tpl.html',container:!1,element:null,backdrop:!1,keyboard:!0,show:!0,duration:!1,type:!1,dismissable:!0};this.$get=['$modal','$timeout',function(t,n){function a(a){var o={},i=angular.extend({},e,a);o=t(i),o.$scope.dismissable=!!i.dismissable,i.type&&(o.$scope.type=i.type);var r=o.show;return i.duration&&(o.show=function(){r(),n(function(){o.hide()},1e3*i.duration)}),o}return a}]}).directive('bsAlert',['$window','$sce','$alert',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','placement','keyboard','html','container','animation','duration','dismissable'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['keyboard','html','container','dismissable'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),e.hasOwnProperty('title')||(e.title=''),angular.forEach(['title','content','type'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAlert&&e.$watch(o.bsAlert,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.aside',['mgcrea.ngStrap.modal']).provider('$aside',function(){var e=this.defaults={animation:'am-fade-and-slide-right',prefixClass:'aside',prefixEvent:'aside',placement:'right',templateUrl:'aside/aside.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$modal',function(t){function n(n){var a={},o=angular.extend({},e,n);return a=t(o)}return n}]}).directive('bsAside',['$window','$sce','$aside',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAside&&e.$watch(o.bsAside,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.button',[]).provider('$button',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s=a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n<t.length;n++)e<t[n]&&(t[n]=t[n]-1),t[n]===l.$targets.length&&(t[n]=l.$targets.length-1)}function i(e){var t=l.$targets.$active;return-1===t.indexOf(e)?!1:!0}function r(e){var t=l.$targets.$active.indexOf(e);-1!==t&&l.$targets.$active.splice(t,1)}function s(e){l.$options.allowMultiple||l.$targets.$active.splice(0,1),-1===l.$targets.$active.indexOf(e)&&l.$targets.$active.push(e)}var l=this;l.$options=angular.copy(e),angular.forEach(['animation','disallowToggle','activeClass','startCollapsed','allowMultiple'],function(e){angular.isDefined(a[e])&&(l.$options[e]=a[e])});var u=/^(false|0|)$/i;angular.forEach(['disallowToggle','startCollapsed','allowMultiple'],function(e){angular.isDefined(a[e])&&u.test(a[e])&&(l.$options[e]=!1)}),l.$toggles=[],l.$targets=[],l.$viewChangeListeners=[],l.$registerToggle=function(e){l.$toggles.push(e)},l.$registerTarget=function(e){l.$targets.push(e)},l.$unregisterToggle=function(e){var t=l.$toggles.indexOf(e);l.$toggles.splice(t,1)},l.$unregisterTarget=function(e){var t=l.$targets.indexOf(e);l.$targets.splice(t,1),l.$options.allowMultiple&&r(e),o(t),l.$viewChangeListeners.forEach(function(e){e()})},l.$targets.$active=l.$options.startCollapsed?[]:[0],l.$setActive=t.$setActive=function(e){angular.isArray(e)?l.$targets.$active=e:l.$options.disallowToggle?s(e):i(e)?r(e):s(e),l.$viewChangeListeners.forEach(function(e){e()})},l.$activeIndexes=function(){return l.$options.allowMultiple?l.$targets.$active:1===l.$targets.$active.length?l.$targets.$active[0]:-1}};this.$get=function(){var n={};return n.defaults=e,n.controller=t,n}}).directive('bsCollapse',['$window','$animate','$collapse',function(e,t,n){n.defaults;return{require:['?ngModel','bsCollapse'],controller:['$scope','$element','$attrs',n.controller],link:function(e,t,n,a){var o=a[0],i=a[1];o&&(i.$viewChangeListeners.push(function(){o.$setViewValue(i.$activeIndexes())}),o.$formatters.push(function(e){if(angular.isArray(e))i.$setActive(e);else{var t=i.$activeIndexes();angular.isArray(t)?-1===t.indexOf(1*e)&&i.$setActive(1*e):t!==1*e&&i.$setActive(1*e)}return e}))}}}]).directive('bsCollapseToggle',function(){return{require:['^?ngModel','^bsCollapse'],link:function(e,t,n,a){var o=(a[0],a[1]);t.attr('data-toggle','collapse'),o.$registerToggle(t),e.$on('$destroy',function(){o.$unregisterToggle(t)}),t.on('click',function(){var a=n.bsCollapseToggle&&'bs-collapse-toggle'!==n.bsCollapseToggle?n.bsCollapseToggle:o.$toggles.indexOf(t);o.$setActive(1*a),e.$apply()})}}}).directive('bsCollapseTarget',['$animate',function(e){return{require:['^?ngModel','^bsCollapse'],link:function(t,n,a,o){function i(){var t=r.$targets.indexOf(n),a=r.$activeIndexes(),o='removeClass';angular.isArray(a)?-1!==a.indexOf(t)&&(o='addClass'):t===a&&(o='addClass'),e[o](n,r.$options.activeClass)}var r=(o[0],o[1]);n.addClass('collapse'),r.$options.animation&&n.addClass(r.$options.animation),r.$registerTarget(n),t.$on('$destroy',function(){r.$unregisterTarget(n)}),r.$viewChangeListeners.push(function(){i()}),i()}}}]),angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$datepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','datepickerViews','$tooltip','$timeout',function(t,n,a,o,i,r,s,l){function u(t,n,a){function o(e){e.selected=u.$isSelected(e.date)}function i(){t[0].focus()}var u=s(t,angular.extend({},e,a)),f=a.scope,p=u.$options,g=u.$scope;p.startView&&(p.startView-=p.minView);var m=r(u);u.$views=m.views;var $=m.viewDate;g.$mode=p.startView,g.$iconLeft=p.iconLeft,g.$iconRight=p.iconRight;var h=u.$views[g.$mode];g.$select=function(e){u.select(e)},g.$selectPane=function(e){u.$selectPane(e)},g.$toggleMode=function(){u.setMode((g.$mode+1)%u.$views.length)},u.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(u.$date=e,h.update.call(h,e)),u.$build(!0)},u.updateDisabledDates=function(e){p.disabledDateRanges=e;for(var t=0,n=g.rows.length;n>t;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):new Date('unix'===d.dateType?1e3*e:e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml('<th class="dow text-center">'+f.join('</th><th class="dow text-center">')+'</th>'),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(t<s.minDate||t>s.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n<s.disabledDateRanges.length;n++)if(t>=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return t<s.minDate||e.getTime()>s.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return t<s.minDate||e.getTime()>s.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}{var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new()}u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n<t.length-1?n++:angular.isUndefined(n)&&(n=0),t.eq(n)[0].focus()}}};var f=u.show;u.show=function(){f(),o(function(){c.keyboard&&u.$element&&u.$element.on('keydown',u.$onKeyDown),r.on('click',l)},0,!1),d.hasClass('dropdown')&&d.addClass('open')};var p=u.hide;u.hide=function(){u.$isShown&&(c.keyboard&&u.$element&&u.$element.off('keydown',u.$onKeyDown),r.off('click',l),d.hasClass('dropdown')&&d.removeClass('open'),p())};var g=u.destroy;return u.destroy=function(){r.off('click',l),g()},u}var r=angular.element(t.document.body),s=Element.prototype.matchesSelector||Element.prototype.webkitMatchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector;return i}]}).directive('bsDropdown',['$window','$sce','$dropdown',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,t,a,o){var i={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','id'],function(e){angular.isDefined(a[e])&&(i[e]=a[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(a[e])&&r.test(a[e])&&(i[e]=!1)}),a.bsDropdown&&e.$watch(a.bsDropdown,function(t,n){e.content=t},!0),a.bsShow&&e.$watch(a.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(dropdown),?/i)),e===!0?s.show():s.hide())});var s=n(t,i);e.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t<n.length;t++)if(e.split(n[t]).length>1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t<n.length;t++)a=a.split(n[t]).join('${'+t+'}');for(t=0;t<n.length;t++)a=a.split('${'+t+'}').join('('+$[n[t]]+')');return e=c(e),new RegExp('^'+a+'$',['i'])}var f,p,g=angular.extend({},r,l),m={},$={sss:'[0-9]{3}',ss:'[0-5][0-9]',s:g.strict?'[1-5]?[0-9]':'[0-9]|[0-5][0-9]',mm:'[0-5][0-9]',m:g.strict?'[1-5]?[0-9]':'[0-9]|[0-5][0-9]',HH:'[01][0-9]|2[0-3]',H:g.strict?'1?[0-9]|2[0-3]':'[01]?[0-9]|2[0-3]',hh:'[0][1-9]|[1][012]',h:g.strict?'[1-9]|1[012]':'0?[1-9]|1[012]',a:'AM|PM',EEEE:e.DATETIME_FORMATS.DAY.join('|'),EEE:e.DATETIME_FORMATS.SHORTDAY.join('|'),dd:'0[1-9]|[12][0-9]|3[01]',d:g.strict?'[1-9]|[1-2][0-9]|3[01]':'0?[1-9]|[1-2][0-9]|3[01]',MMMM:e.DATETIME_FORMATS.MONTH.join('|'),MMM:e.DATETIME_FORMATS.SHORTMONTH.join('|'),MM:'0[1-9]|1[012]',M:g.strict?'[1-9]|1[012]':'0?[1-9]|1[012]',yyyy:'[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',yy:'[0-9]{2}',y:g.strict?'-?(0|[1-9][0-9]{0,3})':'-?0*[0-9]{1,4}'},h={sss:i.setMilliseconds,ss:i.setSeconds,s:i.setSeconds,mm:i.setMinutes,m:i.setMinutes,HH:i.setHours,H:i.setHours,hh:i.setHours,h:i.setHours,EEEE:n,EEE:n,dd:i.setDate,d:i.setDate,a:function(e){var t=this.getHours()%12;return this.setHours(e.match(/pm/i)?t+12:t)},MMMM:function(t){return this.setMonth(o(e.DATETIME_FORMATS.MONTH,t))},MMM:function(t){return this.setMonth(o(e.DATETIME_FORMATS.SHORTMONTH,t))},MM:function(e){return this.setMonth(1*e-1)},M:function(e){return this.setMonth(1*e-1)},yyyy:i.setFullYear,yy:function(e){return this.setFullYear(2e3+1*e)},y:function(e){return this.setFullYear(50>=1*e&&2===e.length?2e3+1*e:1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=(new t).fromDate(a&&!isNaN(a.getTime())?a:new Date(1970,0,1,0)),$=0;$<c.length-1;$++)l[$]&&l[$].call(g,c[$+1]);var h=g.toDate();return parseInt(g.day,10)!==h.getDate()?!1:h},m.getDateForAttribute=function(e,t){var n;if('today'===t){var o=new Date;n=new Date(o.getFullYear(),o.getMonth(),o.getDate()+('maxDate'===e?1:0),0,0,0,'minDate'===e?0:-1)}else n=angular.isString(t)&&t.match(/^".+"$/)?new Date(t.substr(1,t.length-2)):a(t)?new Date(parseInt(t,10)):angular.isString(t)&&0===t.length?'minDate'===e?-(1/0):+(1/0):new Date(t);return n},m.getTimeForAttribute=function(e,t){var n;return n='now'===t?(new Date).setFullYear(1970,0,1):angular.isString(t)&&t.match(/^".+"$/)?new Date(t.substr(1,t.length-2)).setFullYear(1970,0,1):a(t)?new Date(parseInt(t,10)).setFullYear(1970,0,1):angular.isString(t)&&0===t.length?'minTime'===e?-(1/0):+(1/0):m.parse(t,new Date(1970,0,1,0));
9
-
10
- },m.daylightSavingAdjust=function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l,u,c,d){function f(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function i(){k.$emit(b.prefixEvent+'.hide',y),h.removeClass(b.prefixClass+'-open'),b.animation&&h.removeClass(b.prefixClass+'-with-'+b.animation)}function r(){b.backdrop&&(x.on('click',f),C.on('click',f),C.on('wheel',v))}function s(){b.backdrop&&(x.off('click',f),C.off('click',f),C.off('wheel',v))}function u(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function d(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function f(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(s(),d()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',m(['title','content'],function(e){b[e]&&(k[e]=c.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('<div class="'+b.prefixClass+'-backdrop"/>');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=g(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&l.enter(C,h,null),angular.version.minor<=2?l.enter(x,e,t,n):l.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,p(k);var a=x[0];$(function(){a.focus()}),h.addClass(b.prefixClass+'-open'),b.animation&&h.addClass(b.prefixClass+'-with-'+b.animation),r(),u()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?l.leave(x,i):l.leave(x).then(i),b.backdrop&&l.leave(C),y.$isShown=k.$isShown=!1,p(k),s(),d()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function p(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function g(e,n){return angular.element((n||t).querySelectorAll(e))}var m=angular.forEach,$=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),h=angular.element(n.document.body);return f}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','controller','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(r.target=s.test(l)?!1:l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),S<C[0].offsetTop&&w!==C[0].target)return x.$activateElement(C[0]);for(var e=C.length;e--;)if(!angular.isUndefined(C[e].offsetTop)&&null!==C[e].offsetTop&&w!==C[e].target&&!(S<C[e].offsetTop||C[e+1]&&S>C[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:'&nbsp;<span class="caret"></span>',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(t,n,a){var r={},s=angular.extend({},e,a);r=o(t,s);var u=r.$scope;u.$matches=[],u.$activeIndex=s.multiple?[]:-1,u.$isMultiple=s.multiple,u.$showAllNoneButtons=s.allNoneButtons&&s.multiple,u.$iconCheckmark=s.iconCheckmark,u.$allText=s.allText,u.$noneText=s.noneText,u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},u.$isActive=function(e){return r.$isActive(e)},u.$selectAll=function(){for(var e=0;e<u.$matches.length;e++)u.$isActive(e)||u.$select(e)},u.$selectNone=function(){for(var e=0;e<u.$matches.length;e++)u.$isActive(e)&&u.$select(e)},r.update=function(e){u.$matches=e,r.$updateActiveIndex()},r.activate=function(e){return s.multiple?(r.$isActive(e)?u.$activeIndex.splice(u.$activeIndex.indexOf(e),1):u.$activeIndex.push(e),s.sort&&u.$activeIndex.sort(function(e,t){return e-t})):u.$activeIndex=e,u.$activeIndex},r.select=function(e){var t=u.$matches[e].value;u.$apply(function(){r.activate(e),s.multiple?n.$setViewValue(u.$activeIndex.map(function(e){return u.$matches[e].value})):(n.$setViewValue(t),r.hide())}),u.$emit(s.prefixEvent+'.select',t,e,r)},r.$updateActiveIndex=function(){n.$modelValue&&u.$matches.length?u.$activeIndex=s.multiple&&angular.isArray(n.$modelValue)?n.$modelValue.map(function(e){return r.$getIndex(e)}):r.$getIndex(n.$modelValue):u.$activeIndex>=u.$matches.length&&(u.$activeIndex=s.multiple?[]:0)},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&n.$viewValue.length>=s.minLength:u.$matches.length},r.$isActive=function(e){return s.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},r.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),s.multiple&&9===e.keyCode?r.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex<u.$matches.length-1?u.$activeIndex++:angular.isUndefined(u.$activeIndex)&&(u.$activeIndex=0),u.$digest())):r.select(u.$activeIndex)):void 0};var c=r.show;r.show=function(){c(),s.multiple&&r.$element.addClass('select-multiple'),i(function(){r.$element.on(l?'touchstart':'mousedown',r.$onMouseDown),s.keyboard&&t.on('keydown',r.$onKeyDown)},0,!1)};var d=r.hide;return r.hide=function(){s.multiple||n.$modelValue||(u.$activeIndex=-1),r.$element.off(l?'touchstart':'mousedown',r.$onMouseDown),s.keyboard&&t.off('keydown',r.$onKeyDown),d(!0)},r}var s=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(s.multiple=l.test(u)?!1:u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element('<button type="button" class="btn btn-default"></button>'),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s),p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,o,i,r,s){function l(t,n,a){function o(e){var t=6e4*g.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function l(e,n){var a=e+n;if(t[0].createTextRange){var o=t[0].createTextRange();o.collapse(!0),o.moveStart('character',e),o.moveEnd('character',a),o.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function d(){t[0].focus()}var f=r(t,angular.extend({},e,a)),p=a.scope,g=f.$options,m=f.$scope,$=g.lang,h=function(e,t,n){return i.formatDate(e,t,$,n)},v=0,w=g.roundDisplay?o(new Date):new Date,y=n.$dateValue||w,b={hour:y.getHours(),meridian:y.getHours()<12,minute:y.getMinutes(),second:y.getSeconds(),millisecond:y.getMilliseconds()},D=i.getDatetimeFormat(g.timeFormat,$),k=i.hoursFormat(D),S=i.timeSeparator(D),x=i.minutesFormat(D),T=i.secondsFormat(D),C=i.showSeconds(D),M=i.showAM(D);m.$iconUp=g.iconUp,m.$iconDown=g.iconDown,m.$select=function(e,t){f.select(e,t)},m.$moveIndex=function(e,t){f.$moveIndex(e,t)},m.$switchMeridian=function(e){f.switchMeridian(e)},f.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(f.$date=e,angular.extend(b,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),f.$build()):f.$isBuilt||f.$build()},f.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),g.autoclose&&!a&&s(function(){f.hide(!0)})},f.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e<g.length;e++)t=new Date(1970,0,1,b.hour-(n-e)*g.hourStep),a.push({date:t,label:h(t,k),selected:f.$date&&f.$isSelected(t,0),disabled:f.$isDisabled(t,0)});var o,i=[];for(e=0;e<g.length;e++)o=new Date(1970,0,1,0,b.minute-(n-e)*g.minuteStep),i.push({date:o,label:h(o,x),selected:f.$date&&f.$isSelected(o,1),disabled:f.$isDisabled(o,1)});var r,s=[];for(e=0;e<g.length;e++)r=new Date(1970,0,1,0,0,b.second-(n-e)*g.secondStep),s.push({date:r,label:h(r,T),selected:f.$date&&f.$isSelected(r,2),disabled:f.$isDisabled(r,2)});var l=[];for(e=0;e<g.length;e++)l.push(C?[a[e],i[e],s[e]]:[a[e],i[e]]);m.rows=l,m.showSeconds=C,m.showAM=M,m.isAM=(f.$date||a[n].date).getHours()<12,m.timeSeparator=S,f.$isBuilt=!0},f.$isSelected=function(e,t){return f.$date?0===t?e.getHours()===f.$date.getHours():1===t?e.getMinutes()===f.$date.getMinutes():2===t?e.getSeconds()===f.$date.getSeconds():void 0:!1},f.$isDisabled=function(e,t){var n;return 0===t?n=e.getTime()+6e4*b.minute+1e3*b.second:1===t?n=e.getTime()+36e5*b.hour+1e3*b.second:2===t&&(n=e.getTime()+36e5*b.hour+6e4*b.minute),n<1*g.minTime||n>1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*M;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var E=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void E())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):new Date('unix'===f.timeType?1e3*e:e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t<o.$panes.length?o.$setActive(o.$panes[t].name||t):o.$setActive()},o.$setActive=t.$setActive=function(e){o.$panes.$active=e,o.$activePaneChangeListeners.forEach(function(e){e()})},o.$isActive=t.$isActive=function(e,t){return o.$panes.$active===e.name||o.$panes.$active===t}};this.$get=function(){var n={};return n.defaults=e,n.controller=t,n}}).directive('bsTabs',['$window','$animate','$tab','$parse',function(e,t,n,a){var o=n.defaults;return{require:['?ngModel','bsTabs'],transclude:!0,scope:!0,controller:['$scope','$element','$attrs',n.controller],templateUrl:function(e,t){return t.template||o.template},link:function(e,t,n,o){var i=o[0],r=o[1];if(i&&(r.$activePaneChangeListeners.push(function(){i.$setViewValue(r.$panes.$active)}),i.$formatters.push(function(e){return r.$setActive(e),e})),n.bsActivePane){var s=a(n.bsActivePane);r.$activePaneChangeListeners.push(function(){s.assign(e,r.$panes.$active)}),e.$watch(n.bsActivePane,function(e,t){r.$setActive(e)},!0)}}}}]).directive('bsPane',['$window','$animate','$sce',function(e,t,n){return{require:['^?ngModel','^bsTabs'],scope:!0,link:function(e,a,o,i){function r(){var n=s.$panes.indexOf(e);t[s.$isActive(e,n)?'addClass':'removeClass'](a,s.$options.activeClass)}var s=(i[0],i[1]);a.addClass('tab-pane'),o.$observe('title',function(t,a){e.title=n.trustAsHtml(t)}),e.name=o.name,s.$options.animation&&a.addClass(s.$options.animation),o.$observe('disabled',function(t,n){e.disabled=e.$eval(t)}),s.$push(e),e.$on('$destroy',function(){s.$remove(e)}),s.$activePaneChangeListeners.push(function(){r()}),r()}}}]),angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){
11
- function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex<d.$matches.length-1?d.$activeIndex++:angular.isUndefined(d.$activeIndex)&&(d.$activeIndex=0),d.$digest())};var f=l.show;l.show=function(){f(),i(function(){l.$element&&l.$element.on('mousedown',l.$onMouseDown),u.keyboard&&t&&t.on('keydown',l.$onKeyDown)},0,!1)};var p=l.hide;return l.hide=function(){l.$element&&l.$element.off('mousedown',l.$onMouseDown),u.keyboard&&t&&t.off('keydown',l.$onKeyDown),u.autoSelect||l.activate(-1),p()},l}function s(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}angular.element(t.document.body);return r.defaults=e,r}]}).filter('bsAsyncFilter',['$filter',function(e){return function(t,n,a){return t&&angular.isFunction(t.then)?t.then(function(t){return e('filter')(t,n,a)}):e('filter')(t,n,a)}}]).directive('bsTypeahead',['$window','$parse','$q','$typeahead','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','filter','limit','minLength','watchOptions','selectMode','autoSelect','comparator','id','prefixEvent','prefixClass'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','trimValue'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)}),t.attr('autocomplete','false');var u=s.filter||i.filter,c=s.limit||i.limit,d=s.comparator||i.comparator,f=n.bsOptions;u&&(f+=' | '+u+':$viewValue'),d&&(f+=':'+d),c&&(f+=' | limitTo:'+c);var p=o(f),g=a(t,r,s);if(s.watchOptions){var m=p.$match[7].replace(/\|.+/,'').replace(/\(.*\)/g,'').trim();e.$watchCollection(m,function(t,n){p.valuesFn(e,r).then(function(e){g.update(e),r.$render()})})}e.$watch(n.ngModel,function(t,n){e.$modelValue=t,p.valuesFn(e,r).then(function(e){if(s.selectMode&&!e.length&&t.length>0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){P.$emit(V.prefixEvent+'.show',F)}function p(){if(P.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function T(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function C(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=M(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';E(f,n[p],d)}}}function M(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;s<r.top?o.top=r.top-s:l>r.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;u<r.left?o.left=r.left-u:c>r.right&&(o.left=r.left+r.width-c)}return o}function E(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),Y&&(Y.$destroy(),Y=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),P=F.$scope=V.scope&&V.scope.$new()||a.$new(),I=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(P.title=u.trustAsHtml(V.title)),P.$setEnabled=function(e){P.$$postDigest(function(){F.setEnabled(e)})},P.$hide=function(){P.$$postDigest(function(){F.hide()})},P.$show=function(){P.$$postDigest(function(){F.show()})},P.$toggle=function(){P.$$postDigest(function(){F.toggle()})},F.$isShown=P.$isShown=!1;var H,L,U,R,q,Y;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?q=i:angular.isElement(V.container)?q=V.container:V.container&&(q=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&P.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),P.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){P.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=q,t=q[0].lastChild?angular.element(q[0].lastChild):null):(e=null,t=i),R&&A(),Y=F.$scope.$new(),R=F.$element=U.link(Y,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=P.$isShown=!0,g(P),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(P),d(function(){R&&R.css({visibility:'visible'})}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y()),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(P.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=P.$isShown=!1,g(P),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-r<l.top&&(t=s.replace('top','bottom')),('right'===s||'bottom-left'===s||'top-left'===s)&&o.right+i>l.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-i<l.left&&(t='left'===s?'right':t.replace('right','left')),R.removeClass(s).addClass(t)}var u=T(t,o,i,r);C(u,t)}},F.$onKeyUp=function(e){27===e.which&&F.$isShown&&(F.hide(),e.stopPropagation())},F.$onFocusKeyUp=function(e){27===e.which&&(i[0].blur(),e.stopPropagation())},F.$onFocusElementMouseDown=function(e){e.preventDefault(),e.stopPropagation(),F.$isShown?i[0].blur():i[0].focus()};var K=!1;return F}function g(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function m(e,n){return angular.element((n||t).querySelectorAll(e))}var $=(String.prototype.trim,'createTouch'in n.document),h=angular.element(n.document);return p}]}).directive('bsTooltip',['$window','$location','$sce','$tooltip','$$rAF',function(e,t,n,a,o){return{restrict:'EAC',scope:!0,link:function(e,t,i,r){var s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','backdropAnimation','type','customClass','id'],function(e){angular.isDefined(i[e])&&(s[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(s[e]=!1)});var u=t.attr('data-target');angular.isDefined(u)&&(s.target=l.test(u)?!1:u),e.hasOwnProperty('title')||(e.title=''),i.$observe('title',function(t){if(angular.isDefined(t)||!e.hasOwnProperty('title')){var a=e.title;e.title=n.trustAsHtml(t),angular.isDefined(a)&&o(function(){c&&c.$applyPlacement()})}}),i.bsTooltip&&e.$watch(i.bsTooltip,function(t,n){angular.isObject(t)?angular.extend(e,t):e.title=t,angular.isDefined(n)&&o(function(){c&&c.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){c&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(tooltip),?/i)),e===!0?c.show():c.hide())}),i.bsEnabled&&e.$watch(i.bsEnabled,function(e,t){c&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|1|,?(tooltip),?/i)),c.setEnabled(e===!1?!1:!0))}),i.viewport&&e.$watch(i.viewport,function(e){c&&angular.isDefined(e)&&c.setViewport(e)});var c=a(t,s);e.$on('$destroy',function(){c&&c.destroy(),s=null,c=null})}}}])}(window,document);
12
- //# sourceMappingURL=angular-strap.min.js.map
8
+ !function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;if(angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),r)d.$template=e.when(r);else{if(!n)throw new Error('Missing `template` / `templateUrl` option.');d.$template=l(n)}return t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"], [ng-bind="title"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('<div>').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t;for(t=d.$matches.length;t--&&!angular.equals(d.$matches[t].value,e););return t},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex<d.$matches.length-1?d.$activeIndex++:angular.isUndefined(d.$activeIndex)&&(d.$activeIndex=0),d.$digest())};var f=l.show;l.show=function(){f(),i(function(){l.$element&&(l.$element.on('mousedown',l.$onMouseDown),u.keyboard&&t&&t.on('keydown',l.$onKeyDown))},0,!1)};var p=l.hide;return l.hide=function(){l.$element&&l.$element.off('mousedown',l.$onMouseDown),u.keyboard&&t&&t.off('keydown',l.$onKeyDown),u.autoSelect||l.activate(-1),p()},l}function s(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}return r.defaults=e,r}]}).filter('bsAsyncFilter',['$filter',function(e){return function(t,n,a){return t&&angular.isFunction(t.then)?t.then(function(t){return e('filter')(t,n,a)}):e('filter')(t,n,a)}}]).directive('bsTypeahead',['$window','$parse','$q','$typeahead','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','filter','limit','minLength','watchOptions','selectMode','autoSelect','comparator','id','prefixEvent','prefixClass'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','trimValue'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)}),t.attr('autocomplete')||t.attr('autocomplete','off');var u=s.filter||i.filter,c=s.limit||i.limit,d=s.comparator||i.comparator,f=n.bsOptions;u&&(f+=' | '+u+':$viewValue'),d&&(f+=':'+d),c&&(f+=' | limitTo:'+c);var p=o(f),g=a(t,r,s);if(s.watchOptions){var m=p.$match[7].replace(/\|.+/,'').replace(/\(.*\)/g,'').trim();e.$watchCollection(m,function(t,n){p.valuesFn(e,r).then(function(e){g.update(e),r.$render()})})}e.$watch(n.ngModel,function(t,n){e.$modelValue=t,p.valuesFn(e,r).then(function(e){return s.selectMode&&!e.length&&t.length>0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=-1!==e?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){I.$emit(V.prefixEvent+'.show',F)}function p(){if(I.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===N&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function C(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a+t.height;break;case'bottom':o.top=t.top}return o}function T(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=E(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';M(f,n[p],d)}}}function E(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;s<r.top?o.top=r.top-s:l>r.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;u<r.left?o.left=r.left-u:c>r.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),q&&(q.$destroy(),q=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),I=F.$scope=V.scope&&V.scope.$new()||a.$new(),N=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var P=V.delay.split(',').map(parseFloat);V.delay=P.length>1?{show:P[0],hide:P[1]}:P[0]}F.$id=V.id||i.attr('id')||'',V.title&&(I.title=u.trustAsHtml(V.title)),I.$setEnabled=function(e){I.$$postDigest(function(){F.setEnabled(e)})},I.$hide=function(){I.$$postDigest(function(){F.hide()})},I.$show=function(){I.$$postDigest(function(){F.show()})},I.$toggle=function(){I.$$postDigest(function(){F.toggle()})},F.$isShown=I.$isShown=!1;var H,L,U,R,Y,q;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?Y=i:angular.isElement(V.container)?Y=V.container:V.container&&(Y=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&I.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),I.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){I.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=Y,t=Y[0].lastChild?angular.element(Y[0].lastChild):null):(e=null,t=i),R&&A(),q=F.$scope.$new(),R=F.$element=U.link(q,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=I.$isShown=!0,g(I),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(I),d(function(){R&&R.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(I.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=I.$isShown=!1,g(I),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);/bottom/.test(s)&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):/top/.test(s)&&o.top-r<l.top&&(t=s.replace('top','bottom')),/left/.test(s)&&o.left-i<l.left?t=t.replace('left','right'):/right/.test(s)&&o.right+i>l.width&&(t=t.replace('right','left')),R.removeClass(s).addClass(t)}var u=C(t,o,i,r);T(u,t)}},F.$onKeyUp=function(e){27===e.which&&F.$isShown&&(F.hide(),e.stopPropagation())},F.$onFocusKeyUp=function(e){27===e.which&&(i[0].blur(),e.stopPropagation())},F.$onFocusElementMouseDown=function(e){e.preventDefault(),e.stopPropagation(),F.$isShown?i[0].blur():i[0].focus()};var K=!1;return F}function g(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function m(e,n){return angular.element((n||t).querySelectorAll(e))}var $='createTouch'in n.document,h=angular.element(n.document);return p}]}).directive('bsTooltip',['$window','$location','$sce','$tooltip','$$rAF',function(e,t,n,a,o){return{restrict:'EAC',scope:!0,link:function(e,t,i,r){var s,l={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','backdropAnimation','type','customClass','id'],function(e){angular.isDefined(i[e])&&(l[e]=i[e])});var u=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(i[e])&&u.test(i[e])&&(l[e]=!1)});var c=t.attr('data-target');angular.isDefined(c)&&(u.test(c)?l.target=!1:l.target=c),e.hasOwnProperty('title')||(e.title=''),i.$observe('title',function(t){if(angular.isDefined(t)||!e.hasOwnProperty('title')){var a=e.title;e.title=n.trustAsHtml(t),angular.isDefined(a)&&o(function(){s&&s.$applyPlacement()})}}),i.bsTooltip&&e.$watch(i.bsTooltip,function(t,n){angular.isObject(t)?angular.extend(e,t):e.title=t,angular.isDefined(n)&&o(function(){s&&s.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(tooltip),?/i)),e===!0?s.show():s.hide())}),i.bsEnabled&&e.$watch(i.bsEnabled,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|1|,?(tooltip),?/i)),e===!1?s.setEnabled(!1):s.setEnabled(!0))}),i.viewport&&e.$watch(i.viewport,function(e){s&&angular.isDefined(e)&&s.setViewport(e)}),s=a(t,l),e.$on('$destroy',function(){s&&s.destroy(),l=null,s=null})}}}]),angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,o,i,r,s){function l(t,n,a){function o(e){var t=6e4*g.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function l(e,n){var a=e+n;if(t[0].createTextRange){var o=t[0].createTextRange();o.collapse(!0),o.moveStart('character',e),o.moveEnd('character',a),o.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function d(){t[0].focus()}var f=r(t,angular.extend({},e,a)),p=a.scope,g=f.$options,m=f.$scope,$=g.lang,h=function(e,t,n){return i.formatDate(e,t,$,n)},v=0,w=g.roundDisplay?o(new Date):new Date,y=n.$dateValue||w,b={hour:y.getHours(),meridian:y.getHours()<12,minute:y.getMinutes(),second:y.getSeconds(),millisecond:y.getMilliseconds()},D=i.getDatetimeFormat(g.timeFormat,$),k=i.hoursFormat(D),S=i.timeSeparator(D),x=i.minutesFormat(D),C=i.secondsFormat(D),T=i.showSeconds(D),E=i.showAM(D);m.$iconUp=g.iconUp,m.$iconDown=g.iconDown,m.$select=function(e,t){f.select(e,t)},m.$moveIndex=function(e,t){f.$moveIndex(e,t)},m.$switchMeridian=function(e){f.switchMeridian(e)},f.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(f.$date=e,angular.extend(b,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),f.$build()):f.$isBuilt||f.$build()},f.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),g.autoclose&&!a&&s(function(){f.hide(!0)})},f.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e<g.length;e++)t=new Date(1970,0,1,b.hour-(n-e)*g.hourStep),a.push({date:t,label:h(t,k),selected:f.$date&&f.$isSelected(t,0),disabled:f.$isDisabled(t,0)});var o,i=[];for(e=0;e<g.length;e++)o=new Date(1970,0,1,0,b.minute-(n-e)*g.minuteStep),i.push({date:o,label:h(o,x),selected:f.$date&&f.$isSelected(o,1),disabled:f.$isDisabled(o,1)});var r,s=[];for(e=0;e<g.length;e++)r=new Date(1970,0,1,0,0,b.second-(n-e)*g.secondStep),s.push({date:r,label:h(r,C),selected:f.$date&&f.$isSelected(r,2),disabled:f.$isDisabled(r,2)});var l=[];for(e=0;e<g.length;e++)T?l.push([a[e],i[e],s[e]]):l.push([a[e],i[e]]);m.rows=l,m.showSeconds=T,m.showAM=E,m.isAM=(f.$date||a[n].date).getHours()<12,m.timeSeparator=S,f.$isBuilt=!0},f.$isSelected=function(e,t){return f.$date?0===t?e.getHours()===f.$date.getHours():1===t?e.getMinutes()===f.$date.getMinutes():2===t?e.getSeconds()===f.$date.getSeconds():void 0:!1},f.$isDisabled=function(e,t){var n;return 0===t?n=e.getTime()+6e4*b.minute+1e3*b.second:1===t?n=e.getTime()+36e5*b.hour+1e3*b.second:2===t&&(n=e.getTime()+36e5*b.hour+6e4*b.minute),n<1*g.minTime||n>1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,C).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*T+1*E;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&T,y=2===v&&!T||3===v&&T;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,C).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*T,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var M=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)};a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())});var h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),isNaN(g.$options[e])||g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t<o.$panes.length?o.$setActive(o.$panes[t].name||t):o.$setActive()},o.$setActive=t.$setActive=function(e){o.$panes.$active=e,o.$activePaneChangeListeners.forEach(function(e){e()})},o.$isActive=t.$isActive=function(e,t){return o.$panes.$active===e.name||o.$panes.$active===t}};this.$get=function(){var n={};return n.defaults=e,n.controller=t,n}}).directive('bsTabs',['$window','$animate','$tab','$parse',function(e,t,n,a){var o=n.defaults;return{require:['?ngModel','bsTabs'],transclude:!0,scope:!0,controller:['$scope','$element','$attrs',n.controller],templateUrl:function(e,t){return t.template||o.template},link:function(e,t,n,o){var i=o[0],r=o[1];if(i&&(r.$activePaneChangeListeners.push(function(){i.$setViewValue(r.$panes.$active)}),i.$formatters.push(function(e){return r.$setActive(e),e})),n.bsActivePane){var s=a(n.bsActivePane);r.$activePaneChangeListeners.push(function(){s.assign(e,r.$panes.$active)}),e.$watch(n.bsActivePane,function(e,t){r.$setActive(e)},!0)}}}}]).directive('bsPane',['$window','$animate','$sce',function(e,t,n){return{require:['^?ngModel','^bsTabs'],scope:!0,link:function(e,a,o,i){function r(){var n=s.$panes.indexOf(e);t[s.$isActive(e,n)?'addClass':'removeClass'](a,s.$options.activeClass)}var s=i[1];a.addClass('tab-pane'),o.$observe('title',function(t,a){e.title=n.trustAsHtml(t)}),e.name=o.name,s.$options.animation&&a.addClass(s.$options.animation),o.$observe('disabled',function(t,n){e.disabled=e.$eval(t)}),s.$push(e),e.$on('$destroy',function(){s.$remove(e)}),s.$activePaneChangeListeners.push(function(){r()}),r()}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:'&nbsp;<span class="caret"></span>',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(a,r,s){var u={},c=angular.extend({},e,s);u=o(a,c);var d=u.$scope;d.$matches=[],c.multiple?d.$activeIndex=[]:d.$activeIndex=-1,d.$isMultiple=c.multiple,d.$showAllNoneButtons=c.allNoneButtons&&c.multiple,d.$iconCheckmark=c.iconCheckmark,d.$allText=c.allText,d.$noneText=c.noneText,d.$activate=function(e){d.$$postDigest(function(){u.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){u.select(e)})},d.$isVisible=function(){return u.$isVisible()},d.$isActive=function(e){return u.$isActive(e)},d.$selectAll=function(){for(var e=0;e<d.$matches.length;e++)d.$isActive(e)||d.$select(e)},d.$selectNone=function(){for(var e=0;e<d.$matches.length;e++)d.$isActive(e)&&d.$select(e)},u.update=function(e){d.$matches=e,u.$updateActiveIndex()},u.activate=function(e){return c.multiple?(u.$isActive(e)?d.$activeIndex.splice(d.$activeIndex.indexOf(e),1):d.$activeIndex.push(e),c.sort&&d.$activeIndex.sort(function(e,t){return e-t})):d.$activeIndex=e,d.$activeIndex},u.select=function(e){var t=d.$matches[e].value;d.$apply(function(){u.activate(e),c.multiple?r.$setViewValue(d.$activeIndex.map(function(e){return angular.isUndefined(d.$matches[e])?null:d.$matches[e].value})):(r.$setViewValue(t),u.hide())}),d.$emit(c.prefixEvent+'.select',t,e,u)},u.$updateActiveIndex=function(){c.multiple?angular.isArray(r.$modelValue)?d.$activeIndex=r.$modelValue.map(function(e){return u.$getIndex(e)}):d.$activeIndex=[]:angular.isDefined(r.$modelValue)&&d.$matches.length?d.$activeIndex=u.$getIndex(r.$modelValue):d.$activeIndex=-1},u.$isVisible=function(){return c.minLength&&r?d.$matches.length&&r.$viewValue.length>=c.minLength:d.$matches.length},u.$isActive=function(e){return c.multiple?-1!==d.$activeIndex.indexOf(e):d.$activeIndex===e},u.$getIndex=function(e){var t;for(t=d.$matches.length;t--&&!angular.equals(d.$matches[t].value,e););return t},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},u.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),c.multiple&&9===e.keyCode?u.hide():c.multiple||13!==e.keyCode&&9!==e.keyCode?void(c.multiple||(38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:38===e.keyCode&&d.$activeIndex<0?d.$activeIndex=d.$matches.length-1:40===e.keyCode&&d.$activeIndex<d.$matches.length-1?d.$activeIndex++:angular.isUndefined(d.$activeIndex)&&(d.$activeIndex=0),d.$digest())):u.select(d.$activeIndex)):void 0},u.$isIE=function(){var e=t.navigator.userAgent;return e.indexOf('MSIE ')>0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},u.$selectScrollFix=function(e){'UL'===n[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var f=u.show;u.show=function(){f(),c.multiple&&u.$element.addClass('select-multiple'),i(function(){u.$element.on(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.on('keydown',u.$onKeyDown)},0,!1)};var p=u.hide;return u.hide=function(){!c.multiple&&angular.isUndefined(r.$modelValue)&&(d.$activeIndex=-1),u.$element.off(l?'touchstart':'mousedown',u.$onMouseDown),c.keyboard&&a.off('keydown',u.$onKeyDown),p(!0)},u}var s=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),l='createTouch'in t.document&&s;return r.defaults=e,r}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element('<button type="button" class="btn btn-default"></button>'),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watch(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})},!0),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),-1!==n?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),
9
+ e=-1!==n?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r,s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(s[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(s[e]=!1)});var u=o.attr('data-target');angular.isDefined(u)&&(l.test(u)?s.target=!1:s.target=u),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){r&&r.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){r&&r.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){r&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?r.show():r.hide())}),i.viewport&&e.$watch(i.viewport,function(e){r&&angular.isDefined(e)&&r.setViewport(e)}),r=n(o,s),e.$on('$destroy',function(){r&&r.destroy(),s=null,r=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},C=x.$trackedElements=[],T=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(T.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),S<T[0].offsetTop&&w!==T[0].target)return x.$activateElement(T[0]);for(var e=T.length;e--;)if(!angular.isUndefined(T[e].offsetTop)&&null!==T[e].offsetTop&&w!==T[e].target&&!(S<T[e].offsetTop||T[e+1]&&S>T[e+1].offsetTop))return x.$activateElement(T[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return C.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(C,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),T=C.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){C.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=C.length;a--;)if(C[a].target===e&&C[a].source===t){n=a;break}C=C.splice(n,1)},x.activate=function(e){C[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',customClass:'',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){C.$emit(S.prefixEvent+'.show',k)}function r(){C.$emit(S.prefixEvent+'.hide',k),g.removeClass(S.prefixClass+'-open'),S.animation&&g.removeClass(S.prefixClass+'-with-'+S.animation)}function l(){S.backdrop&&(E.on('click',y),A.on('click',y),A.on('wheel',b))}function u(){S.backdrop&&(E.off('click',y),A.off('click',y),A.off('wheel',b))}function v(){S.keyboard&&E.on('keyup',k.$onKeyUp)}function w(){S.keyboard&&E.off('keyup',k.$onKeyUp)}function y(e){e.target===e.currentTarget&&('static'===S.backdrop?k.focus():k.hide())}function b(e){e.preventDefault()}function D(){k.$isShown&&null!==E&&(u(),w()),M&&(M.$destroy(),M=null),E&&(E.remove(),E=k.$element=null)}var k={},S=k.$options=angular.extend({},e,t),x=k.$promise=o.compile(S),C=k.$scope=S.scope&&S.scope.$new()||a.$new();S.element||S.container||(S.container='body'),k.$id=S.id||S.element&&S.element.attr('id')||'',f(['title','content'],function(e){S[e]&&(C[e]=s.trustAsHtml(S[e]))}),C.$hide=function(){C.$$postDigest(function(){k.hide()})},C.$show=function(){C.$$postDigest(function(){k.show()})},C.$toggle=function(){C.$$postDigest(function(){k.toggle()})},k.$isShown=C.$isShown=!1;var T,E,M,A=angular.element('<div class="'+S.prefixClass+'-backdrop"/>');return A.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px'}),x.then(function(e){T=e,k.init()}),k.init=function(){S.show&&C.$$postDigest(function(){k.show()})},k.destroy=function(){D(),A&&(A.remove(),A=null),C.$destroy()},k.show=function(){if(!k.$isShown){var e,t;if(angular.isElement(S.container)?(e=S.container,t=S.container[0].lastChild?angular.element(S.container[0].lastChild):null):S.container?(e=d(S.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=S.element),E&&D(),M=k.$scope.$new(),E=k.$element=T.link(M,function(e,t){}),S.backdrop&&(E.css({'z-index':$+20*m}),A.css({'z-index':h+20*m}),m++),!C.$emit(S.prefixEvent+'.show.before',k).defaultPrevented){E.css({display:'block'}).addClass(S.placement),S.customClass&&E.addClass(S.customClass),S.animation&&(S.backdrop&&A.addClass(S.backdropAnimation),E.addClass(S.animation)),S.backdrop&&i.enter(A,g,null),angular.version.minor<=2?i.enter(E,e,t,n):i.enter(E,e,t).then(n),k.$isShown=C.$isShown=!0,c(C);var a=E[0];p(function(){a.focus()}),g.addClass(S.prefixClass+'-open'),S.animation&&g.addClass(S.prefixClass+'-with-'+S.animation),l(),v()}}},k.hide=function(){k.$isShown&&(S.backdrop&&m--,C.$emit(S.prefixEvent+'.hide.before',k).defaultPrevented||(angular.version.minor<=2?i.leave(E,r):i.leave(E).then(r),S.backdrop&&i.leave(A),k.$isShown=C.$isShown=!1,c(C),u(),w()))},k.toggle=function(){k.$isShown?k.hide():k.show()},k.focus=function(){E[0].focus()},k.$onKeyUp=function(e){27===e.which&&k.$isShown&&(k.hide(),e.stopPropagation())},k}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=n.requestAnimationFrame||n.setTimeout,g=angular.element(n.document.body),m=0,$=1050,h=1040;return u}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass','customClass','modalClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),r.modalClass&&(r.customClass=r.modalClass);var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',function(){function t(e){var t=e.ownerDocument,o=e.offsetParent||t;if(a(o,'#document'))return t.documentElement;for(;o&&!a(o,'html')&&'static'===n.css(o,'position');)o=o.offsetParent;return o||t.documentElement}var n={},a=n.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};return n.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},n.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},n.setOffset=function(e,t,a){var o,i,r,s,l,u,c,d=n.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=n.offset(e),r=n.css(e,'top'),u=n.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=n.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,a,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},n.position=function(e){var o,i,r={top:0,left:0};return'fixed'===n.css(e,'position')?i=e.getBoundingClientRect():(o=t(e),i=n.offset(e),a(o,'html')||(r=n.offset(o)),r.top+=n.css(o,'borderTopWidth',!0),r.left+=n.css(o,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:i.top-r.top-n.css(e,'marginTop',!0),left:i.left-r.left-n.css(e,'marginLeft',!0)}},n.height=function(e,t){var a=e.offsetHeight;return t?a+=n.css(e,'marginTop',!0)+n.css(e,'marginBottom',!0):a-=n.css(e,'paddingTop',!0)+n.css(e,'paddingBottom',!0)+n.css(e,'borderTopWidth',!0)+n.css(e,'borderBottomWidth',!0),a},n.width=function(e,t){var a=e.offsetWidth;return t?a+=n.css(e,'marginLeft',!0)+n.css(e,'marginRight',!0):a-=n.css(e,'paddingLeft',!0)+n.css(e,'paddingRight',!0)+n.css(e,'borderLeftWidth',!0)+n.css(e,'borderRightWidth',!0),a},n}),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t=c(e);return g(t)}function c(e){var t=d(e),n=t.replace(/''/g,'\\\''),a=/('(?:\\'|.)*?')/,o=n.split(a),i=Object.keys(b),r=[];return angular.forEach(o,function(e){if(f(e))e=p(e);else for(var t=0;t<i.length;t++)e=e.split(i[t]).join('${'+t+'}');r.push(e)}),r.join('')}function d(e){return e.replace(/\\/g,'[\\\\]').replace(/-/g,'[-]').replace(/\./g,'[.]').replace(/\*/g,'[*]').replace(/\+/g,'[+]').replace(/\?/g,'[?]').replace(/\$/g,'[$]').replace(/\^/g,'[^]').replace(/\//g,'[/]').replace(/\\s/g,'[\\s]')}function f(e){return/^'.*'$/.test(e)}function p(e){return e.replace(/^'(.*)'$/,'$1')}function g(e){for(var t=Object.keys(b),n=e,a=0;a<t.length;a++)n=n.split('${'+a+'}').join('('+b[t[a]]+')');return new RegExp('^'+n+'$',['i'])}function m(e){var t=c(e);return $(t)}function $(e){for(var t,n,a,o,i=Object.keys(b),r=new RegExp('\\${(\\d+)}','g'),s=[];null!==(t=r.exec(e));)n=t[1],a=i[n],o=D[a],s.push(o);return s}var h,v,w=angular.extend({},r,l),y={},b={sss:'[0-9]{3}',ss:'[0-5][0-9]',s:w.strict?'[1-5]?[0-9]':'[0-9]|[0-5][0-9]',mm:'[0-5][0-9]',m:w.strict?'[1-5]?[0-9]':'[0-9]|[0-5][0-9]',HH:'[01][0-9]|2[0-3]',H:w.strict?'1?[0-9]|2[0-3]':'[01]?[0-9]|2[0-3]',hh:'[0][1-9]|[1][012]',h:w.strict?'[1-9]|1[012]':'0?[1-9]|1[012]',a:'AM|PM',EEEE:e.DATETIME_FORMATS.DAY.join('|'),EEE:e.DATETIME_FORMATS.SHORTDAY.join('|'),dd:'0[1-9]|[12][0-9]|3[01]',d:w.strict?'[1-9]|[1-2][0-9]|3[01]':'0?[1-9]|[1-2][0-9]|3[01]',MMMM:e.DATETIME_FORMATS.MONTH.join('|'),MMM:e.DATETIME_FORMATS.SHORTMONTH.join('|'),MM:'0[1-9]|1[012]',M:w.strict?'[1-9]|1[012]':'0?[1-9]|1[012]',yyyy:'[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',yy:'[0-9]{2}',y:w.strict?'-?(0|[1-9][0-9]{0,3})':'-?0*[0-9]{1,4}'},D={sss:i.setMilliseconds,ss:i.setSeconds,s:i.setSeconds,mm:i.setMinutes,m:i.setMinutes,HH:i.setHours,H:i.setHours,hh:i.setHours,h:i.setHours,EEEE:n,EEE:n,dd:i.setDate,d:i.setDate,a:function(e){var t=this.getHours()%12;return this.setHours(e.match(/pm/i)?t+12:t)},MMMM:function(t){return this.setMonth(o(e.DATETIME_FORMATS.MONTH,t))},MMM:function(t){return this.setMonth(o(e.DATETIME_FORMATS.SHORTMONTH,t))},MM:function(e){return this.setMonth(1*e-1)},M:function(e){return this.setMonth(1*e-1)},yyyy:i.setFullYear,yy:function(e){return this.setFullYear(2e3+1*e)},y:function(e){return 50>=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return y.init=function(){y.$format=e.DATETIME_FORMATS[w.format]||w.format,h=u(y.$format),v=m(y.$format)},y.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):h.test(e)},y.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||y.$format,i));var r=o?u(o):h,l=o?m(o):v,c=r.exec(n);if(!c)return!1;for(var d=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),f=0;f<c.length-1;f++)l[f]&&l[f].call(d,c[f+1]);var p=d.toDate();return parseInt(d.day,10)!==p.getDate()?!1:p},y.getDateForAttribute=function(e,t){var n;if('today'===t){var o=new Date;n=new Date(o.getFullYear(),o.getMonth(),o.getDate()+('maxDate'===e?1:0),0,0,0,'minDate'===e?0:-1)}else n=angular.isString(t)&&t.match(/^".+"$/)?new Date(t.substr(1,t.length-2)):a(t)?new Date(parseInt(t,10)):angular.isString(t)&&0===t.length?'minDate'===e?-(1/0):+(1/0):new Date(t);return n},y.getTimeForAttribute=function(e,t){var n;return n='now'===t?(new Date).setFullYear(1970,0,1):angular.isString(t)&&t.match(/^".+"$/)?new Date(t.substr(1,t.length-2)).setFullYear(1970,0,1):a(t)?new Date(parseInt(t,10)).setFullYear(1970,0,1):angular.isString(t)&&0===t.length?'minTime'===e?-(1/0):+(1/0):y.parse(t,new Date(1970,0,1,0))},y.daylightSavingAdjust=function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},y.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},y.init(),y};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new(),u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n<t.length-1?n++:angular.isUndefined(n)&&(n=0),t.eq(n)[0].focus()}}};var f=u.show;u.show=function(){f(),o(function(){c.keyboard&&u.$element&&u.$element.on('keydown',u.$onKeyDown),r.on('click',l)},0,!1),d.hasClass('dropdown')&&d.addClass('open')};var p=u.hide;u.hide=function(){u.$isShown&&(c.keyboard&&u.$element&&u.$element.off('keydown',u.$onKeyDown),r.off('click',l),d.hasClass('dropdown')&&d.removeClass('open'),p())};var g=u.destroy;return u.destroy=function(){r.off('click',l),g()},u}var r=angular.element(t.document.body),s=Element.prototype.matchesSelector||Element.prototype.webkitMatchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector;return i}]}).directive('bsDropdown',['$window','$sce','$dropdown',function(e,t,a){return{restrict:'EAC',scope:!0,compile:function(e,t){if(!t.bsDropdown){for(var o=e[0].nextSibling;o&&1!==o.nodeType;)o=o.nextSibling;o&&o.classList.contains('dropdown-menu')&&(t.template=o.outerHTML,t.templateUrl=n,o.parentNode.removeChild(o))}return function(e,n,o){var i={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','id','autoClose'],function(e){angular.isDefined(t[e])&&(i[e]=t[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(o[e])&&r.test(o[e])&&(i[e]=!1)}),o.bsDropdown&&e.$watch(o.bsDropdown,function(t,n){e.content=t},!0);var s=a(n,i);o.bsShow&&e.$watch(o.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(dropdown),?/i)),e===!0?s.show():s.hide())}),e.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}}]),angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$datepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','datepickerViews','$tooltip','$timeout',function(t,n,a,o,i,r,s,l){function u(t,n,a){function o(e){e.selected=u.$isSelected(e.date)}function i(){t[0].focus()}var u=s(t,angular.extend({},e,a)),f=a.scope,p=u.$options,g=u.$scope;p.startView&&(p.startView-=p.minView);var m=r(u);u.$views=m.views;var $=m.viewDate;g.$mode=p.startView,g.$iconLeft=p.iconLeft,g.$iconRight=p.iconRight;var h=u.$views[g.$mode];g.$select=function(e){u.select(e)},g.$selectPane=function(e){u.$selectPane(e)},g.$toggleMode=function(){u.setMode((g.$mode+1)%u.$views.length)},u.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(u.$date=e,h.update.call(h,e)),u.$build(!0)},u.updateDisabledDates=function(e){p.disabledDateRanges=e;for(var t=0,n=g.rows.length;n>t;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void(g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0));h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())}),angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),isNaN(p.$options[e])||p.$build(!1),u(s.$dateValue)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml('<th class="dow text-center">'+f.join('</th><th class="dow text-center">')+'</th>'),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(t<s.minDate||t>s.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n<s.disabledDateRanges.length;n++)if(t>=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0);
10
+ }}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=[],a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return t<s.minDate||e.getTime()>s.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return t<s.minDate||e.getTime()>s.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n<t.length;n++)e<t[n]&&(t[n]=t[n]-1),t[n]===l.$targets.length&&(t[n]=l.$targets.length-1)}function i(e){var t=l.$targets.$active;return-1===t.indexOf(e)?!1:!0}function r(e){var t=l.$targets.$active.indexOf(e);-1!==t&&l.$targets.$active.splice(t,1)}function s(e){l.$options.allowMultiple||l.$targets.$active.splice(0,1),-1===l.$targets.$active.indexOf(e)&&l.$targets.$active.push(e)}var l=this;l.$options=angular.copy(e),angular.forEach(['animation','disallowToggle','activeClass','startCollapsed','allowMultiple'],function(e){angular.isDefined(a[e])&&(l.$options[e]=a[e])});var u=/^(false|0|)$/i;angular.forEach(['disallowToggle','startCollapsed','allowMultiple'],function(e){angular.isDefined(a[e])&&u.test(a[e])&&(l.$options[e]=!1)}),l.$toggles=[],l.$targets=[],l.$viewChangeListeners=[],l.$registerToggle=function(e){l.$toggles.push(e)},l.$registerTarget=function(e){l.$targets.push(e)},l.$unregisterToggle=function(e){var t=l.$toggles.indexOf(e);l.$toggles.splice(t,1)},l.$unregisterTarget=function(e){var t=l.$targets.indexOf(e);l.$targets.splice(t,1),l.$options.allowMultiple&&r(e),o(t),l.$viewChangeListeners.forEach(function(e){e()})},l.$targets.$active=l.$options.startCollapsed?[]:[0],l.$setActive=t.$setActive=function(e){angular.isArray(e)?l.$targets.$active=e:!l.$options.disallowToggle&&i(e)?r(e):s(e),l.$viewChangeListeners.forEach(function(e){e()})},l.$activeIndexes=function(){return l.$options.allowMultiple?l.$targets.$active:1===l.$targets.$active.length?l.$targets.$active[0]:-1}};this.$get=function(){var n={};return n.defaults=e,n.controller=t,n}}).directive('bsCollapse',['$window','$animate','$collapse',function(e,t,n){return{require:['?ngModel','bsCollapse'],controller:['$scope','$element','$attrs',n.controller],link:function(e,t,n,a){var o=a[0],i=a[1];o&&(i.$viewChangeListeners.push(function(){o.$setViewValue(i.$activeIndexes())}),o.$formatters.push(function(e){if(angular.isArray(e))i.$setActive(e);else{var t=i.$activeIndexes();angular.isArray(t)?-1===t.indexOf(1*e)&&i.$setActive(1*e):t!==1*e&&i.$setActive(1*e)}return e}))}}}]).directive('bsCollapseToggle',function(){return{require:['^?ngModel','^bsCollapse'],link:function(e,t,n,a){var o=a[1];t.attr('data-toggle','collapse'),o.$registerToggle(t),e.$on('$destroy',function(){o.$unregisterToggle(t)}),t.on('click',function(){if(!n.disabled){var a=n.bsCollapseToggle&&'bs-collapse-toggle'!==n.bsCollapseToggle?n.bsCollapseToggle:o.$toggles.indexOf(t);o.$setActive(1*a),e.$apply()}})}}}).directive('bsCollapseTarget',['$animate',function(e){return{require:['^?ngModel','^bsCollapse'],link:function(t,n,a,o){function i(){var t=r.$targets.indexOf(n),a=r.$activeIndexes(),o='removeClass';angular.isArray(a)?-1!==a.indexOf(t)&&(o='addClass'):t===a&&(o='addClass'),e[o](n,r.$options.activeClass)}var r=o[1];n.addClass('collapse'),r.$options.animation&&n.addClass(r.$options.animation),r.$registerTarget(n),t.$on('$destroy',function(){r.$unregisterTarget(n)}),r.$viewChangeListeners.push(function(){i()}),i()}}}]),angular.module('mgcrea.ngStrap.button',[]).provider('$button',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s=a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.aside',['mgcrea.ngStrap.modal']).provider('$aside',function(){var e=this.defaults={animation:'am-fade-and-slide-right',prefixClass:'aside',prefixEvent:'aside',placement:'right',templateUrl:'aside/aside.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$modal',function(t){function n(n){var a={},o=angular.extend({},e,n);return a=t(o)}return n}]}).directive('bsAside',['$window','$sce','$aside',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAside&&e.$watch(o.bsAside,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.alert',['mgcrea.ngStrap.modal']).provider('$alert',function(){var e=this.defaults={animation:'am-fade',prefixClass:'alert',prefixEvent:'alert',placement:null,templateUrl:'alert/alert.tpl.html',container:!1,element:null,backdrop:!1,keyboard:!0,show:!0,duration:!1,type:!1,dismissable:!0};this.$get=['$modal','$timeout',function(t,n){function a(a){var o={},i=angular.extend({},e,a);o=t(i),o.$scope.dismissable=!!i.dismissable,i.type&&(o.$scope.type=i.type);var r=o.show;return i.duration&&(o.show=function(){r(),n(function(){o.hide()},1e3*i.duration)}),o}return a}]}).directive('bsAlert',['$window','$sce','$alert',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','placement','keyboard','html','container','animation','duration','dismissable'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['keyboard','html','container','dismissable'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),e.hasOwnProperty('title')||(e.title=''),angular.forEach(['title','content','type'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAlert&&e.$watch(o.bsAlert,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.affix',['mgcrea.ngStrap.helpers.dimensions','mgcrea.ngStrap.helpers.debounce']).provider('$affix',function(){var e=this.defaults={offsetTop:'auto',inlineStyles:!0};this.$get=['$window','debounce','dimensions',function(t,n,a){function o(o,s){function l(e,t,n){var a=u(),o=c();return v>=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document);
11
+ //# sourceMappingURL=angular-strap.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["angular-strap.js","helpers/compiler.js","helpers/date-formatter.js","affix/affix.js","alert/alert.js","aside/aside.js","button/button.js","collapse/collapse.js","datepicker/datepicker.js","dropdown/dropdown.js","helpers/date-parser.js","helpers/debounce.js","helpers/dimensions.js","helpers/parse-options.js","helpers/raf.js","modal/modal.js","navbar/navbar.js","popover/popover.js","scrollspy/scrollspy.js","select/select.js","timepicker/timepicker.js","tab/tab.js","typeahead/typeahead.js","tooltip/tooltip.js"],"names":["window","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","getDefaultLocale","$locale","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","data","apply","bodyEl","$window","body","windowEl","defaults","AffixFactory","offsetTop","$affix","inlineStyles","$get","reset","setWidth","initialAffixTop","offsetParent","match","getRequiredAffixClass","unpin","position","top","scrollTop","getScrollTop","scrollHeight","getScrollHeight","targetEl","pageYOffset","directive","parent","target","initialOffsetTop","offsetBottom","affixed","init","i","$parseOffsets","on","checkPosition","require","checkPositionWithEventLoop","dimensions","offset","destroy","style","width","off","affix","setTimeout","elementHeight","height","css","addClass","offsetUnpin","offsetHeight","offsetWidth","$debouncedOnResize","$onResize","initialPosition","restrict","affixTarget","$element","option","$on","attr","test","animation","prefixClass","container","provider","backdrop","keyboard","show","duration","type","dismissable","AlertFactory","$alert","$scope","config","$timeout","hide","isDefined","falseValueRegExp","hasOwnProperty","title","newValue","oldValue","trustAsHtml","bsAlert","$observe","content","alert","trigger","toggle","AsideFactory","$aside","requestAnimationFrame","$modal","bsAside","$watch","aside","activeClass","querySelectorAll","childEl","ngModel","child","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","viewValue","$formatters","push","$render","modelValue","isActive","equals","checked","activeElement","bind","toggleEvent","$modelValue","$$rAF","$setViewValue","toggleClass","$apply","hasClass","nodeName","self","startCollapsed","allowMultiple","$attrs","activeIndexes","$targets","$active","length","index","indexOf","activeItems","splice","activateItem","$options","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fn","fixActiveItemIndexes","$setActive","disallowToggle","$activeIndexes","bsCollapseCtrl","controllers","$animate","ngModelCtrl","attrs","isArray","bsCollapseToggle","$registerTarget","render","active","action","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","isNative","DatepickerFactory","parentScope","$datepicker","pickerViews","views","el","selected","date","focus","viewDate","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","select","isDate","$build","updateDisabledDates","disabledDateRanges","dateRanges","$date","$dateValue","keep","Date","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","$onKeyDown","keyCode","shiftKey","altKey","updateSelected","onKeyDown","$digest","prop","focusElement","_init","_destroy","_show","_hide","blur","navigator","userAgent","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","$setValidity","getDateFormattedString","formatDate","bsShow","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","isUndefined","NaN","daySplit","arr","mod","n","m","arrays","size","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","showLabels","labels","time","isSelected","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","placement","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","$rootScope","$new","parentEl","$isShown","removeClass","prototype","transclusion","bsDropdown","dropdown","service","splitTimeFormat","timeFormat","exec","DATETIME_FORMATS","id","getDatetimeFormat","SHORTDAY","hoursFormat","minutesFormat","secondsFormat","timeSeparator","showSeconds","dateFilter","ParseDate","seconds","$localeProvider","milliseconds","hours","array","isNumeric","parseFloat","isFinite","indexOfCaseInsensitive","len","str","toString","toLowerCase","DateParserFactory","minutes","getHours","getMilliseconds","getMinutes","proto","noop","toDate","regExpMap","sss","mm","keys","setFnMap","map","clonedFormat","search","v","sortedMap","regExpForFormat","re","join","text","Object","escapeReservedSymbols","RegExp","regex","HH","H","hh","h","a","EEEE","EEE","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","setFullYear","setMap","$format","setMapForFormat","baseDate","formatRegex","formatSetMap","matches","fromDate","substr","getTimeForAttribute","daylightSavingAdjust","undo","func","timeout","context","factory","immediate","args","cancel","callNow","leading","trailing","wait","currentStyle","getComputedStyle","extra","boxRect","getBoundingClientRect","left","docElement","ownerDocument","curPosition","curLeft","curCSSTop","documentElement","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","props","isFunction","using","offsetParentRect","offsetParentElement","outer","$parseOptions","$values","regexp","$match","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","valuesFn","$parse","keyName","cancelAnimationFrame","values","displayValue","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","timer","prefixEvent","bodyElement","ModalFactory","enterAnimateCallback","version","minor","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","bindKeyboardEvents","$onKeyUp","destroyModalElement","modalScope","$destroy","promise","$hide","$$postDigest","$id","$show","bottom","right","z-index","compileData","after","isElement","$emit","display","clonedElement","defaultPrevented","enter","backdropAnimation","safeDigest","bindBackdropEvents","leave","leaveAnimateCallback","unbindKeyboardEvents","which","$root","$$phase","query","bsModal","modal","routeAttr","$navbar","liElements","li","liElement","pattern","path","autoClose","$popover","PopoverFactory","$tooltip","dataTarget","popover","bsPopover","$applyPlacement","setViewport","viewport","spies","$document","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","checkOffsets","docEl","$activateElement","source","$getTrackedElement","filter","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","activate","scrollspy","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$select","$activeIndex","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$isActive","$isVisible","$selectNone","$matches","$updateActiveIndex","$getIndex","minLength","$viewValue","l","dataMultiple","inputEl","watchedOptions","$watchCollection","parsedOptions","bsOptions","$isEmpty","timeType","modelTimeFormat","minTime","maxTime","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","$timepicker","timepickerFactory","hour","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","floorMinutes","floor","selectedIndex","defaultDate","second","getSeconds","millisecond","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","minute","midIndex","$isDisabled","showAM","isAM","selectedTime","$arrowAction","$setTimeByStep","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","parsedTime","getTimeFormattedString","timepicker","validateAgainstMinMaxTime","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$navClass","$remove","activeIndex","$pane","$tab","transclude","postLink","bsTabsCtrl","bsActivePane","parsedBsActivePane","assign","limit","autoSelect","comparator","trimValue","$typeahead","$resetMatches","TypeaheadFactory","$filter","expression","results","typeahead","watchOptions","selectMode","isVisible","val","bsEnabled","selector","padding","String","htmlReplaceRegExp","$body","_tipToHide","tipElement","triggers","unbindTriggerEvents","$onFocusElementMouseDown","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","elRect","p","scroll","isBody","getCalculatedOffset","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","tipScope","$promise","$bsCompiler","$setEnabled","setEnabled","isEnabled","tipContainer","bindTriggerEvents","destroyTipElement","hoverState","lastChild","visibility","customClass","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","tipHeight","tipPosition","applyPlacement","tipWidth","$location","tooltip","bsTooltip"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\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// 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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 };\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: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// '<span ng-if=\"title\"><strong ng-bind=\"title\"></strong>&nbsp;</span><span ng-bind-html=\"content\"></span>' +\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: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: 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: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\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: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n\n// Source: 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 * <hljs lang=\"js\">\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 * </hljs>\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.<string, function>=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').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: 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/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<len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function($locale, dateFilter) {\n\n var DateParserFactory = function(config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}',\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function(value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function(value) { return this.setMonth(1 * value - 1); },\n 'M' : function(value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function(value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function(value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n\n var regex, setMap;\n\n $dateParser.init = function() {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function(date) {\n if(angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function(value, baseDate, format, timezone) {\n // check for date format special names\n if(format) format = $locale.DATETIME_FORMATS[format] || format;\n if(angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if(!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for(var i = 0; i < matches.length - 1; i++) {\n formatSetMap[i] && formatSetMap[i].call(date, matches[i+1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function(key, value) {\n var date;\n\n if(value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if(isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && 0 === value.length) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function(key, value) {\n var time;\n\n if(value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if(isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && 0 === value.length) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/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/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/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/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: 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, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private methods\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', 'controller', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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: 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: 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: 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: '&nbsp;<span class=\"caret\"></span>',\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 return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n }\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 evt.preventDefault();\n evt.stopPropagation();\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 // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('<button type=\"button\" class=\"btn btn-default\"></button>');\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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: 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 element.attr('autocomplete', 'false');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n})(window, document);\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 * <hljs lang=\"js\">\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 * </hljs>\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.<string, function>=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').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.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.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 // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + 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 };\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","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// '<span ng-if=\"title\"><strong ng-bind=\"title\"></strong>&nbsp;</span><span ng-bind-html=\"content\"></span>' +\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.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\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.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\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.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.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<len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function($locale, dateFilter) {\n\n var DateParserFactory = function(config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}',\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function(value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function(value) { return this.setMonth(1 * value - 1); },\n 'M' : function(value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function(value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function(value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n\n var regex, setMap;\n\n $dateParser.init = function() {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function(date) {\n if(angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function(value, baseDate, format, timezone) {\n // check for date format special names\n if(format) format = $locale.DATETIME_FORMATS[format] || format;\n if(angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if(!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for(var i = 0; i < matches.length - 1; i++) {\n formatSetMap[i] && formatSetMap[i].call(date, matches[i+1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function(key, value) {\n var date;\n\n if(value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if(isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && 0 === value.length) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function(key, value) {\n var time;\n\n if(value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if(isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && 0 === value.length) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.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.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.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\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.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, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private methods\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', 'controller', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', '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.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.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.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: '&nbsp;<span class=\"caret\"></span>',\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 return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n }\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 evt.preventDefault();\n evt.stopPropagation();\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 // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('<button type=\"button\" class=\"btn btn-default\"></button>');\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 // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.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 element.attr('autocomplete', 'false');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"}
1
+ {"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","dropdown/dropdown.js","tooltip/tooltip.js","timepicker/timepicker.js","tab/tab.js","select/select.js","popover/popover.js","scrollspy/scrollspy.js","navbar/navbar.js","modal/modal.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","datepicker/datepicker.js","collapse/collapse.js","button/button.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["prefixEvent","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","module","$http","get","defaults","animation","prefixClass","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","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","bsCompilerService","$inject","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","$typeahead","parentScope","$resetMatches","$window","$rootScope","$tooltip","$$rAF","$timeout","$matches","config","$$postDigest","$scope","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$render","$emit","length","equals","$onMouseDown","preventDefault","stopPropagation","keyCode","$digest","show","isUndefined","$element","hide","$onKeyDown","$$phase","$root","TypeaheadFactory","array","isFunction","$filter","expression","directive","results","postLink","attr","restrict","require","falseValueRegExp","bsOptions","test","parsedOptions","$parseOptions","typeahead","watchOptions","watchedOptions","$watchCollection","values","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","$setViewValue","$viewValue","substring","displayValue","slice","$formatters","push","modelValue","selected","val","destroy","label","toString","$on","target","placement","title","type","autoClose","bsEnabled","viewport","selector","padding","isTouch","TooltipFactory","$new","split","enterAnimateCallback","leaveAnimateCallback","_tipToHide","$isShown","leave","triggers","nodeName","on","toggle","enter","unbindTriggerEvents","$onFocusElementMouseDown","off","i","bindKeyboardEvents","tipElement","$onKeyUp","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$body","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","elRect","getBoundingClientRect","rect","p","width","height","top","left","dimensions","offset","el","scroll","outerDims","isBody","document","documentElement","scrollTop","body","prop","clientWidth","innerHeight","position","actualWidth","actualHeight","marginLeft","isNaN","setOffset","using","parseInt","props","css","right","marginTop","tip","offsetHeight","getViewportAdjustedDelta","delta","offsetWidth","isVertical","arrowDelta","replaceArrow","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","timeout","tipScope","$destroy","$options","$promise","$bsCompiler","toLowerCase","$id","map","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","hoverState","compileData","promise","tipContainer","init","bindTriggerEvents","isElement","focus","destroyTipElement","parent","after","lastChild","display","visibility","clonedElement","addClass","version","prepend","$applyPlacement","$animate","_blur","blur","autoPlace","autoToken","elementPosition","tipWidth","tipHeight","viewportPosition","originalPlacement","removeClass","tipPosition","getCalculatedOffset","applyPlacement","query","querySelectorAll","tooltip","transclusion","isDefined","dataTarget","hasOwnProperty","$observe","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","isNative","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","timeSeparator","minute","minutesFormat","secondsFormat","showSeconds","$iconUp","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","keep","Date","setHours","setMinutes","setSeconds","midIndex","hours","disabled","minutes","$date","seconds","rows","$isDisabled","showAM","$isSelected","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","hoursLength","minutesLength","sepLength","lateralMove","count","selectRange","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","timezoneOffsetAdjust","NaN","parse","self","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$active","$attrs","$navClass","$remove","active","activeIndex","indexOf","splice","$setActive","name","fn","$pane","$tab","transclude","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","controllers","render","$isActive","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","b","$apply","isArray","$selectScrollFix","$isIE","stopImmediatePropagation","ua","activeElement","tagName","e","dataMultiple","inputEl","addEventListener","join","$getIndex","$isEmpty","content","$popover","PopoverFactory","requestAnimationFrame","bsPopover","popover","spies","$document","windowEl","debounce","bodyEl","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","sortedElements","activeTarget","debouncedCheckOffsets","viewportHeight","debouncedCheckPosition","throttledCheckPosition","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","source","$getTrackedElement","targetElement","querySelector","trackedElement","trackElement","toDelete","untrackElement","scrollspy","childEl","child","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","bodyElement","backdropCount","dialogBaseZindex","ModalFactory","$modal","unbindBackdropEvents","modalElement","hideOnBackdropClick","backdropElement","preventEventDefault","modalScope","$show","bottom","destroyModalElement","z-index","backdropBaseZindex","customClass","minor","backdropAnimation","bindBackdropEvents","defaultPrevented","which","modalClass","bsModal","modal","dot","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","cancel","supported","$values","valueName","keyName","displayFn","valueFn","ParseOptionsFactory","groupByFn","factory","offsetParent","docElement","ownerDocument","outer","window","getComputedStyle","extra","currentStyle","boxRect","style","curPosition","curLeft","curCSSTop","curTop","calculatePosition","curElem","curCSSLeft","curOffset","call","offsetParentRect","offsetParentEl","offsetParentElement","func","immediate","args","context","callNow","leading","wait","trailing","year","$localeProvider","milliseconds","ParseDate","prototype","noop","indexOfCaseInsensitive","len","str","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","isNumeric","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","valueKey","valuesFunctionMap","valueFunction","valuesRegex","exec","setFnMap","setMap","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","regex","$format","regExpForFormat","baseDate","formatRegex","formatSetMap","fromDate","getDate","today","getDateForAttribute","substr","getTimeForAttribute","daylightSavingAdjust","undo","getTimezoneOffset","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","tAttrs","nextSibling","nodeType","parentNode","removeChild","bsDropdown","dropdown","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","updateDisabledDates","disabledDateRanges","dateRanges","mode","pristine","$updateSelected","built","$setDisabledEl","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","size","arrays","mod","n","arr","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDayOfMonthOffset","firstDate","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isSelected","getDay","months","lastDate","actualMonth","firstYear","years","actualYear","Array","setYear","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","isActive","$activeIndexes","bsCollapseCtrl","bsCollapseToggle","$registerTarget","action","toggleEvent","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","checked","bind","toggleClass","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","initialOffsetTop","getRequiredAffixClass","_unpin","getScrollTop","scrollHeight","getScrollHeight","offsetBottom","elementHeight","initialAffixTop","pageYOffset","affixed","unpin","$parseOffsets","affix","setWidth","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\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 if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\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 }\n return $filter('filter')(array, expression, comparator);\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 = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isTouch = 'createTouch' in $window.document;\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;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var 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 if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\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;\n var 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 if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\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 if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\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 var autoToken = /\\s?auto?\\s?/i;\n var 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 var tipWidth = tipElement.prop('offsetWidth');\n var 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 (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\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 if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\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 if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\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 if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\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 var 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 /* eslint-disable guard-for-in */\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\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 var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var 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 break;\n default:\n break;\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 break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var 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 var 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 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var 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 /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\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 var tooltip;\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\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\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 if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n 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 if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n 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 if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]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 var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var 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;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var 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 var 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 var 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 var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var 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 if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (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 if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (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[ao]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\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 // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\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 if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\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 }\n validateAgainstMinMaxTime(parsedTime);\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 }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: '&nbsp;<span class=\"caret\"></span>',\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[ao]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 } 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 if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\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 }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\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\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\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('<button type=\"button\" class=\"btn btn-default\"></button>');\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;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? 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 = index !== -1 ? 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 var popover;\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])) 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\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n 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 if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n 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: 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;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\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: 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 customClass: '',\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 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;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\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;\n var 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: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\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 if ($modal.$isShown) {\n $modal.hide();\n } else {\n $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 if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\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 /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\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', 'customClass', 'modalClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\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])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n 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\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: helpers/raf.js\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n 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\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;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var 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 = {};\n var label;\n var 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 () {\n\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 var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var 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 var offsetParentEl;\n var 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* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, '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 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 var args = arguments;\n var 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 if (!options) options = {};\n return function () {\n var context = this;\n var 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;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 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 } 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;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\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\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 * <hljs lang=\"js\">\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 * </hljs>\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.<string, function>=}` - 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\"], [ng-bind=\"title\"]', templateEl[0])\n .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('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (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 && 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])) options[key] = false;\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\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: 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[ao]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[ao]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 if (attr.bsShow) {\n 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 if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n 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 if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\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 }\n return new Date(date);\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('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\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);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var 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 = [];\n var 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 = [];\n var 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 = [];\n var 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 var 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 } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return 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 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 } 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 } 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 if (!attrs.disabled) {\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\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 } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n 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])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n 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\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// '<span ng-if=\"title\"><strong ng-bind=\"title\"></strong>&nbsp;</span><span ng-bind-html=\"content\"></span>' +\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 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])) 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 if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n 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\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 var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var 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 } 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 } 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 } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\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 } 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 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 }\n return 'middle';\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 if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n 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 index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\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 if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\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 }\n return $filter('filter')(array, expression, comparator);\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 = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n\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 * <hljs lang=\"js\">\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 * </hljs>\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.<string, function>=}` - 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\"], [ng-bind=\"title\"]', templateEl[0])\n .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('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (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 && 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])) options[key] = false;\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\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.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 isTouch = 'createTouch' in $window.document;\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;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var 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 if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\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;\n var 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 if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\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 if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\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 var autoToken = /\\s?auto?\\s?/i;\n var 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 var tipWidth = tipElement.prop('offsetWidth');\n var 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 (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\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 if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\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 if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\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 if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\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 var 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 /* eslint-disable guard-for-in */\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\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 var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var 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 break;\n default:\n break;\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 break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var 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 var 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 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var 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 /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\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 var tooltip;\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\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\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 if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n 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 if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n 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 if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]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 var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var 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;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var 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 var 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 var 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 var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var 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 if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (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 if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (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[ao]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\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 // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\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 if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\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 }\n validateAgainstMinMaxTime(parsedTime);\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 }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: '&nbsp;<span class=\"caret\"></span>',\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[ao]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 } 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 if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\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 }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\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\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\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('<button type=\"button\" class=\"btn btn-default\"></button>');\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;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? 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 = index !== -1 ? 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 var popover;\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])) 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\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n 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 if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n 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 if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.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;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\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.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\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 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;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\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;\n var 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: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\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 if ($modal.$isShown) {\n $modal.hide();\n } else {\n $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 if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\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 /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\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', 'customClass', 'modalClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\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])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n 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\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\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n 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","'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;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var 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 = {};\n var label;\n var 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 () {\n\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 var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var 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 var offsetParentEl;\n var 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* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, '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 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 var args = arguments;\n var 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 if (!options) options = {};\n return function () {\n var context = this;\n var 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","'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;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 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 } 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;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\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.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[ao]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[ao]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 if (attr.bsShow) {\n 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 if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n 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 if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\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 }\n return new Date(date);\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('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\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);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var 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 = [];\n var 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 = [];\n var 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 = [];\n var 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 var 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 } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return 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 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 } 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 } 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 if (!attrs.disabled) {\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\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 } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n 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])) options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n 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\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// '<span ng-if=\"title\"><strong ng-bind=\"title\"></strong>&nbsp;</span><span ng-bind-html=\"content\"></span>' +\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 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])) 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 if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n 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\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 var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var 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 } 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 } 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 } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\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 } 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 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 }\n return 'middle';\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 if (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/"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.1 - 2015-07-19
3
+ * @version v2.3.7 - 2016-01-16
4
4
  * @link http://mgcrea.github.io/angular-strap
5
5
  * @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
6
6
  * @license MIT License, http://www.opensource.org/licenses/MIT
@@ -14,30 +14,30 @@
14
14
  $templateCache.put('aside/aside.tpl.html', '<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">&times;</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
15
15
  } ]);
16
16
  angular.module('mgcrea.ngStrap.datepicker').run([ '$templateCache', function($templateCache) {
17
- $templateCache.put('datepicker/datepicker.tpl.html', '<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-show="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>');
17
+ $templateCache.put('datepicker/datepicker.tpl.html', '<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-if="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>');
18
18
  } ]);
19
19
  angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) {
20
- $templateCache.put('dropdown/dropdown.tpl.html', '<ul tabindex="-1" class="dropdown-menu" role="menu"><li role="presentation" ng-class="{divider: item.divider}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>');
20
+ $templateCache.put('dropdown/dropdown.tpl.html', '<ul tabindex="-1" class="dropdown-menu" role="menu" ng-show="content && content.length"><li role="presentation" ng-class="{divider: item.divider, active: item.active}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>');
21
21
  } ]);
22
22
  angular.module('mgcrea.ngStrap.modal').run([ '$templateCache', function($templateCache) {
23
23
  $templateCache.put('modal/modal.tpl.html', '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
24
24
  } ]);
25
25
  angular.module('mgcrea.ngStrap.popover').run([ '$templateCache', function($templateCache) {
26
- $templateCache.put('popover/popover.tpl.html', '<div class="popover"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>');
26
+ $templateCache.put('popover/popover.tpl.html', '<div class="popover" tabindex="-1"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>');
27
27
  } ]);
28
28
  angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) {
29
29
  $templateCache.put('select/select.tpl.html', '<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>');
30
30
  } ]);
31
- angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) {
32
- $templateCache.put('timepicker/timepicker.tpl.html', '<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM">&nbsp;</td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>');
33
- } ]);
34
31
  angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) {
35
32
  $templateCache.put('tab/tab.tpl.html', '<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $isActive($pane, $index) ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($pane.name || $index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>');
36
33
  } ]);
37
- angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) {
38
- $templateCache.put('typeahead/typeahead.tpl.html', '<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>');
34
+ angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) {
35
+ $templateCache.put('timepicker/timepicker.tpl.html', '<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM">&nbsp;</td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>');
39
36
  } ]);
40
37
  angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) {
41
38
  $templateCache.put('tooltip/tooltip.tpl.html', '<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>');
42
39
  } ]);
40
+ angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) {
41
+ $templateCache.put('typeahead/typeahead.tpl.html', '<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>');
42
+ } ]);
43
43
  })(window, document);
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.1 - 2015-07-19
3
+ * @version v2.3.7 - 2016-01-16
4
4
  * @link http://mgcrea.github.io/angular-strap
5
5
  * @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
6
6
  * @license MIT License, http://www.opensource.org/licenses/MIT
7
7
  */
8
- !function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','<div class="alert" ng-class="[type ? \'alert-\' + type : null]"><button type="button" class="close" ng-if="dismissable" ng-click="$hide()">&times;</button> <strong ng-bind="title"></strong>&nbsp;<span ng-bind-html="content"></span></div>')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">&times;</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-show="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','<ul tabindex="-1" class="dropdown-menu" role="menu"><li role="presentation" ng-class="{divider: item.divider}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','<div class="popover"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM">&nbsp;</td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $isActive($pane, $index) ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($pane.name || $index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>')}])}(window,document);
8
+ !function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','<div class="alert" ng-class="[type ? \'alert-\' + type : null]"><button type="button" class="close" ng-if="dismissable" ng-click="$hide()">&times;</button> <strong ng-bind="title"></strong>&nbsp;<span ng-bind-html="content"></span></div>')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">&times;</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-if="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','<ul tabindex="-1" class="dropdown-menu" role="menu" ng-show="content && content.length"><li role="presentation" ng-class="{divider: item.divider, active: item.active}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','<div class="popover" tabindex="-1"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $isActive($pane, $index) ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($pane.name || $index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM">&nbsp;</td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>')}])}(window,document);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-angular-strap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Bobrov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-23 00:00:00.000000000 Z
11
+ date: 2016-02-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Injects AngularStrap into your asset pipeline.
14
14
  email: alexander@devvela.com
@@ -48,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
48
  version: '0'
49
49
  requirements: []
50
50
  rubyforge_project:
51
- rubygems_version: 2.4.6
51
+ rubygems_version: 2.5.1
52
52
  signing_key:
53
53
  specification_version: 4
54
54
  summary: AngularStrap on Rails