rails-angular-strap 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.0 - 2015-07-12
3
+ * @version v2.3.1 - 2015-07-19
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(){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));
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
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){var a;try{a=g(e,t)}catch(o){a=[]}return n.when(a).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.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.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.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.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},i=V.viewport&&m(V.viewport.selector||V.viewport);if(!i)return o;var r=V.viewport&&V.viewport.padding||0,s=x(i);if(/right|left/.test(e)){var l=t.top-r-s.scroll,u=t.top+r-s.scroll+a;l<s.top?o.top=s.top-l:u>s.top+s.height&&(o.top=s.top+s.height-u)}else{var c=t.left-r,d=t.left+r+n;c<s.left?o.left=s.left-c:d>s.width&&(o.left=s.left+s.width-d)}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(),r=R.prop('offsetWidth'),s=R.prop('offsetHeight');if(a){var l=t,u=V.container?m(V.container):i.parent(),c=x(u);l.indexOf('bottom')>=0&&o.bottom+s>c.bottom?t=l.replace('bottom','top'):l.indexOf('top')>=0&&o.top-s<c.top&&(t=l.replace('top','bottom')),('right'===l||'bottom-left'===l||'top-left'===l)&&o.right+r>c.width?t='right'===l?'left':t.replace('left','right'):('left'===l||'bottom-right'===l||'top-right'===l)&&o.left-r<c.left&&(t='left'===l?'right':t.replace('right','left')),R.removeClass(l).addClass(t)}var d=T(t,o,r,s);C(d,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})}}}]),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,
11
- 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),a=n.getHours(),o=(h(n,k).length,n.getMinutes()),i=(h(n,x).length,n.getSeconds());h(n,T).length}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 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(){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=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,n,a,o,i){{var r=i.defaults,s=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);e.requestAnimationFrame||e.setTimeout}return{restrict:'EAC',require:'ngModel',link:function(e,t,n,l){function u(e){if(angular.isDate(e)){var t=isNaN(d.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=d.minTime,n=isNaN(d.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=d.maxTime,a=t&&n;l.$setValidity('date',a),l.$setValidity('min',t),l.$setValidity('max',n),a&&(l.$dateValue=e)}}function c(){return!l.$dateValue||isNaN(l.$dateValue.getTime())?'':m(l.$dateValue,d.timeFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],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|,?(timepicker),?/i)),e===!0?p.show():p.hide())}),s&&(d.useNative||r.useNative)&&(d.timeFormat='HH:mm');var p=i(t,l,d);d=p.$options;var g=d.lang,m=function(e,t,n){return a.formatDate(e,t,g,n)},$=o({format:d.timeFormat,lang:g});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getTimeForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(),u(l.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(l.$dateValue)},!0),l.$parsers.unshift(function(e){var t;if(!e)return l.$setValidity('date',!0),null;var n=angular.isDate(e)?e:$.parse(e,l.$dateValue);return!n||isNaN(n.getTime())?void l.$setValidity('date',!1):(u(n),'string'===d.timeType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelTimeFormat||d.timeFormat)):(t=$.timezoneOffsetAdjust(l.$dateValue,d.timezone,!0),'number'===d.timeType?t.getTime():'unix'===d.timeType?t.getTime()/1e3:'iso'===d.timeType?t.toISOString():new Date(t)))}),l.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.timeType?$.parse(e,null,d.modelTimeFormat):new Date('unix'===d.timeType?1e3*e:e),l.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),l.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]),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:'filter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$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}]}).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})}}}])}(window,document);
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
12
  //# 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","scrollspy/scrollspy.js","select/select.js","popover/popover.js","tab/tab.js","tooltip/tooltip.js","timepicker/timepicker.js","typeahead/typeahead.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","valuesPromise","err","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","$document","spies","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","$tooltip","$activeIndex","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$isActive","$isVisible","$selectNone","$matches","$updateActiveIndex","$getIndex","minLength","$viewValue","l","dataMultiple","inputEl","watchedOptions","$watchCollection","parsedOptions","bsOptions","$isEmpty","autoClose","$popover","PopoverFactory","dataTarget","popover","bsPopover","$applyPlacement","setViewport","viewport","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$navClass","$remove","activeIndex","$pane","$tab","transclude","postLink","bsTabsCtrl","bsActivePane","parsedBsActivePane","assign","customClass","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","viewportPadding","topEdgeOffset","$viewport","viewportDimensions","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","tipScope","$promise","$bsCompiler","$setEnabled","setEnabled","isEnabled","tipContainer","bindTriggerEvents","destroyTipElement","hoverState","lastChild","visibility","_blur","elementPosition","autoPlace","originalPlacement","containerPosition","tipHeight","tipPosition","applyPlacement","tipWidth","$location","tooltip","bsTooltip","timeType","modelTimeFormat","minTime","maxTime","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","timepickerFactory","hour","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","$timepicker","floorMinutes","floor","selectedIndex","defaultDate","second","getSeconds","millisecond","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","minute","midIndex","$isDisabled","showAM","isAM","selectedTime","$arrowAction","$setTimeByStep","hoursLength","triggerHandler","secondsLength","sepLength","lateralMove","count","minutesLength","selectRange","incr","isSeconds","isMeridian","createSelection","createTextRange","parsedTime","getTimeFormattedString","timepicker","validateAgainstMinMaxTime","limit","autoSelect","comparator","trimValue","$typeahead","$resetMatches","TypeaheadFactory","typeahead","watchOptions","selectMode","isVisible","val"],"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 _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 var valuesPromise;\n try {\n // Might throw 'notarray' error since cea8e75\n valuesPromise = valuesFn(scope, controller);\n } catch(err) {\n valuesPromise = [];\n }\n return $q.when(valuesPromise)\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: 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: 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: 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: 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 // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.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 > containerPosition.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 < containerPosition.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 function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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 = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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({format: options.timeFormat, lang: lang});\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;\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: 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: 'filter',\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, 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 .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 = {scope: scope};\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) return displayValue;\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)) return element.val('');\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})(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 _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 var valuesPromise;\n try {\n // Might throw 'notarray' error since cea8e75\n valuesPromise = valuesFn(scope, controller);\n } catch(err) {\n valuesPromise = [];\n }\n return $q.when(valuesPromise)\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.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.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.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.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 // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var container = options.container ? findElement(options.container) : element.parent();\n var containerPosition = getPosition(container);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > containerPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < containerPosition.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 > containerPosition.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 < containerPosition.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 function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 },\n $viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n if (!$viewport) {\n return delta;\n }\n\n var viewportPadding = options.viewport && options.viewport.padding || 0,\n viewportDimensions = getPosition($viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll,\n 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 rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n '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 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 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 {\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 = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};\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, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});\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() { $timepicker.hide(true); });\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 = [], 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({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});\n }\n var minutes = [], 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({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});\n }\n var seconds = [], 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({date: second, label: formatDate(second, secondsFormat), selected: $timepicker.$date && $timepicker.$isSelected(second, 2), disabled: $timepicker.$isDisabled(second, 2)});\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);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length;\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n }\n else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n }\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, {hour: targetDate.getHours()});\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, {minute: targetDate.getMinutes()});\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, {second: targetDate.getSeconds()});\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) return $timepicker.hide(true);\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(), 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 _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 var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\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', '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({format: options.timeFormat, lang: lang});\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;\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.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: 'filter',\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, 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 .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 = {scope: scope};\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) return displayValue;\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)) return element.val('');\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"],"sourceRoot":"/source/"}
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,6 +1,6 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.0 - 2015-07-12
3
+ * @version v2.3.1 - 2015-07-19
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
@@ -22,22 +22,22 @@
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
- angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) {
26
- $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>');
27
- } ]);
28
25
  angular.module('mgcrea.ngStrap.popover').run([ '$templateCache', function($templateCache) {
29
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>');
30
27
  } ]);
31
- angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) {
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>');
33
- } ]);
34
- angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) {
35
- $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>');
28
+ angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) {
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>');
36
30
  } ]);
37
31
  angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) {
38
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>');
39
33
  } ]);
34
+ angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) {
35
+ $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
+ } ]);
40
37
  angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) {
41
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>');
42
39
  } ]);
40
+ angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) {
41
+ $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
+ } ]);
43
43
  })(window, document);
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * angular-strap
3
- * @version v2.3.0 - 2015-07-12
3
+ * @version v2.3.1 - 2015-07-19
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.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.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.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.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.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.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);
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);
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.0
4
+ version: 2.3.1
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-15 00:00:00.000000000 Z
11
+ date: 2015-07-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Injects AngularStrap into your asset pipeline.
14
14
  email: alexander@devvela.com