You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2013/07/13 00:16:11 UTC
[1/7] git commit: Added missing semicolons to the webui.
Updated Branches:
refs/heads/master d2484213d -> 9929d2b8c
Added missing semicolons to the webui.
From: Ross Allen <ro...@mesosphe.re>
Review: https://reviews.apache.org/r/12392
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4f934cba
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4f934cba
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4f934cba
Branch: refs/heads/master
Commit: 4f934cba99501b7d109b1511d1f7bfcf038dbb13
Parents: d248421
Author: Benjamin Mahler <bm...@twitter.com>
Authored: Fri Jul 12 15:13:34 2013 -0700
Committer: Benjamin Mahler <bm...@twitter.com>
Committed: Fri Jul 12 15:13:34 2013 -0700
----------------------------------------------------------------------
src/webui/master/static/app.js | 8 ++++----
src/webui/master/static/controllers.js | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/4f934cba/src/webui/master/static/app.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/app.js b/src/webui/master/static/app.js
index e39742b..2578299 100644
--- a/src/webui/master/static/app.js
+++ b/src/webui/master/static/app.js
@@ -21,13 +21,13 @@ angular.module('mesos', []).
} else {
return '';
}
- }
+ };
})
.filter('truncateMesosState', function() {
return function(state) {
// Remove the "TASK_" prefix.
return state.substring(5);
- }
+ };
})
.filter('mesosDate', function($filter) {
return function(date) {
@@ -37,7 +37,7 @@ angular.module('mesos', []).
.filter('relativeDate', function() {
return function(date) {
return relativeDate(date);
- }
+ };
})
.filter('unixDate', function($filter) {
return function(date) {
@@ -46,7 +46,7 @@ angular.module('mesos', []).
} else {
return $filter('date')(date, 'MMM dd YYYY');
}
- }
+ };
})
.filter('dataSize', function() {
return function(bytes) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4f934cba/src/webui/master/static/controllers.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/controllers.js b/src/webui/master/static/controllers.js
index 1999763..2b3f01e 100644
--- a/src/webui/master/static/controllers.js
+++ b/src/webui/master/static/controllers.js
@@ -515,7 +515,7 @@ function SlaveCtrl($scope, $routeParams, $http, $q) {
$scope.alert_message = 'Failed to get slave usage / state: ' + reason;
$('#alert').show();
});
- }
+ };
if ($scope.state) {
update();
@@ -738,14 +738,14 @@ function BrowseCtrl($scope, $routeParams, $http) {
var pid = $scope.slaves[$routeParams.slave_id].pid;
var hostname = $scope.slaves[$routeParams.slave_id].hostname;
var id = pid.substring(0, pid.indexOf('@'));
- var host = hostname + ":" + pid.substring(pid.lastIndexOf(':') + 1)
+ var host = hostname + ":" + pid.substring(pid.lastIndexOf(':') + 1);
var url = 'http://' + host + '/files/browse.json?jsonp=JSON_CALLBACK';
$scope.slave_host = host;
$scope.pail = function($event, path) {
pailer(host, path, decodeURIComponent(path));
- }
+ };
// TODO(bmahler): Try to get the error code / body in the error callback.
// This wasn't working with the current version of angular.
@@ -766,7 +766,7 @@ function BrowseCtrl($scope, $routeParams, $http) {
}
$('#alert').show();
}
- }
+ };
if ($scope.state) {
update();
[2/7] git commit: Updated the webui breadcrumbs to use badges to
represent the Master, Slave, Framework,
and Executor. The rightmost crumb always shows the non-truncated ID.
Posted by bm...@apache.org.
Updated the webui breadcrumbs to use badges to represent the Master,
Slave, Framework, and Executor. The rightmost crumb always shows the
non-truncated ID.
From: Ross Allen <ro...@mesosphe.re>
Review: https://reviews.apache.org/r/12393
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9dac716e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9dac716e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9dac716e
Branch: refs/heads/master
Commit: 9dac716e2d1d2eacb91d717a43e2ce23c6857a83
Parents: 4f934cb
Author: Benjamin Mahler <bm...@twitter.com>
Authored: Fri Jul 12 15:13:49 2013 -0700
Committer: Benjamin Mahler <bm...@twitter.com>
Committed: Fri Jul 12 15:13:49 2013 -0700
----------------------------------------------------------------------
src/webui/master/static/browse.html | 11 ++++------
src/webui/master/static/framework.html | 15 ++++----------
src/webui/master/static/frameworks.html | 5 +++--
src/webui/master/static/home.html | 13 ++++++------
src/webui/master/static/mesos.css | 13 ++++++++++++
src/webui/master/static/slave.html | 7 +++----
src/webui/master/static/slave_executor.html | 25 +++++++----------------
src/webui/master/static/slave_framework.html | 25 ++++++-----------------
src/webui/master/static/slaves.html | 5 +++--
9 files changed, 50 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/browse.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/browse.html b/src/webui/master/static/browse.html
index 6a3d290..366e999 100644
--- a/src/webui/master/static/browse.html
+++ b/src/webui/master/static/browse.html
@@ -1,18 +1,15 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a>
+ <a class="badge badge-type" href="#">Master</a>
<span class="divider">/</span>
</li>
<li>
- <a href="#/slaves">Slaves</a>
- <span class="divider">/</span>
- </li>
- <li>
- <a href="#/slaves/{{slave_id}}">{{slaves[slave_id].hostname}}</a>
+ <a class="badge badge-type" href="#/slaves/{{slave_id}}" title="{{slave_id}}">
+ Slave</a>
<span class="divider">/</span>
</li>
<li class="active">
- <em>browse</em>
+ Browse
</li>
</ul>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/framework.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/framework.html b/src/webui/master/static/framework.html
index 77c6455..3af4b83 100644
--- a/src/webui/master/static/framework.html
+++ b/src/webui/master/static/framework.html
@@ -1,12 +1,11 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a> <span class="divider">/</span>
- </li>
- <li>
- <a href="#/frameworks">Frameworks</a> <span class="divider">/</span>
+ <a class="badge badge-type" href="#">Master</a>
+ <span class="divider">/</span>
</li>
<li class="active">
- {{framework.name}}
+ <span class="badge badge-type">Framework</span>
+ {{framework.id}}
</li>
</ul>
@@ -21,12 +20,6 @@
<dl class="inline clearfix">
<dt>Name:</dt>
<dd>{{framework.name}}</dd>
- <dt>ID:</dt>
- <dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{framework.id}}" data-original-title="ID">
- {{framework.id | truncateMesosID}}
- </a>
- </dd>
<dt>User:</dt>
<dd>{{framework.user}}</dd>
<dt>Registered:</dt>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/frameworks.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/frameworks.html b/src/webui/master/static/frameworks.html
index 0e2c691..49306ca 100644
--- a/src/webui/master/static/frameworks.html
+++ b/src/webui/master/static/frameworks.html
@@ -1,9 +1,10 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a> <span class="divider">/</span>
+ <a class="badge badge-type" href="#">Master</a>
+ <span class="divider">/</span>
</li>
<li class="active">
- Frameworks
+ <span class="badge badge-type">Frameworks</span>
</li>
</ul>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/home.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/home.html b/src/webui/master/static/home.html
index e98c975..f08abbb 100644
--- a/src/webui/master/static/home.html
+++ b/src/webui/master/static/home.html
@@ -10,6 +10,13 @@
</div>
</div>
+<ul class="breadcrumb">
+ <li class="active">
+ <span class="badge badge-type">Master</span>
+ {{state.id}}
+ </li>
+</ul>
+
<div class="row">
<div class="span3">
<div class="well">
@@ -30,12 +37,6 @@
{{state.start_time * 1000 | relativeDate}}
</a>
</dd>
- <dt>ID:</dt>
- <dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{state.id}}" data-original-title="ID">
- {{state.id | truncateMesosID}}
- </a>
- </dd>
</dl>
<p><a href="" ng-click="log($event)">LOG</a></p>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/mesos.css
----------------------------------------------------------------------
diff --git a/src/webui/master/static/mesos.css b/src/webui/master/static/mesos.css
index 9a5b4e1..34f6067 100644
--- a/src/webui/master/static/mesos.css
+++ b/src/webui/master/static/mesos.css
@@ -43,3 +43,16 @@ th.unselected:after {
padding-left: 5px;
content: " ";
}
+.badge-type {
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ font-weight: normal;
+ padding-left: 4px;
+ padding-right: 4px;
+ text-shadow: none;
+}
+
+a.badge-type:hover {
+ text-decoration: underline;
+}
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/slave.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slave.html b/src/webui/master/static/slave.html
index 74ede1d..378079c 100644
--- a/src/webui/master/static/slave.html
+++ b/src/webui/master/static/slave.html
@@ -1,11 +1,10 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a> <span class="divider">/</span>
- </li>
- <li>
- <a href="#/slaves">Slaves</a> <span class="divider">/</span>
+ <a class="badge badge-type" href="#">Master</a>
+ <span class="divider">/</span>
</li>
<li class="active">
+ <span class="badge badge-type">Slave</span>
{{slave_id}}
</li>
</ul>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/slave_executor.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slave_executor.html b/src/webui/master/static/slave_executor.html
index 354832e..4d7e8d0 100644
--- a/src/webui/master/static/slave_executor.html
+++ b/src/webui/master/static/slave_executor.html
@@ -1,24 +1,21 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a>
+ <a class="badge badge-type" href="#">Master</a>
<span class="divider">/</span>
</li>
<li>
- <a href="#/slaves">Slaves</a>
+ <a class="badge badge-type" href="#/slaves/{{slave_id}}" title="{{slave_id}}">
+ Slave</a>
<span class="divider">/</span>
</li>
<li>
- <a href="#/slaves/{{slave_id}}">{{slave_id | truncateMesosID}}</a>
- <span class="divider">/</span>
- </li>
- <li>
- <a href="#/slaves/{{slave_id}}/frameworks/{{framework_id}}">
- {{framework.name}}
- </a>
+ <a class="badge badge-type" href="#/slaves/{{slave_id}}/frameworks/{{framework_id}}" title="{{framework_id}}">
+ Framework</a>
<span class="divider">/</span>
</li>
<li class="active">
- <em>{{executor_id}}</em>
+ <span class="badge badge-type">Executor</span>
+ {{executor_id}}
</li>
</ul>
@@ -31,8 +28,6 @@
<div class="span3">
<div class="well">
<dl class="inline clearfix">
- <dt>Executor ID:</dt>
- <dd>{{executor_id}}</dd>
<dt>Executor Name:</dt>
<dd>{{executor.name}}</dd>
<dt>Executor Source:</dt>
@@ -44,12 +39,6 @@
<dd>{{cluster}}</dd>
<dt>Master:</dt>
<dd>{{state.master_hostname}}</dd>
- <dt>Framework ID:</dt>
- <dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{framework_id}}" data-original-title="ID">
- {{framework_id | truncateMesosID}}
- </a>
- </dd>
</dl>
<dl class="inline clearfix">
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/slave_framework.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slave_framework.html b/src/webui/master/static/slave_framework.html
index 74fba64..d97684e 100644
--- a/src/webui/master/static/slave_framework.html
+++ b/src/webui/master/static/slave_framework.html
@@ -1,18 +1,16 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a>
+ <a class="badge badge-type" href="#">Master</a>
<span class="divider">/</span>
</li>
<li>
- <a href="#/slaves">Slaves</a>
- <span class="divider">/</span>
- </li>
- <li>
- <a href="#/slaves/{{slave_id}}">{{slave_id | truncateMesosID}}</a>
+ <a class="badge badge-type" href="#/slaves/{{slave_id}}" title="{{slave_id}}">
+ Slave</a>
<span class="divider">/</span>
</li>
<li class="active">
- <em>{{framework.name}}</em>
+ <span class="badge badge-type">Framework</span>
+ {{framework.id}}
</li>
</ul>
@@ -25,19 +23,8 @@
<div class="span3">
<div class="well">
<dl class="inline clearfix">
- <dt>{{framework.name}}</dt>
- </dl>
-
- <dl class="inline clearfix">
- <dt>Cluster:</dt><dd>{{cluster}}</dd>
+ <dt>Name:</dt><dd>{{framework.name}}</dd>
<dt>Master:</dt><dd>{{state.master_hostname}}</dd>
- <dt>ID:</dt>
- <dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')"
- data-content="{{framework_id}}" data-original-title="ID">
- {{framework_id | truncateMesosID}}
- </a>
- </dd>
</dl>
<dl class="inline clearfix">
http://git-wip-us.apache.org/repos/asf/mesos/blob/9dac716e/src/webui/master/static/slaves.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slaves.html b/src/webui/master/static/slaves.html
index 9c73ecf..64baba9 100644
--- a/src/webui/master/static/slaves.html
+++ b/src/webui/master/static/slaves.html
@@ -1,9 +1,10 @@
<ul class="breadcrumb">
<li>
- <a href="#">Home</a> <span class="divider">/</span>
+ <a class="badge badge-type" href="#">Master</a>
+ <span class="divider">/</span>
</li>
<li class="active">
- Slaves
+ <span class="badge badge-type">Slaves</span>
</li>
</ul>
[4/7] Replaced bootstrap.js with angular-ui.js
Posted by bm...@apache.org.
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/ui-bootstrap-tpls-0.4.0.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/ui-bootstrap-tpls-0.4.0.js b/src/webui/master/static/ui-bootstrap-tpls-0.4.0.js
new file mode 100644
index 0000000..2e9eeb9
--- /dev/null
+++ b/src/webui/master/static/ui-bootstrap-tpls-0.4.0.js
@@ -0,0 +1,3165 @@
+angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.datepicker","ui.bootstrap.dialog","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.position","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
+angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/dialog/message.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead.html"]);
+angular.module('ui.bootstrap.transition', [])
+
+/**
+ * $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
+ * @param {DOMElement} element The DOMElement that will be animated.
+ * @param {string|object|function} trigger The thing that will cause the transition to start:
+ * - As a string, it represents the css class to be added to the element.
+ * - As an object, it represents a hash of style attributes to be applied to the element.
+ * - As a function, it represents a function to be called that will cause the transition to occur.
+ * @return {Promise} A promise that is resolved when the transition finishes.
+ */
+.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
+
+ var $transition = function(element, trigger, options) {
+ options = options || {};
+ var deferred = $q.defer();
+ var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"];
+
+ var transitionEndHandler = function(event) {
+ $rootScope.$apply(function() {
+ element.unbind(endEventName, transitionEndHandler);
+ deferred.resolve(element);
+ });
+ };
+
+ if (endEventName) {
+ element.bind(endEventName, transitionEndHandler);
+ }
+
+ // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
+ $timeout(function() {
+ if ( angular.isString(trigger) ) {
+ element.addClass(trigger);
+ } else if ( angular.isFunction(trigger) ) {
+ trigger(element);
+ } else if ( angular.isObject(trigger) ) {
+ element.css(trigger);
+ }
+ //If browser does not support transitions, instantly resolve
+ if ( !endEventName ) {
+ deferred.resolve(element);
+ }
+ });
+
+ // Add our custom cancel function to the promise that is returned
+ // We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
+ // i.e. it will therefore never raise a transitionEnd event for that transition
+ deferred.promise.cancel = function() {
+ if ( endEventName ) {
+ element.unbind(endEventName, transitionEndHandler);
+ }
+ deferred.reject('Transition cancelled');
+ };
+
+ return deferred.promise;
+ };
+
+ // Work out the name of the transitionEnd event
+ var transElement = document.createElement('trans');
+ var transitionEndEventNames = {
+ 'WebkitTransition': 'webkitTransitionEnd',
+ 'MozTransition': 'transitionend',
+ 'OTransition': 'oTransitionEnd',
+ 'transition': 'transitionend'
+ };
+ var animationEndEventNames = {
+ 'WebkitTransition': 'webkitAnimationEnd',
+ 'MozTransition': 'animationend',
+ 'OTransition': 'oAnimationEnd',
+ 'transition': 'animationend'
+ };
+ function findEndEventName(endEventNames) {
+ for (var name in endEventNames){
+ if (transElement.style[name] !== undefined) {
+ return endEventNames[name];
+ }
+ }
+ }
+ $transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
+ $transition.animationEndEventName = findEndEventName(animationEndEventNames);
+ return $transition;
+}]);
+
+angular.module('ui.bootstrap.collapse',['ui.bootstrap.transition'])
+
+// The collapsible directive indicates a block of html that will expand and collapse
+.directive('collapse', ['$transition', function($transition) {
+ // CSS transitions don't work with height: auto, so we have to manually change the height to a
+ // specific value and then once the animation completes, we can reset the height to auto.
+ // Unfortunately if you do this while the CSS transitions are specified (i.e. in the CSS class
+ // "collapse") then you trigger a change to height 0 in between.
+ // The fix is to remove the "collapse" CSS class while changing the height back to auto - phew!
+ var fixUpHeight = function(scope, element, height) {
+ // We remove the collapse CSS class to prevent a transition when we change to height: auto
+ element.removeClass('collapse');
+ element.css({ height: height });
+ // It appears that reading offsetWidth makes the browser realise that we have changed the
+ // height already :-/
+ var x = element[0].offsetWidth;
+ element.addClass('collapse');
+ };
+
+ return {
+ link: function(scope, element, attrs) {
+
+ var isCollapsed;
+ var initialAnimSkip = true;
+ scope.$watch(function (){ return element[0].scrollHeight; }, function (value) {
+ //The listener is called when scollHeight changes
+ //It actually does on 2 scenarios:
+ // 1. Parent is set to display none
+ // 2. angular bindings inside are resolved
+ //When we have a change of scrollHeight we are setting again the correct height if the group is opened
+ if (element[0].scrollHeight !== 0) {
+ if (!isCollapsed) {
+ if (initialAnimSkip) {
+ fixUpHeight(scope, element, element[0].scrollHeight + 'px');
+ } else {
+ fixUpHeight(scope, element, 'auto');
+ }
+ }
+ }
+ });
+
+ scope.$watch(attrs.collapse, function(value) {
+ if (value) {
+ collapse();
+ } else {
+ expand();
+ }
+ });
+
+
+ var currentTransition;
+ var doTransition = function(change) {
+ if ( currentTransition ) {
+ currentTransition.cancel();
+ }
+ currentTransition = $transition(element,change);
+ currentTransition.then(
+ function() { currentTransition = undefined; },
+ function() { currentTransition = undefined; }
+ );
+ return currentTransition;
+ };
+
+ var expand = function() {
+ if (initialAnimSkip) {
+ initialAnimSkip = false;
+ if ( !isCollapsed ) {
+ fixUpHeight(scope, element, 'auto');
+ }
+ } else {
+ doTransition({ height : element[0].scrollHeight + 'px' })
+ .then(function() {
+ // This check ensures that we don't accidentally update the height if the user has closed
+ // the group while the animation was still running
+ if ( !isCollapsed ) {
+ fixUpHeight(scope, element, 'auto');
+ }
+ });
+ }
+ isCollapsed = false;
+ };
+
+ var collapse = function() {
+ isCollapsed = true;
+ if (initialAnimSkip) {
+ initialAnimSkip = false;
+ fixUpHeight(scope, element, 0);
+ } else {
+ fixUpHeight(scope, element, element[0].scrollHeight + 'px');
+ doTransition({'height':'0'});
+ }
+ };
+ }
+ };
+}]);
+
+angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
+
+.constant('accordionConfig', {
+ closeOthers: true
+})
+
+.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {
+
+ // This array keeps track of the accordion groups
+ this.groups = [];
+
+ // Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
+ this.closeOthers = function(openGroup) {
+ var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
+ if ( closeOthers ) {
+ angular.forEach(this.groups, function (group) {
+ if ( group !== openGroup ) {
+ group.isOpen = false;
+ }
+ });
+ }
+ };
+
+ // This is called from the accordion-group directive to add itself to the accordion
+ this.addGroup = function(groupScope) {
+ var that = this;
+ this.groups.push(groupScope);
+
+ groupScope.$on('$destroy', function (event) {
+ that.removeGroup(groupScope);
+ });
+ };
+
+ // This is called from the accordion-group directive when to remove itself
+ this.removeGroup = function(group) {
+ var index = this.groups.indexOf(group);
+ if ( index !== -1 ) {
+ this.groups.splice(this.groups.indexOf(group), 1);
+ }
+ };
+
+}])
+
+// The accordion directive simply sets up the directive controller
+// and adds an accordion CSS class to itself element.
+.directive('accordion', function () {
+ return {
+ restrict:'EA',
+ controller:'AccordionController',
+ transclude: true,
+ replace: false,
+ templateUrl: 'template/accordion/accordion.html'
+ };
+})
+
+// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
+.directive('accordionGroup', ['$parse', '$transition', '$timeout', function($parse, $transition, $timeout) {
+ return {
+ require:'^accordion', // We need this directive to be inside an accordion
+ restrict:'EA',
+ transclude:true, // It transcludes the contents of the directive into the template
+ replace: true, // The element containing the directive will be replaced with the template
+ templateUrl:'template/accordion/accordion-group.html',
+ scope:{ heading:'@' }, // Create an isolated scope and interpolate the heading attribute onto this scope
+ controller: ['$scope', function($scope) {
+ this.setHeading = function(element) {
+ this.heading = element;
+ };
+ }],
+ link: function(scope, element, attrs, accordionCtrl) {
+ var getIsOpen, setIsOpen;
+
+ accordionCtrl.addGroup(scope);
+
+ scope.isOpen = false;
+
+ if ( attrs.isOpen ) {
+ getIsOpen = $parse(attrs.isOpen);
+ setIsOpen = getIsOpen.assign;
+
+ scope.$watch(
+ function watchIsOpen() { return getIsOpen(scope.$parent); },
+ function updateOpen(value) { scope.isOpen = value; }
+ );
+
+ scope.isOpen = getIsOpen ? getIsOpen(scope.$parent) : false;
+ }
+
+ scope.$watch('isOpen', function(value) {
+ if ( value ) {
+ accordionCtrl.closeOthers(scope);
+ }
+ if ( setIsOpen ) {
+ setIsOpen(scope.$parent, value);
+ }
+ });
+ }
+ };
+}])
+
+// Use accordion-heading below an accordion-group to provide a heading containing HTML
+// <accordion-group>
+// <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
+// </accordion-group>
+.directive('accordionHeading', function() {
+ return {
+ restrict: 'EA',
+ transclude: true, // Grab the contents to be used as the heading
+ template: '', // In effect remove this element!
+ replace: true,
+ require: '^accordionGroup',
+ compile: function(element, attr, transclude) {
+ return function link(scope, element, attr, accordionGroupCtrl) {
+ // Pass the heading to the accordion-group controller
+ // so that it can be transcluded into the right place in the template
+ // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
+ accordionGroupCtrl.setHeading(transclude(scope, function() {}));
+ };
+ }
+ };
+})
+
+// Use in the accordion-group template to indicate where you want the heading to be transcluded
+// You must provide the property on the accordion-group controller that will hold the transcluded element
+// <div class="accordion-group">
+// <div class="accordion-heading" ><a ... accordion-transclude="heading">...</a></div>
+// ...
+// </div>
+.directive('accordionTransclude', function() {
+ return {
+ require: '^accordionGroup',
+ link: function(scope, element, attr, controller) {
+ scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
+ if ( heading ) {
+ element.html('');
+ element.append(heading);
+ }
+ });
+ }
+ };
+});
+
+angular.module("ui.bootstrap.alert", []).directive('alert', function () {
+ return {
+ restrict:'EA',
+ templateUrl:'template/alert/alert.html',
+ transclude:true,
+ replace:true,
+ scope: {
+ type: '=',
+ close: '&'
+ },
+ link: function(scope, iElement, iAttrs, controller) {
+ scope.closeable = "close" in iAttrs;
+ }
+ };
+});
+
+angular.module('ui.bootstrap.buttons', [])
+
+ .constant('buttonConfig', {
+ activeClass:'active',
+ toggleEvent:'click'
+ })
+
+ .directive('btnRadio', ['buttonConfig', function (buttonConfig) {
+ var activeClass = buttonConfig.activeClass || 'active';
+ var toggleEvent = buttonConfig.toggleEvent || 'click';
+
+ return {
+
+ require:'ngModel',
+ link:function (scope, element, attrs, ngModelCtrl) {
+
+ //model -> UI
+ ngModelCtrl.$render = function () {
+ element.toggleClass(activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.btnRadio)));
+ };
+
+ //ui->model
+ element.bind(toggleEvent, function () {
+ if (!element.hasClass(activeClass)) {
+ scope.$apply(function () {
+ ngModelCtrl.$setViewValue(scope.$eval(attrs.btnRadio));
+ ngModelCtrl.$render();
+ });
+ }
+ });
+ }
+ };
+}])
+
+ .directive('btnCheckbox', ['buttonConfig', function (buttonConfig) {
+
+ var activeClass = buttonConfig.activeClass || 'active';
+ var toggleEvent = buttonConfig.toggleEvent || 'click';
+
+ return {
+ require:'ngModel',
+ link:function (scope, element, attrs, ngModelCtrl) {
+
+ var trueValue = scope.$eval(attrs.btnCheckboxTrue);
+ var falseValue = scope.$eval(attrs.btnCheckboxFalse);
+
+ trueValue = angular.isDefined(trueValue) ? trueValue : true;
+ falseValue = angular.isDefined(falseValue) ? falseValue : false;
+
+ //model -> UI
+ ngModelCtrl.$render = function () {
+ element.toggleClass(activeClass, angular.equals(ngModelCtrl.$modelValue, trueValue));
+ };
+
+ //ui->model
+ element.bind(toggleEvent, function () {
+ scope.$apply(function () {
+ ngModelCtrl.$setViewValue(element.hasClass(activeClass) ? falseValue : trueValue);
+ ngModelCtrl.$render();
+ });
+ });
+ }
+ };
+}]);
+/**
+* @ngdoc overview
+* @name ui.bootstrap.carousel
+*
+* @description
+* AngularJS version of an image carousel.
+*
+*/
+angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
+.controller('CarouselController', ['$scope', '$timeout', '$transition', '$q', function ($scope, $timeout, $transition, $q) {
+ var self = this,
+ slides = self.slides = [],
+ currentIndex = -1,
+ currentTimeout, isPlaying;
+ self.currentSlide = null;
+
+ /* direction: "prev" or "next" */
+ self.select = function(nextSlide, direction) {
+ var nextIndex = slides.indexOf(nextSlide);
+ //Decide direction if it's not given
+ if (direction === undefined) {
+ direction = nextIndex > currentIndex ? "next" : "prev";
+ }
+ if (nextSlide && nextSlide !== self.currentSlide) {
+ if ($scope.$currentTransition) {
+ $scope.$currentTransition.cancel();
+ //Timeout so ng-class in template has time to fix classes for finished slide
+ $timeout(goNext);
+ } else {
+ goNext();
+ }
+ }
+ function goNext() {
+ //If we have a slide to transition from and we have a transition type and we're allowed, go
+ if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
+ //We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
+ nextSlide.$element.addClass(direction);
+ nextSlide.$element[0].offsetWidth = nextSlide.$element[0].offsetWidth; //force reflow
+
+ //Set all other slides to stop doing their stuff for the new transition
+ angular.forEach(slides, function(slide) {
+ angular.extend(slide, {direction: '', entering: false, leaving: false, active: false});
+ });
+ angular.extend(nextSlide, {direction: direction, active: true, entering: true});
+ angular.extend(self.currentSlide||{}, {direction: direction, leaving: true});
+
+ $scope.$currentTransition = $transition(nextSlide.$element, {});
+ //We have to create new pointers inside a closure since next & current will change
+ (function(next,current) {
+ $scope.$currentTransition.then(
+ function(){ transitionDone(next, current); },
+ function(){ transitionDone(next, current); }
+ );
+ }(nextSlide, self.currentSlide));
+ } else {
+ transitionDone(nextSlide, self.currentSlide);
+ }
+ self.currentSlide = nextSlide;
+ currentIndex = nextIndex;
+ //every time you change slides, reset the timer
+ restartTimer();
+ }
+ function transitionDone(next, current) {
+ angular.extend(next, {direction: '', active: true, leaving: false, entering: false});
+ angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false});
+ $scope.$currentTransition = null;
+ }
+ };
+
+ /* Allow outside people to call indexOf on slides array */
+ self.indexOfSlide = function(slide) {
+ return slides.indexOf(slide);
+ };
+
+ $scope.next = function() {
+ var newIndex = (currentIndex + 1) % slides.length;
+
+ //Prevent this user-triggered transition from occurring if there is already one in progress
+ if (!$scope.$currentTransition) {
+ return self.select(slides[newIndex], 'next');
+ }
+ };
+
+ $scope.prev = function() {
+ var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
+
+ //Prevent this user-triggered transition from occurring if there is already one in progress
+ if (!$scope.$currentTransition) {
+ return self.select(slides[newIndex], 'prev');
+ }
+ };
+
+ $scope.select = function(slide) {
+ self.select(slide);
+ };
+
+ $scope.isActive = function(slide) {
+ return self.currentSlide === slide;
+ };
+
+ $scope.slides = function() {
+ return slides;
+ };
+
+ $scope.$watch('interval', restartTimer);
+ function restartTimer() {
+ if (currentTimeout) {
+ $timeout.cancel(currentTimeout);
+ }
+ function go() {
+ if (isPlaying) {
+ $scope.next();
+ restartTimer();
+ } else {
+ $scope.pause();
+ }
+ }
+ var interval = +$scope.interval;
+ if (!isNaN(interval) && interval>=0) {
+ currentTimeout = $timeout(go, interval);
+ }
+ }
+ $scope.play = function() {
+ if (!isPlaying) {
+ isPlaying = true;
+ restartTimer();
+ }
+ };
+ $scope.pause = function() {
+ if (!$scope.noPause) {
+ isPlaying = false;
+ if (currentTimeout) {
+ $timeout.cancel(currentTimeout);
+ }
+ }
+ };
+
+ self.addSlide = function(slide, element) {
+ slide.$element = element;
+ slides.push(slide);
+ //if this is the first slide or the slide is set to active, select it
+ if(slides.length === 1 || slide.active) {
+ self.select(slides[slides.length-1]);
+ if (slides.length == 1) {
+ $scope.play();
+ }
+ } else {
+ slide.active = false;
+ }
+ };
+
+ self.removeSlide = function(slide) {
+ //get the index of the slide inside the carousel
+ var index = slides.indexOf(slide);
+ slides.splice(index, 1);
+ if (slides.length > 0 && slide.active) {
+ if (index >= slides.length) {
+ self.select(slides[index-1]);
+ } else {
+ self.select(slides[index]);
+ }
+ } else if (currentIndex > index) {
+ currentIndex--;
+ }
+ };
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.carousel.directive:carousel
+ * @restrict EA
+ *
+ * @description
+ * Carousel is the outer container for a set of image 'slides' to showcase.
+ *
+ * @param {number=} interval The time, in milliseconds, that it will take the carousel to go to the next slide.
+ * @param {boolean=} noTransition Whether to disable transitions on the carousel.
+ * @param {boolean=} noPause Whether to disable pausing on the carousel (by default, the carousel interval pauses on hover).
+ *
+ * @example
+<example module="ui.bootstrap">
+ <file name="index.html">
+ <carousel>
+ <slide>
+ <img src="http://placekitten.com/150/150" style="margin:auto;">
+ <div class="carousel-caption">
+ <p>Beautiful!</p>
+ </div>
+ </slide>
+ <slide>
+ <img src="http://placekitten.com/100/150" style="margin:auto;">
+ <div class="carousel-caption">
+ <p>D'aww!</p>
+ </div>
+ </slide>
+ </carousel>
+ </file>
+ <file name="demo.css">
+ .carousel-indicators {
+ top: auto;
+ bottom: 15px;
+ }
+ </file>
+</example>
+ */
+.directive('carousel', [function() {
+ return {
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ controller: 'CarouselController',
+ require: 'carousel',
+ templateUrl: 'template/carousel/carousel.html',
+ scope: {
+ interval: '=',
+ noTransition: '=',
+ noPause: '='
+ }
+ };
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.carousel.directive:slide
+ * @restrict EA
+ *
+ * @description
+ * Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}. Must be placed as a child of a carousel element.
+ *
+ * @param {boolean=} active Model binding, whether or not this slide is currently active.
+ *
+ * @example
+<example module="ui.bootstrap">
+ <file name="index.html">
+<div ng-controller="CarouselDemoCtrl">
+ <carousel>
+ <slide ng-repeat="slide in slides" active="slide.active">
+ <img ng-src="{{slide.image}}" style="margin:auto;">
+ <div class="carousel-caption">
+ <h4>Slide {{$index}}</h4>
+ <p>{{slide.text}}</p>
+ </div>
+ </slide>
+ </carousel>
+ <div class="row-fluid">
+ <div class="span6">
+ <ul>
+ <li ng-repeat="slide in slides">
+ <button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button>
+ {{$index}}: {{slide.text}}
+ </li>
+ </ul>
+ <a class="btn" ng-click="addSlide()">Add Slide</a>
+ </div>
+ <div class="span6">
+ Interval, in milliseconds: <input type="number" ng-model="myInterval">
+ <br />Enter a negative number to stop the interval.
+ </div>
+ </div>
+</div>
+ </file>
+ <file name="script.js">
+function CarouselDemoCtrl($scope) {
+ $scope.myInterval = 5000;
+ var slides = $scope.slides = [];
+ $scope.addSlide = function() {
+ var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
+ slides.push({
+ image: 'http://placekitten.com/' + newWidth + '/200',
+ text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
+ ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
+ });
+ };
+ for (var i=0; i<4; i++) $scope.addSlide();
+}
+ </file>
+ <file name="demo.css">
+ .carousel-indicators {
+ top: auto;
+ bottom: 15px;
+ }
+ </file>
+</example>
+*/
+
+.directive('slide', ['$parse', function($parse) {
+ return {
+ require: '^carousel',
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ templateUrl: 'template/carousel/slide.html',
+ scope: {
+ },
+ link: function (scope, element, attrs, carouselCtrl) {
+ //Set up optional 'active' = binding
+ if (attrs.active) {
+ var getActive = $parse(attrs.active);
+ var setActive = getActive.assign;
+ var lastValue = scope.active = getActive(scope.$parent);
+ scope.$watch(function parentActiveWatch() {
+ var parentActive = getActive(scope.$parent);
+
+ if (parentActive !== scope.active) {
+ // we are out of sync and need to copy
+ if (parentActive !== lastValue) {
+ // parent changed and it has precedence
+ lastValue = scope.active = parentActive;
+ } else {
+ // if the parent can be assigned then do so
+ setActive(scope.$parent, parentActive = lastValue = scope.active);
+ }
+ }
+ return parentActive;
+ });
+ }
+
+ carouselCtrl.addSlide(scope, element);
+ //when the scope is destroyed then remove the slide from the current slides array
+ scope.$on('$destroy', function() {
+ carouselCtrl.removeSlide(scope);
+ });
+
+ scope.$watch('active', function(active) {
+ if (active) {
+ carouselCtrl.select(scope);
+ }
+ });
+ }
+ };
+}]);
+
+angular.module('ui.bootstrap.datepicker', [])
+
+.constant('datepickerConfig', {
+ dayFormat: 'dd',
+ monthFormat: 'MMMM',
+ yearFormat: 'yyyy',
+ dayHeaderFormat: 'EEE',
+ dayTitleFormat: 'MMMM yyyy',
+ monthTitleFormat: 'yyyy',
+ showWeeks: true,
+ startingDay: 0,
+ yearRange: 20
+})
+
+.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', function (dateFilter, $parse, datepickerConfig) {
+ return {
+ restrict: 'EA',
+ replace: true,
+ scope: {
+ model: '=ngModel',
+ dateDisabled: '&'
+ },
+ templateUrl: 'template/datepicker/datepicker.html',
+ link: function(scope, element, attrs) {
+ scope.mode = 'day'; // Initial mode
+
+ // Configuration parameters
+ var selected = new Date(), showWeeks, minDate, maxDate, format = {};
+ format.day = angular.isDefined(attrs.dayFormat) ? scope.$eval(attrs.dayFormat) : datepickerConfig.dayFormat;
+ format.month = angular.isDefined(attrs.monthFormat) ? scope.$eval(attrs.monthFormat) : datepickerConfig.monthFormat;
+ format.year = angular.isDefined(attrs.yearFormat) ? scope.$eval(attrs.yearFormat) : datepickerConfig.yearFormat;
+ format.dayHeader = angular.isDefined(attrs.dayHeaderFormat) ? scope.$eval(attrs.dayHeaderFormat) : datepickerConfig.dayHeaderFormat;
+ format.dayTitle = angular.isDefined(attrs.dayTitleFormat) ? scope.$eval(attrs.dayTitleFormat) : datepickerConfig.dayTitleFormat;
+ format.monthTitle = angular.isDefined(attrs.monthTitleFormat) ? scope.$eval(attrs.monthTitleFormat) : datepickerConfig.monthTitleFormat;
+ var startingDay = angular.isDefined(attrs.startingDay) ? scope.$eval(attrs.startingDay) : datepickerConfig.startingDay;
+ var yearRange = angular.isDefined(attrs.yearRange) ? scope.$eval(attrs.yearRange) : datepickerConfig.yearRange;
+
+ if (attrs.showWeeks) {
+ scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
+ showWeeks = !! value;
+ updateShowWeekNumbers();
+ });
+ } else {
+ showWeeks = datepickerConfig.showWeeks;
+ updateShowWeekNumbers();
+ }
+
+ if (attrs.min) {
+ scope.$parent.$watch($parse(attrs.min), function(value) {
+ minDate = new Date(value);
+ refill();
+ });
+ }
+ if (attrs.max) {
+ scope.$parent.$watch($parse(attrs.max), function(value) {
+ maxDate = new Date(value);
+ refill();
+ });
+ }
+
+ function updateCalendar (rows, labels, title) {
+ scope.rows = rows;
+ scope.labels = labels;
+ scope.title = title;
+ }
+
+ // Define whether the week number are visible
+ function updateShowWeekNumbers() {
+ scope.showWeekNumbers = ( scope.mode === 'day' && showWeeks );
+ }
+
+ function compare( date1, date2 ) {
+ if ( scope.mode === 'year') {
+ return date2.getFullYear() - date1.getFullYear();
+ } else if ( scope.mode === 'month' ) {
+ return new Date( date2.getFullYear(), date2.getMonth() ) - new Date( date1.getFullYear(), date1.getMonth() );
+ } else if ( scope.mode === 'day' ) {
+ return (new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) - new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) );
+ }
+ }
+
+ function isDisabled(date) {
+ return ((minDate && compare(date, minDate) > 0) || (maxDate && compare(date, maxDate) < 0) || (scope.dateDisabled && scope.dateDisabled({ date: date, mode: scope.mode })));
+ }
+
+ // Split array into smaller arrays
+ var split = function(a, size) {
+ var arrays = [];
+ while (a.length > 0) {
+ arrays.push(a.splice(0, size));
+ }
+ return arrays;
+ };
+ var getDaysInMonth = function( year, month ) {
+ return new Date(year, month + 1, 0).getDate();
+ };
+
+ var fill = {
+ day: function() {
+ var days = [], labels = [], lastDate = null;
+
+ function addDays( dt, n, isCurrentMonth ) {
+ for (var i =0; i < n; i ++) {
+ days.push( {date: new Date(dt), isCurrent: isCurrentMonth, isSelected: isSelected(dt), label: dateFilter(dt, format.day), disabled: isDisabled(dt) } );
+ dt.setDate( dt.getDate() + 1 );
+ }
+ lastDate = dt;
+ }
+
+ var d = new Date(selected);
+ d.setDate(1);
+
+ var difference = startingDay - d.getDay();
+ var numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference;
+
+ if ( numDisplayedFromPreviousMonth > 0 ) {
+ d.setDate( - numDisplayedFromPreviousMonth + 1 );
+ addDays(d, numDisplayedFromPreviousMonth, false);
+ }
+ addDays(lastDate || d, getDaysInMonth(selected.getFullYear(), selected.getMonth()), true);
+ addDays(lastDate, (7 - days.length % 7) % 7, false);
+
+ // Day labels
+ for (i = 0; i < 7; i++) {
+ labels.push( dateFilter(days[i].date, format.dayHeader) );
+ }
+ updateCalendar( split( days, 7 ), labels, dateFilter(selected, format.dayTitle) );
+ },
+ month: function() {
+ var months = [], i = 0, year = selected.getFullYear();
+ while ( i < 12 ) {
+ var dt = new Date(year, i++, 1);
+ months.push( {date: dt, isCurrent: true, isSelected: isSelected(dt), label: dateFilter(dt, format.month), disabled: isDisabled(dt)} );
+ }
+ updateCalendar( split( months, 3 ), [], dateFilter(selected, format.monthTitle) );
+ },
+ year: function() {
+ var years = [], year = parseInt((selected.getFullYear() - 1) / yearRange, 10) * yearRange + 1;
+ for ( var i = 0; i < yearRange; i++ ) {
+ var dt = new Date(year + i, 0, 1);
+ years.push( {date: dt, isCurrent: true, isSelected: isSelected(dt), label: dateFilter(dt, format.year), disabled: isDisabled(dt)} );
+ }
+ var title = years[0].label + ' - ' + years[years.length - 1].label;
+ updateCalendar( split( years, 5 ), [], title );
+ }
+ };
+ var refill = function() {
+ fill[scope.mode]();
+ };
+ var isSelected = function( dt ) {
+ if ( scope.model && scope.model.getFullYear() === dt.getFullYear() ) {
+ if ( scope.mode === 'year' ) {
+ return true;
+ }
+ if ( scope.model.getMonth() === dt.getMonth() ) {
+ return ( scope.mode === 'month' || (scope.mode === 'day' && scope.model.getDate() === dt.getDate()) );
+ }
+ }
+ return false;
+ };
+
+ scope.$watch('model', function ( dt, olddt ) {
+ if ( angular.isDate(dt) ) {
+ selected = angular.copy(dt);
+ }
+
+ if ( ! angular.equals(dt, olddt) ) {
+ refill();
+ }
+ });
+ scope.$watch('mode', function() {
+ updateShowWeekNumbers();
+ refill();
+ });
+
+ scope.select = function( dt ) {
+ selected = new Date(dt);
+
+ if ( scope.mode === 'year' ) {
+ scope.mode = 'month';
+ selected.setFullYear( dt.getFullYear() );
+ } else if ( scope.mode === 'month' ) {
+ scope.mode = 'day';
+ selected.setMonth( dt.getMonth() );
+ } else if ( scope.mode === 'day' ) {
+ scope.model = new Date(selected);
+ }
+ };
+ scope.move = function(step) {
+ if (scope.mode === 'day') {
+ selected.setMonth( selected.getMonth() + step );
+ } else if (scope.mode === 'month') {
+ selected.setFullYear( selected.getFullYear() + step );
+ } else if (scope.mode === 'year') {
+ selected.setFullYear( selected.getFullYear() + step * yearRange );
+ }
+ refill();
+ };
+ scope.toggleMode = function() {
+ scope.mode = ( scope.mode === 'day' ) ? 'month' : ( scope.mode === 'month' ) ? 'year' : 'day';
+ };
+ scope.getWeekNumber = function(row) {
+ if ( scope.mode !== 'day' || ! scope.showWeekNumbers || row.length !== 7 ) {
+ return;
+ }
+
+ var index = ( startingDay > 4 ) ? 11 - startingDay : 4 - startingDay; // Thursday
+ var d = new Date( row[ index ].date );
+ d.setHours(0, 0, 0);
+ return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 86400000) + 1) / 7); // 86400000 = 1000*60*60*24;
+ };
+ }
+ };
+}]);
+// The `$dialogProvider` can be used to configure global defaults for your
+// `$dialog` service.
+var dialogModule = angular.module('ui.bootstrap.dialog', ['ui.bootstrap.transition']);
+
+dialogModule.controller('MessageBoxController', ['$scope', 'dialog', 'model', function($scope, dialog, model){
+ $scope.title = model.title;
+ $scope.message = model.message;
+ $scope.buttons = model.buttons;
+ $scope.close = function(res){
+ dialog.close(res);
+ };
+}]);
+
+dialogModule.provider("$dialog", function(){
+
+ // The default options for all dialogs.
+ var defaults = {
+ backdrop: true,
+ dialogClass: 'modal',
+ backdropClass: 'modal-backdrop',
+ transitionClass: 'fade',
+ triggerClass: 'in',
+ resolve:{},
+ backdropFade: false,
+ dialogFade:false,
+ keyboard: true, // close with esc key
+ backdropClick: true // only in conjunction with backdrop=true
+ /* other options: template, templateUrl, controller */
+ };
+
+ var globalOptions = {};
+
+ var activeBackdrops = {value : 0};
+
+ // The `options({})` allows global configuration of all dialogs in the application.
+ //
+ // var app = angular.module('App', ['ui.bootstrap.dialog'], function($dialogProvider){
+ // // don't close dialog when backdrop is clicked by default
+ // $dialogProvider.options({backdropClick: false});
+ // });
+ this.options = function(value){
+ globalOptions = value;
+ };
+
+ // Returns the actual `$dialog` service that is injected in controllers
+ this.$get = ["$http", "$document", "$compile", "$rootScope", "$controller", "$templateCache", "$q", "$transition", "$injector",
+ function ($http, $document, $compile, $rootScope, $controller, $templateCache, $q, $transition, $injector) {
+
+ var body = $document.find('body');
+
+ function createElement(clazz) {
+ var el = angular.element("<div>");
+ el.addClass(clazz);
+ return el;
+ }
+
+ // The `Dialog` class represents a modal dialog. The dialog class can be invoked by providing an options object
+ // containing at lest template or templateUrl and controller:
+ //
+ // var d = new Dialog({templateUrl: 'foo.html', controller: 'BarController'});
+ //
+ // Dialogs can also be created using templateUrl and controller as distinct arguments:
+ //
+ // var d = new Dialog('path/to/dialog.html', MyDialogController);
+ function Dialog(opts) {
+
+ var self = this, options = this.options = angular.extend({}, defaults, globalOptions, opts);
+ this._open = false;
+
+ this.backdropEl = createElement(options.backdropClass);
+ if(options.backdropFade){
+ this.backdropEl.addClass(options.transitionClass);
+ this.backdropEl.removeClass(options.triggerClass);
+ }
+
+ this.modalEl = createElement(options.dialogClass);
+ if(options.dialogFade){
+ this.modalEl.addClass(options.transitionClass);
+ this.modalEl.removeClass(options.triggerClass);
+ }
+
+ this.handledEscapeKey = function(e) {
+ if (e.which === 27) {
+ self.close();
+ e.preventDefault();
+ self.$scope.$apply();
+ }
+ };
+
+ this.handleBackDropClick = function(e) {
+ self.close();
+ e.preventDefault();
+ self.$scope.$apply();
+ };
+
+ this.handleLocationChange = function() {
+ self.close();
+ };
+ }
+
+ // The `isOpen()` method returns wether the dialog is currently visible.
+ Dialog.prototype.isOpen = function(){
+ return this._open;
+ };
+
+ // The `open(templateUrl, controller)` method opens the dialog.
+ // Use the `templateUrl` and `controller` arguments if specifying them at dialog creation time is not desired.
+ Dialog.prototype.open = function(templateUrl, controller){
+ var self = this, options = this.options;
+
+ if(templateUrl){
+ options.templateUrl = templateUrl;
+ }
+ if(controller){
+ options.controller = controller;
+ }
+
+ if(!(options.template || options.templateUrl)) {
+ throw new Error('Dialog.open expected template or templateUrl, neither found. Use options or open method to specify them.');
+ }
+
+ this._loadResolves().then(function(locals) {
+ var $scope = locals.$scope = self.$scope = locals.$scope ? locals.$scope : $rootScope.$new();
+
+ self.modalEl.html(locals.$template);
+
+ if (self.options.controller) {
+ var ctrl = $controller(self.options.controller, locals);
+ self.modalEl.children().data('ngControllerController', ctrl);
+ }
+
+ $compile(self.modalEl)($scope);
+ self._addElementsToDom();
+
+ // trigger tranisitions
+ setTimeout(function(){
+ if(self.options.dialogFade){ self.modalEl.addClass(self.options.triggerClass); }
+ if(self.options.backdropFade){ self.backdropEl.addClass(self.options.triggerClass); }
+ });
+
+ self._bindEvents();
+ });
+
+ this.deferred = $q.defer();
+ return this.deferred.promise;
+ };
+
+ // closes the dialog and resolves the promise returned by the `open` method with the specified result.
+ Dialog.prototype.close = function(result){
+ var self = this;
+ var fadingElements = this._getFadingElements();
+
+ if(fadingElements.length > 0){
+ for (var i = fadingElements.length - 1; i >= 0; i--) {
+ $transition(fadingElements[i], removeTriggerClass).then(onCloseComplete);
+ }
+ return;
+ }
+
+ this._onCloseComplete(result);
+
+ function removeTriggerClass(el){
+ el.removeClass(self.options.triggerClass);
+ }
+
+ function onCloseComplete(){
+ if(self._open){
+ self._onCloseComplete(result);
+ }
+ }
+ };
+
+ Dialog.prototype._getFadingElements = function(){
+ var elements = [];
+ if(this.options.dialogFade){
+ elements.push(this.modalEl);
+ }
+ if(this.options.backdropFade){
+ elements.push(this.backdropEl);
+ }
+
+ return elements;
+ };
+
+ Dialog.prototype._bindEvents = function() {
+ if(this.options.keyboard){ body.bind('keydown', this.handledEscapeKey); }
+ if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.bind('click', this.handleBackDropClick); }
+ };
+
+ Dialog.prototype._unbindEvents = function() {
+ if(this.options.keyboard){ body.unbind('keydown', this.handledEscapeKey); }
+ if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.unbind('click', this.handleBackDropClick); }
+ };
+
+ Dialog.prototype._onCloseComplete = function(result) {
+ this._removeElementsFromDom();
+ this._unbindEvents();
+
+ this.deferred.resolve(result);
+ };
+
+ Dialog.prototype._addElementsToDom = function(){
+ body.append(this.modalEl);
+
+ if(this.options.backdrop) {
+ if (activeBackdrops.value === 0) {
+ body.append(this.backdropEl);
+ }
+ activeBackdrops.value++;
+ }
+
+ this._open = true;
+ };
+
+ Dialog.prototype._removeElementsFromDom = function(){
+ this.modalEl.remove();
+
+ if(this.options.backdrop) {
+ activeBackdrops.value--;
+ if (activeBackdrops.value === 0) {
+ this.backdropEl.remove();
+ }
+ }
+ this._open = false;
+ };
+
+ // Loads all `options.resolve` members to be used as locals for the controller associated with the dialog.
+ Dialog.prototype._loadResolves = function(){
+ var values = [], keys = [], templatePromise, self = this;
+
+ if (this.options.template) {
+ templatePromise = $q.when(this.options.template);
+ } else if (this.options.templateUrl) {
+ templatePromise = $http.get(this.options.templateUrl, {cache:$templateCache})
+ .then(function(response) { return response.data; });
+ }
+
+ angular.forEach(this.options.resolve || [], function(value, key) {
+ keys.push(key);
+ values.push(angular.isString(value) ? $injector.get(value) : $injector.invoke(value));
+ });
+
+ keys.push('$template');
+ values.push(templatePromise);
+
+ return $q.all(values).then(function(values) {
+ var locals = {};
+ angular.forEach(values, function(value, index) {
+ locals[keys[index]] = value;
+ });
+ locals.dialog = self;
+ return locals;
+ });
+ };
+
+ // The actual `$dialog` service that is injected in controllers.
+ return {
+ // Creates a new `Dialog` with the specified options.
+ dialog: function(opts){
+ return new Dialog(opts);
+ },
+ // creates a new `Dialog` tied to the default message box template and controller.
+ //
+ // Arguments `title` and `message` are rendered in the modal header and body sections respectively.
+ // The `buttons` array holds an object with the following members for each button to include in the
+ // modal footer section:
+ //
+ // * `result`: the result to pass to the `close` method of the dialog when the button is clicked
+ // * `label`: the label of the button
+ // * `cssClass`: additional css class(es) to apply to the button for styling
+ messageBox: function(title, message, buttons){
+ return new Dialog({templateUrl: 'template/dialog/message.html', controller: 'MessageBoxController', resolve:
+ {model: function() {
+ return {
+ title: title,
+ message: message,
+ buttons: buttons
+ };
+ }
+ }});
+ }
+ };
+ }];
+});
+
+/*
+ * dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
+ * @restrict class or attribute
+ * @example:
+ <li class="dropdown">
+ <a class="dropdown-toggle">My Dropdown Menu</a>
+ <ul class="dropdown-menu">
+ <li ng-repeat="choice in dropChoices">
+ <a ng-href="{{choice.href}}">{{choice.text}}</a>
+ </li>
+ </ul>
+ </li>
+ */
+
+angular.module('ui.bootstrap.dropdownToggle', []).directive('dropdownToggle', ['$document', '$location', function ($document, $location) {
+ var openElement = null,
+ closeMenu = angular.noop;
+ return {
+ restrict: 'CA',
+ link: function(scope, element, attrs) {
+ scope.$watch('$location.path', function() { closeMenu(); });
+ element.parent().bind('click', function() { closeMenu(); });
+ element.bind('click', function (event) {
+
+ var elementWasOpen = (element === openElement);
+
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (!!openElement) {
+ closeMenu();
+ }
+
+ if (!elementWasOpen) {
+ element.parent().addClass('open');
+ openElement = element;
+ closeMenu = function (event) {
+ if (event) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ $document.unbind('click', closeMenu);
+ element.parent().removeClass('open');
+ closeMenu = angular.noop;
+ openElement = null;
+ };
+ $document.bind('click', closeMenu);
+ }
+ });
+ }
+ };
+}]);
+angular.module('ui.bootstrap.modal', ['ui.bootstrap.dialog'])
+.directive('modal', ['$parse', '$dialog', function($parse, $dialog) {
+ return {
+ restrict: 'EA',
+ terminal: true,
+ link: function(scope, elm, attrs) {
+ var opts = angular.extend({}, scope.$eval(attrs.uiOptions || attrs.bsOptions || attrs.options));
+ var shownExpr = attrs.modal || attrs.show;
+ var setClosed;
+
+ // Create a dialog with the template as the contents of the directive
+ // Add the current scope as the resolve in order to make the directive scope as a dialog controller scope
+ opts = angular.extend(opts, {
+ template: elm.html(),
+ resolve: { $scope: function() { return scope; } }
+ });
+ var dialog = $dialog.dialog(opts);
+
+ elm.remove();
+
+ if (attrs.close) {
+ setClosed = function() {
+ $parse(attrs.close)(scope);
+ };
+ } else {
+ setClosed = function() {
+ if (angular.isFunction($parse(shownExpr).assign)) {
+ $parse(shownExpr).assign(scope, false);
+ }
+ };
+ }
+
+ scope.$watch(shownExpr, function(isShown, oldShown) {
+ if (isShown) {
+ dialog.open().then(function(){
+ setClosed();
+ });
+ } else {
+ //Make sure it is not opened
+ if (dialog.isOpen()){
+ dialog.close();
+ }
+ }
+ });
+ }
+ };
+}]);
+angular.module('ui.bootstrap.pagination', [])
+
+.controller('PaginationController', ['$scope', function (scope) {
+
+ scope.noPrevious = function() {
+ return scope.currentPage === 1;
+ };
+ scope.noNext = function() {
+ return scope.currentPage === scope.numPages;
+ };
+
+ scope.isActive = function(page) {
+ return scope.currentPage === page;
+ };
+
+ scope.selectPage = function(page) {
+ if ( ! scope.isActive(page) && page > 0 && page <= scope.numPages) {
+ scope.currentPage = page;
+ scope.onSelectPage({ page: page });
+ }
+ };
+}])
+
+.constant('paginationConfig', {
+ boundaryLinks: false,
+ directionLinks: true,
+ firstText: 'First',
+ previousText: 'Previous',
+ nextText: 'Next',
+ lastText: 'Last',
+ rotate: true
+})
+
+.directive('pagination', ['paginationConfig', function(paginationConfig) {
+ return {
+ restrict: 'EA',
+ scope: {
+ numPages: '=',
+ currentPage: '=',
+ maxSize: '=',
+ onSelectPage: '&'
+ },
+ controller: 'PaginationController',
+ templateUrl: 'template/pagination/pagination.html',
+ replace: true,
+ link: function(scope, element, attrs) {
+
+ // Setup configuration parameters
+ var boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks;
+ var directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$eval(attrs.directionLinks) : paginationConfig.directionLinks;
+ var firstText = angular.isDefined(attrs.firstText) ? scope.$parent.$eval(attrs.firstText) : paginationConfig.firstText;
+ var previousText = angular.isDefined(attrs.previousText) ? scope.$parent.$eval(attrs.previousText) : paginationConfig.previousText;
+ var nextText = angular.isDefined(attrs.nextText) ? scope.$parent.$eval(attrs.nextText) : paginationConfig.nextText;
+ var lastText = angular.isDefined(attrs.lastText) ? scope.$parent.$eval(attrs.lastText) : paginationConfig.lastText;
+ var rotate = angular.isDefined(attrs.rotate) ? scope.$eval(attrs.rotate) : paginationConfig.rotate;
+
+ // Create page object used in template
+ function makePage(number, text, isActive, isDisabled) {
+ return {
+ number: number,
+ text: text,
+ active: isActive,
+ disabled: isDisabled
+ };
+ }
+
+ scope.$watch('numPages + currentPage + maxSize', function() {
+ scope.pages = [];
+
+ // Default page limits
+ var startPage = 1, endPage = scope.numPages;
+ var isMaxSized = ( angular.isDefined(scope.maxSize) && scope.maxSize < scope.numPages );
+
+ // recompute if maxSize
+ if ( isMaxSized ) {
+ if ( rotate ) {
+ // Current page is displayed in the middle of the visible ones
+ startPage = Math.max(scope.currentPage - Math.floor(scope.maxSize/2), 1);
+ endPage = startPage + scope.maxSize - 1;
+
+ // Adjust if limit is exceeded
+ if (endPage > scope.numPages) {
+ endPage = scope.numPages;
+ startPage = endPage - scope.maxSize + 1;
+ }
+ } else {
+ // Visible pages are paginated with maxSize
+ startPage = ((Math.ceil(scope.currentPage / scope.maxSize) - 1) * scope.maxSize) + 1;
+
+ // Adjust last page if limit is exceeded
+ endPage = Math.min(startPage + scope.maxSize - 1, scope.numPages);
+ }
+ }
+
+ // Add page number links
+ for (var number = startPage; number <= endPage; number++) {
+ var page = makePage(number, number, scope.isActive(number), false);
+ scope.pages.push(page);
+ }
+
+ // Add links to move between page sets
+ if ( isMaxSized && ! rotate ) {
+ if ( startPage > 1 ) {
+ var previousPageSet = makePage(startPage - 1, '...', false, false);
+ scope.pages.unshift(previousPageSet);
+ }
+
+ if ( endPage < scope.numPages ) {
+ var nextPageSet = makePage(endPage + 1, '...', false, false);
+ scope.pages.push(nextPageSet);
+ }
+ }
+
+ // Add previous & next links
+ if (directionLinks) {
+ var previousPage = makePage(scope.currentPage - 1, previousText, false, scope.noPrevious());
+ scope.pages.unshift(previousPage);
+
+ var nextPage = makePage(scope.currentPage + 1, nextText, false, scope.noNext());
+ scope.pages.push(nextPage);
+ }
+
+ // Add first & last links
+ if (boundaryLinks) {
+ var firstPage = makePage(1, firstText, false, scope.noPrevious());
+ scope.pages.unshift(firstPage);
+
+ var lastPage = makePage(scope.numPages, lastText, false, scope.noNext());
+ scope.pages.push(lastPage);
+ }
+
+ if ( scope.currentPage > scope.numPages ) {
+ scope.selectPage(scope.numPages);
+ }
+ });
+ }
+ };
+}])
+
+.constant('pagerConfig', {
+ previousText: '« Previous',
+ nextText: 'Next »',
+ align: true
+})
+
+.directive('pager', ['pagerConfig', function(config) {
+ return {
+ restrict: 'EA',
+ scope: {
+ numPages: '=',
+ currentPage: '=',
+ onSelectPage: '&'
+ },
+ controller: 'PaginationController',
+ templateUrl: 'template/pagination/pager.html',
+ replace: true,
+ link: function(scope, element, attrs, paginationCtrl) {
+
+ // Setup configuration parameters
+ var previousText = angular.isDefined(attrs.previousText) ? scope.$parent.$eval(attrs.previousText) : config.previousText;
+ var nextText = angular.isDefined(attrs.nextText) ? scope.$parent.$eval(attrs.nextText) : config.nextText;
+ var align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : config.align;
+
+ // Create page object used in template
+ function makePage(number, text, isDisabled, isPrevious, isNext) {
+ return {
+ number: number,
+ text: text,
+ disabled: isDisabled,
+ previous: ( align && isPrevious ),
+ next: ( align && isNext )
+ };
+ }
+
+ scope.$watch('numPages + currentPage', function() {
+ scope.pages = [];
+
+ // Add previous & next links
+ var previousPage = makePage(scope.currentPage - 1, previousText, scope.noPrevious(), true, false);
+ scope.pages.unshift(previousPage);
+
+ var nextPage = makePage(scope.currentPage + 1, nextText, scope.noNext(), false, true);
+ scope.pages.push(nextPage);
+
+ if ( scope.currentPage > scope.numPages ) {
+ scope.selectPage(scope.numPages);
+ }
+ });
+ }
+ };
+}]);
+
+angular.module('ui.bootstrap.position', [])
+
+/**
+ * A set of utility methods that can be use to retrieve position of DOM elements.
+ * It is meant to be used where we need to absolute-position DOM elements in
+ * relation to other, existing elements (this is the case for tooltips, popovers,
+ * typeahead suggestions etc.).
+ */
+ .factory('$position', ['$document', '$window', function ($document, $window) {
+
+ var mouseX, mouseY;
+
+ $document.bind('mousemove', function mouseMoved(event) {
+ mouseX = event.pageX;
+ mouseY = event.pageY;
+ });
+
+ function getStyle(el, cssprop) {
+ if (el.currentStyle) { //IE
+ return el.currentStyle[cssprop];
+ } else if ($window.getComputedStyle) {
+ return $window.getComputedStyle(el)[cssprop];
+ }
+ // finally try and get inline style
+ return el.style[cssprop];
+ }
+
+ /**
+ * Checks if a given element is statically positioned
+ * @param element - raw DOM element
+ */
+ function isStaticPositioned(element) {
+ return (getStyle(element, "position") || 'static' ) === 'static';
+ }
+
+ /**
+ * returns the closest, non-statically positioned parentOffset of a given element
+ * @param element
+ */
+ var parentOffsetEl = function (element) {
+ var docDomEl = $document[0];
+ var offsetParent = element.offsetParent || docDomEl;
+ while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent || docDomEl;
+ };
+
+ return {
+ /**
+ * Provides read-only equivalent of jQuery's position function:
+ * http://api.jquery.com/position/
+ */
+ position: function (element) {
+ var elBCR = this.offset(element);
+ var offsetParentBCR = { top: 0, left: 0 };
+ var offsetParentEl = parentOffsetEl(element[0]);
+ if (offsetParentEl != $document[0]) {
+ offsetParentBCR = this.offset(angular.element(offsetParentEl));
+ offsetParentBCR.top += offsetParentEl.clientTop;
+ offsetParentBCR.left += offsetParentEl.clientLeft;
+ }
+
+ return {
+ width: element.prop('offsetWidth'),
+ height: element.prop('offsetHeight'),
+ top: elBCR.top - offsetParentBCR.top,
+ left: elBCR.left - offsetParentBCR.left
+ };
+ },
+
+ /**
+ * Provides read-only equivalent of jQuery's offset function:
+ * http://api.jquery.com/offset/
+ */
+ offset: function (element) {
+ var boundingClientRect = element[0].getBoundingClientRect();
+ return {
+ width: element.prop('offsetWidth'),
+ height: element.prop('offsetHeight'),
+ top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop),
+ left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft)
+ };
+ },
+
+ /**
+ * Provides the coordinates of the mouse
+ */
+ mouse: function () {
+ return {x: mouseX, y: mouseY};
+ }
+ };
+ }]);
+
+/**
+ * The following features are still outstanding: animation as a
+ * function, placement as a function, inside, support for more triggers than
+ * just mouse enter/leave, html tooltips, and selector delegation.
+ */
+angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
+
+/**
+ * The $tooltip service creates tooltip- and popover-like directives as well as
+ * houses global options for them.
+ */
+.provider( '$tooltip', function () {
+ // The default options tooltip and popover.
+ var defaultOptions = {
+ placement: 'top',
+ animation: true,
+ popupDelay: 0
+ };
+
+ // Default hide triggers for each show trigger
+ var triggerMap = {
+ 'mouseenter': 'mouseleave',
+ 'click': 'click',
+ 'focus': 'blur'
+ };
+
+ // The options specified to the provider globally.
+ var globalOptions = {};
+
+ /**
+ * `options({})` allows global configuration of all tooltips in the
+ * application.
+ *
+ * var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {
+ * // place tooltips left instead of top by default
+ * $tooltipProvider.options( { placement: 'left' } );
+ * });
+ */
+ this.options = function( value ) {
+ angular.extend( globalOptions, value );
+ };
+
+ /**
+ * This allows you to extend the set of trigger mappings available. E.g.:
+ *
+ * $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
+ */
+ this.setTriggers = function setTriggers ( triggers ) {
+ angular.extend( triggerMap, triggers );
+ };
+
+ /**
+ * This is a helper function for translating camel-case to snake-case.
+ */
+ function snake_case(name){
+ var regexp = /[A-Z]/g;
+ var separator = '-';
+ return name.replace(regexp, function(letter, pos) {
+ return (pos ? separator : '') + letter.toLowerCase();
+ });
+ }
+
+ /**
+ * Returns the actual instance of the $tooltip service.
+ * TODO support multiple triggers
+ */
+ this.$get = [ '$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $parse, $document, $position, $interpolate ) {
+ return function $tooltip ( type, prefix, defaultTriggerShow ) {
+ var options = angular.extend( {}, defaultOptions, globalOptions );
+
+ /**
+ * Returns an object of show and hide triggers.
+ *
+ * If a trigger is supplied,
+ * it is used to show the tooltip; otherwise, it will use the `trigger`
+ * option passed to the `$tooltipProvider.options` method; else it will
+ * default to the trigger supplied to this directive factory.
+ *
+ * The hide trigger is based on the show trigger. If the `trigger` option
+ * was passed to the `$tooltipProvider.options` method, it will use the
+ * mapped trigger from `triggerMap` or the passed trigger if the map is
+ * undefined; otherwise, it uses the `triggerMap` value of the show
+ * trigger; else it will just use the show trigger.
+ */
+ function setTriggers ( trigger ) {
+ var show, hide;
+
+ show = trigger || options.trigger || defaultTriggerShow;
+ if ( angular.isDefined ( options.trigger ) ) {
+ hide = triggerMap[options.trigger] || show;
+ } else {
+ hide = triggerMap[show] || show;
+ }
+
+ return {
+ show: show,
+ hide: hide
+ };
+ }
+
+ var directiveName = snake_case( type );
+ var triggers = setTriggers( undefined );
+
+ var startSym = $interpolate.startSymbol();
+ var endSym = $interpolate.endSymbol();
+ var template =
+ '<'+ directiveName +'-popup '+
+ 'title="'+startSym+'tt_title'+endSym+'" '+
+ 'content="'+startSym+'tt_content'+endSym+'" '+
+ 'placement="'+startSym+'tt_placement'+endSym+'" '+
+ 'animation="tt_animation()" '+
+ 'is-open="tt_isOpen"'+
+ '>'+
+ '</'+ directiveName +'-popup>';
+
+ return {
+ restrict: 'EA',
+ scope: true,
+ link: function link ( scope, element, attrs ) {
+ var tooltip = $compile( template )( scope );
+ var transitionTimeout;
+ var popupTimeout;
+ var $body;
+ var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
+
+ // By default, the tooltip is not open.
+ // TODO add ability to start tooltip opened
+ scope.tt_isOpen = false;
+
+ function toggleTooltipBind () {
+ if ( ! scope.tt_isOpen ) {
+ showTooltipBind();
+ } else {
+ hideTooltipBind();
+ }
+ }
+
+ // Show the tooltip with delay if specified, otherwise show it immediately
+ function showTooltipBind() {
+ if ( scope.tt_popupDelay ) {
+ popupTimeout = $timeout( show, scope.tt_popupDelay );
+ } else {
+ scope.$apply( show );
+ }
+ }
+
+ function hideTooltipBind () {
+ scope.$apply(function () {
+ hide();
+ });
+ }
+
+ // Show the tooltip popup element.
+ function show() {
+ var position,
+ ttWidth,
+ ttHeight,
+ ttPosition;
+
+ // Don't show empty tooltips.
+ if ( ! scope.tt_content ) {
+ return;
+ }
+
+ // If there is a pending remove transition, we must cancel it, lest the
+ // tooltip be mysteriously removed.
+ if ( transitionTimeout ) {
+ $timeout.cancel( transitionTimeout );
+ }
+
+ // Set the initial positioning.
+ tooltip.css({ top: 0, left: 0, display: 'block' });
+
+ // Now we add it to the DOM because need some info about it. But it's not
+ // visible yet anyway.
+ if ( appendToBody ) {
+ $body = $body || $document.find( 'body' );
+ $body.append( tooltip );
+ } else {
+ element.after( tooltip );
+ }
+
+ // Get the position of the directive element.
+ position = options.appendToBody ? $position.offset( element ) : $position.position( element );
+
+ // Get the height and width of the tooltip so we can center it.
+ ttWidth = tooltip.prop( 'offsetWidth' );
+ ttHeight = tooltip.prop( 'offsetHeight' );
+
+ // Calculate the tooltip's top and left coordinates to center it with
+ // this directive.
+ switch ( scope.tt_placement ) {
+ case 'mouse':
+ var mousePos = $position.mouse();
+ ttPosition = {
+ top: mousePos.y,
+ left: mousePos.x
+ };
+ break;
+ case 'right':
+ ttPosition = {
+ top: position.top + position.height / 2 - ttHeight / 2,
+ left: position.left + position.width
+ };
+ break;
+ case 'bottom':
+ ttPosition = {
+ top: position.top + position.height,
+ left: position.left + position.width / 2 - ttWidth / 2
+ };
+ break;
+ case 'left':
+ ttPosition = {
+ top: position.top + position.height / 2 - ttHeight / 2,
+ left: position.left - ttWidth
+ };
+ break;
+ default:
+ ttPosition = {
+ top: position.top - ttHeight,
+ left: position.left + position.width / 2 - ttWidth / 2
+ };
+ break;
+ }
+
+ ttPosition.top += 'px';
+ ttPosition.left += 'px';
+
+ // Now set the calculated positioning.
+ tooltip.css( ttPosition );
+
+ // And show the tooltip.
+ scope.tt_isOpen = true;
+ }
+
+ // Hide the tooltip popup element.
+ function hide() {
+ // First things first: we don't show it anymore.
+ scope.tt_isOpen = false;
+
+ //if tooltip is going to be shown after delay, we must cancel this
+ $timeout.cancel( popupTimeout );
+
+ // And now we remove it from the DOM. However, if we have animation, we
+ // need to wait for it to expire beforehand.
+ // FIXME: this is a placeholder for a port of the transitions library.
+ if ( angular.isDefined( scope.tt_animation ) && scope.tt_animation() ) {
+ transitionTimeout = $timeout( function () { tooltip.remove(); }, 500 );
+ } else {
+ tooltip.remove();
+ }
+ }
+
+ /**
+ * Observe the relevant attributes.
+ */
+ attrs.$observe( type, function ( val ) {
+ scope.tt_content = val;
+ });
+
+ attrs.$observe( prefix+'Title', function ( val ) {
+ scope.tt_title = val;
+ });
+
+ attrs.$observe( prefix+'Placement', function ( val ) {
+ scope.tt_placement = angular.isDefined( val ) ? val : options.placement;
+ });
+
+ attrs.$observe( prefix+'Animation', function ( val ) {
+ scope.tt_animation = angular.isDefined( val ) ? $parse( val ) : function(){ return options.animation; };
+ });
+
+ attrs.$observe( prefix+'PopupDelay', function ( val ) {
+ var delay = parseInt( val, 10 );
+ scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
+ });
+
+ attrs.$observe( prefix+'Trigger', function ( val ) {
+ element.unbind( triggers.show );
+ element.unbind( triggers.hide );
+
+ triggers = setTriggers( val );
+
+ if ( triggers.show === triggers.hide ) {
+ element.bind( triggers.show, toggleTooltipBind );
+ } else {
+ element.bind( triggers.show, showTooltipBind );
+ element.bind( triggers.hide, hideTooltipBind );
+ }
+ });
+
+ attrs.$observe( prefix+'AppendToBody', function ( val ) {
+ appendToBody = angular.isDefined( val ) ? $parse( val )( scope ) : appendToBody;
+ });
+
+ // if a tooltip is attached to <body> we need to remove it on
+ // location change as its parent scope will probably not be destroyed
+ // by the change.
+ if ( appendToBody ) {
+ scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess () {
+ if ( scope.tt_isOpen ) {
+ hide();
+ }
+ });
+ }
+
+ // Make sure tooltip is destroyed and removed.
+ scope.$on('$destroy', function onDestroyTooltip() {
+ if ( scope.tt_isOpen ) {
+ hide();
+ } else {
+ tooltip.remove();
+ }
+ });
+ }
+ };
+ };
+ }];
+})
+
+.directive( 'tooltipPopup', function () {
+ return {
+ restrict: 'E',
+ replace: true,
+ scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
+ templateUrl: 'template/tooltip/tooltip-popup.html'
+ };
+})
+
+.directive( 'tooltip', [ '$tooltip', function ( $tooltip ) {
+ return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
+}])
+
+.directive( 'tooltipHtmlUnsafePopup', function () {
+ return {
+ restrict: 'E',
+ replace: true,
+ scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
+ templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
+ };
+})
+
+.directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) {
+ return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' );
+}]);
+
+/**
+ * The following features are still outstanding: popup delay, animation as a
+ * function, placement as a function, inside, support for more triggers than
+ * just mouse enter/leave, html popovers, and selector delegatation.
+ */
+angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
+.directive( 'popoverPopup', function () {
+ return {
+ restrict: 'EA',
+ replace: true,
+ scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
+ templateUrl: 'template/popover/popover.html'
+ };
+})
+.directive( 'popover', [ '$compile', '$timeout', '$parse', '$window', '$tooltip', function ( $compile, $timeout, $parse, $window, $tooltip ) {
+ return $tooltip( 'popover', 'popover', 'click' );
+}]);
+
+
+angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
+
+.constant('progressConfig', {
+ animate: true,
+ autoType: false,
+ stackedTypes: ['success', 'info', 'warning', 'danger']
+})
+
+.controller('ProgressBarController', ['$scope', '$attrs', 'progressConfig', function($scope, $attrs, progressConfig) {
+
+ // Whether bar transitions should be animated
+ var animate = angular.isDefined($attrs.animate) ? $scope.$eval($attrs.animate) : progressConfig.animate;
+ var autoType = angular.isDefined($attrs.autoType) ? $scope.$eval($attrs.autoType) : progressConfig.autoType;
+ var stackedTypes = angular.isDefined($attrs.stackedTypes) ? $scope.$eval('[' + $attrs.stackedTypes + ']') : progressConfig.stackedTypes;
+
+ // Create bar object
+ this.makeBar = function(newBar, oldBar, index) {
+ var newValue = (angular.isObject(newBar)) ? newBar.value : (newBar || 0);
+ var oldValue = (angular.isObject(oldBar)) ? oldBar.value : (oldBar || 0);
+ var type = (angular.isObject(newBar) && angular.isDefined(newBar.type)) ? newBar.type : (autoType) ? getStackedType(index || 0) : null;
+
+ return {
+ from: oldValue,
+ to: newValue,
+ type: type,
+ animate: animate
+ };
+ };
+
+ function getStackedType(index) {
+ return stackedTypes[index];
+ }
+
+ this.addBar = function(bar) {
+ $scope.bars.push(bar);
+ $scope.totalPercent += bar.to;
+ };
+
+ this.clearBars = function() {
+ $scope.bars = [];
+ $scope.totalPercent = 0;
+ };
+ this.clearBars();
+}])
+
+.directive('progress', function() {
+ return {
+ restrict: 'EA',
+ replace: true,
+ controller: 'ProgressBarController',
+ scope: {
+ value: '=percent',
+ onFull: '&',
+ onEmpty: '&'
+ },
+ templateUrl: 'template/progressbar/progress.html',
+ link: function(scope, element, attrs, controller) {
+ scope.$watch('value', function(newValue, oldValue) {
+ controller.clearBars();
+
+ if (angular.isArray(newValue)) {
+ // Stacked progress bar
+ for (var i=0, n=newValue.length; i < n; i++) {
+ controller.addBar(controller.makeBar(newValue[i], oldValue[i], i));
+ }
+ } else {
+ // Simple bar
+ controller.addBar(controller.makeBar(newValue, oldValue));
+ }
+ }, true);
+
+ // Total percent listeners
+ scope.$watch('totalPercent', function(value) {
+ if (value >= 100) {
+ scope.onFull();
+ } else if (value <= 0) {
+ scope.onEmpty();
+ }
+ }, true);
+ }
+ };
+})
+
+.directive('progressbar', ['$transition', function($transition) {
+ return {
+ restrict: 'EA',
+ replace: true,
+ scope: {
+ width: '=',
+ old: '=',
+ type: '=',
+ animate: '='
+ },
+ templateUrl: 'template/progressbar/bar.html',
+ link: function(scope, element) {
+ scope.$watch('width', function(value) {
+ if (scope.animate) {
+ element.css('width', scope.old + '%');
+ $transition(element, {width: value + '%'});
+ } else {
+ element.css('width', value + '%');
+ }
+ });
+ }
+ };
+}]);
+angular.module('ui.bootstrap.rating', [])
+
+.constant('ratingConfig', {
+ max: 5
+})
+
+.directive('rating', ['ratingConfig', '$parse', function(ratingConfig, $parse) {
+ return {
+ restrict: 'EA',
+ scope: {
+ value: '='
+ },
+ templateUrl: 'template/rating/rating.html',
+ replace: true,
+ link: function(scope, element, attrs) {
+
+ var maxRange = angular.isDefined(attrs.max) ? scope.$eval(attrs.max) : ratingConfig.max;
+
+ scope.range = [];
+ for (var i = 1; i <= maxRange; i++) {
+ scope.range.push(i);
+ }
+
+ scope.rate = function(value) {
+ if ( ! scope.readonly ) {
+ scope.value = value;
+ }
+ };
+
+ scope.enter = function(value) {
+ if ( ! scope.readonly ) {
+ scope.val = value;
+ }
+ };
+
+ scope.reset = function() {
+ scope.val = angular.copy(scope.value);
+ };
+ scope.reset();
+
+ scope.$watch('value', function(value) {
+ scope.val = value;
+ });
+
+ scope.readonly = false;
+ if (attrs.readonly) {
+ scope.$parent.$watch($parse(attrs.readonly), function(value) {
+ scope.readonly = !!value;
+ });
+ }
+ }
+ };
+}]);
+
+/**
+ * @ngdoc overview
+ * @name ui.bootstrap.tabs
+ *
+ * @description
+ * AngularJS version of the tabs directive.
+ */
+
+angular.module('ui.bootstrap.tabs', [])
+
+.directive('tabs', function() {
+ return function() {
+ throw new Error("The `tabs` directive is deprecated, please migrate to `tabset`. Instructions can be found at http://github.com/angular-ui/bootstrap/tree/master/CHANGELOG.md");
+ };
+})
+
+.controller('TabsetController', ['$scope', '$element',
+function TabsetCtrl($scope, $element) {
+ var ctrl = this,
+ tabs = ctrl.tabs = $scope.tabs = [];
+
+ ctrl.select = function(tab) {
+ angular.forEach(tabs, function(tab) {
+ tab.active = false;
+ });
+ tab.active = true;
+ };
+
+ ctrl.addTab = function addTab(tab) {
+ tabs.push(tab);
+ if (tabs.length == 1) {
+ ctrl.select(tab);
+ }
+ };
+
+ ctrl.removeTab = function removeTab(tab) {
+ var index = tabs.indexOf(tab);
+ //Select a new tab if the tab to be removed is selected
+ if (tab.active && tabs.length > 1) {
+ //If this is the last tab, select the previous tab. else, the next tab.
+ var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
+ ctrl.select(tabs[newActiveIndex]);
+ }
+ tabs.splice(index, 1);
+ };
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tabset
+ * @restrict EA
+ *
+ * @description
+ * Tabset is the outer container for the tabs directive
+ *
+ * @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
+ *
+ * @example
+<example module="ui.bootstrap">
+ <file name="index.html">
+ <tabset>
+ <tab heading="Vertical Tab 1"><b>First</b> Content!</tab>
+ <tab heading="Vertical Tab 2"><i>Second</i> Content!</tab>
+ </tabset>
+ <hr />
+ <tabset vertical="true">
+ <tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
+ <tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
+ </tabset>
+ </file>
+</example>
+ */
+.directive('tabset', function() {
+ return {
+ restrict: 'EA',
+ transclude: true,
+ scope: {},
+ controller: 'TabsetController',
+ templateUrl: 'template/tabs/tabset.html',
+ link: function(scope, element, attrs) {
+ scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
+ scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
+ }
+ };
+})
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tab
+ * @restrict EA
+ *
+ * @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}.
+ * @param {string=} select An expression to evaluate when the tab is selected.
+ * @param {boolean=} active A binding, telling whether or not this tab is selected.
+ * @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
+ *
+ * @description
+ * Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
+ *
+ * @example
+<example module="ui.bootstrap">
+ <file name="index.html">
+ <div ng-controller="TabsDemoCtrl">
+ <button class="btn btn-small" ng-click="items[0].active = true">
+ Select item 1, using active binding
+ </button>
+ <button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
+ Enable/disable item 2, using disabled binding
+ </button>
+ <br />
+ <tabset>
+ <tab heading="Tab 1">First Tab</tab>
+ <tab select="alertMe()">
+ <tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
+ Second Tab, with alert callback and html heading!
+ </tab>
+ <tab ng-repeat="item in items"
+ heading="{{item.title}}"
+ disabled="item.disabled"
+ active="item.active">
+ {{item.content}}
+ </tab>
+ </tabset>
+ </div>
+ </file>
+ <file name="script.js">
+ function TabsDemoCtrl($scope) {
+ $scope.items = [
+ { title:"Dynamic Title 1", content:"Dynamic Item 0" },
+ { title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
+ ];
+
+ $scope.alertMe = function() {
+ setTimeout(function() {
+ alert("You've selected the alert tab!");
+ });
+ };
+ };
+ </file>
+</example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tabHeading
+ * @restrict EA
+ *
+ * @description
+ * Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
+ *
+ * @example
+<example module="ui.bootstrap">
+ <file name="index.html">
+ <tabset>
+ <tab>
+ <tab-heading><b>HTML</b> in my titles?!</tab-heading>
+ And some content, too!
+ </tab>
+ <tab>
+ <tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
+ That's right.
+ </tab>
+ </tabset>
+ </file>
+</example>
+ */
+.directive('tab', ['$parse', '$http', '$templateCache', '$compile',
+function($parse, $http, $templateCache, $compile) {
+ return {
+ require: '^tabset',
+ restrict: 'EA',
+ replace: true,
+ templateUrl: 'template/tabs/tab.html',
+ transclude: true,
+ scope: {
+ heading: '@',
+ onSelect: '&select' //This callback is called in contentHeadingTransclude
+ //once it inserts the tab's content into the dom
+ },
+ controller: function() {
+ //Empty controller so other directives can require being 'under' a tab
+ },
+ compile: function(elm, attrs, transclude) {
+ return function postLink(scope, elm, attrs, tabsetCtrl) {
+ var getActive, setActive;
+ scope.active = false; // default value
+ if (attrs.active) {
+ getActive = $parse(attrs.active);
+ setActive = getActive.assign;
+ scope.$parent.$watch(getActive, function updateActive(value) {
+ if ( !!value && scope.disabled ) {
+ setActive(scope.$parent, false); // Prevent active assignment
+ } else {
+ scope.active = !!value;
+ }
+ });
+ } else {
+ setActive = getActive = angular.noop;
+ }
+
+ scope.$watch('active', function(active) {
+ setActive(scope.$parent, active);
+ if (active) {
+ tabsetCtrl.select(scope);
+ scope.onSelect();
+ }
+ });
+
+ scope.disabled = false;
+ if ( attrs.disabled ) {
+ scope.$parent.$watch($parse(attrs.disabled), function(value) {
+ scope.disabled = !! value;
+ });
+ }
+
+ scope.select = function() {
+ if ( ! scope.disabled ) {
+ scope.active = true;
+ }
+ };
+
+ tabsetCtrl.addTab(scope);
+ scope.$on('$destroy', function() {
+ tabsetCtrl.removeTab(scope);
+ });
+ //If the tabset sets this tab to active, set the parent scope's active
+ //binding too. We do this so the watch for the parent's initial active
+ //value won't overwrite what is initially set by the tabset
+ if (scope.active) {
+ setActive(scope.$parent, true);
+ }
+
+ //Transclude the collection of sibling elements. Use forEach to find
+ //the heading if it exists. We don't use a directive for tab-heading
+ //because it is problematic. Discussion @ http://git.io/MSNPwQ
+ transclude(scope.$parent, function(clone) {
+ //Look at every element in the clone collection. If it's tab-heading,
+ //mark it as that. If it's not tab-heading, mark it as tab contents
+ var contents = [], heading;
+ angular.forEach(clone, function(el) {
+ //See if it's a tab-heading attr or element directive
+ //First make sure it's a normal element, one that has a tagName
+ if (el.tagName &&
+ (el.hasAttribute("tab-heading") ||
+ el.hasAttribute("data-tab-heading") ||
+ el.tagName.toLowerCase() == "tab-heading" ||
+ el.tagName.toLowerCase() == "data-tab-heading"
+ )) {
+ heading = el;
+ } else {
+ contents.push(el);
+ }
+ });
+ //Share what we found on the scope, so our tabHeadingTransclude and
+ //tabContentTransclude directives can find out what the heading and
+ //contents are.
+ if (heading) {
+ scope.headingElement = angular.element(heading);
+ }
+ scope.contentElement = angular.element(contents);
+ });
+ };
+ }
+ };
+}])
+
+.directive('tabHeadingTransclude', [function() {
+ return {
+ restrict: 'A',
+ require: '^tab',
+ link: function(scope, elm, attrs, tabCtrl) {
+ scope.$watch('headingElement', function updateHeadingElement(heading) {
+ if (heading) {
+ elm.html('');
+ elm.append(heading);
+ }
+ });
+ }
+ };
+}])
+
+.directive('tabContentTransclude', ['$parse', function($parse) {
+ return {
+ restrict: 'A',
+ require: '^tabset',
+ link: function(scope, elm, attrs, tabsetCtrl) {
+ scope.$watch($parse(attrs.tabContentTransclude), function(tab) {
+ elm.html('');
+ if (tab) {
+ elm.append(tab.contentElement);
+ }
+ });
+ }
+ };
+}])
+
+;
+
+
+angular.module('ui.bootstrap.timepicker', [])
+
+.filter('pad', function() {
+ return function(input) {
+ if ( angular.isDefined(input) && input.toString().length < 2 ) {
+ input = '0' + input;
+ }
+ return input;
+ };
+})
+
+.constant('timepickerConfig', {
+ hourStep: 1,
+ minuteStep: 1,
+ showMeridian: true,
+ meridians: ['AM', 'PM'],
+ readonlyInput: false,
+ mousewheel: true
+})
+
+.directive('timepicker', ['padFilter', '$parse', 'timepickerConfig', function (padFilter, $parse, timepickerConfig) {
+ return {
+ restrict: 'EA',
+ require:'ngModel',
+ replace: true,
+ templateUrl: 'template/timepicker/timepicker.html',
+ scope: {
+ model: '=ngModel'
+ },
+ link: function(scope, element, attrs, ngModelCtrl) {
+ var selected = new Date(), meridians = timepickerConfig.meridians;
+
+ var hourStep = timepickerConfig.hourStep;
+ if (attrs.hourStep) {
+ scope.$parent.$watch($parse(attrs.hourStep), function(value) {
+ hourStep = parseInt(value, 10);
+ });
+ }
+
+ var minuteStep = timepickerConfig.minuteStep;
+ if (attrs.minuteStep) {
+ scope.$parent.$watch($parse(attrs.minuteStep), function(value) {
+ minuteStep = parseInt(value, 10);
+ });
+ }
+
+ // 12H / 24H mode
+ scope.showMeridian = timepickerConfig.showMeridian;
+ if (attrs.showMeridian) {
+ scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
+ scope.showMeridian = !! value;
+
+ if ( ! scope.model ) {
+ // Reset
+ var dt = new Date( selected );
+ var hours = getScopeHours();
+ if (angular.isDefined( hours )) {
+ dt.setHours( hours );
+ }
+ scope.model = new Date( dt );
+ } else {
+ refreshTemplate();
+ }
+ });
+ }
+
+ // Get scope.hours in 24H mode if valid
+ function getScopeHours ( ) {
+ var hours = parseInt( scope.hours, 10 );
+ var valid = ( scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
+ if ( !valid ) {
+ return;
+ }
+
+ if ( scope.showMeridian ) {
+ if ( hours === 12 ) {
+ hours = 0;
+ }
+ if ( scope.meridian === meridians[1] ) {
+ hours = hours + 12;
+ }
+ }
+ return hours;
+ }
+
+ // Input elements
+ var inputs = element.find('input');
+ var hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
+
+ // Respond on mousewheel spin
+ var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
+ if ( mousewheel ) {
+
+ var isScrollingUp = function(e) {
+ if (e.originalEvent) {
+ e = e.originalEvent;
+ }
+ return (e.detail || e.wheelDelta > 0);
+ };
+
+ hoursInputEl.bind('mousewheel', function(e) {
+ scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
+ e.preventDefault();
+ });
+
+ minutesInputEl.bind('mousewheel', function(e) {
+ scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
+ e.preventDefault();
+ });
+ }
+
+ var keyboardChange = false;
+ scope.readonlyInput = (angular.isDefined(attrs.readonlyInput)) ? scope.$eval(attrs.readonlyInput) : timepickerConfig.readonlyInput;
+ if ( ! scope.readonlyInput ) {
+ scope.updateHours = function() {
+ var hours = getScopeHours();
+
+ if ( angular.isDefined(hours) ) {
+ keyboardChange = 'h';
+ if ( scope.model === null ) {
+ scope.model = new Date( selected );
+ }
+ scope.model.setHours( hours );
+ } else {
+ scope.model = null;
+ scope.validHours = false;
+ }
+ };
+
+ hoursInputEl.bind('blur', function(e) {
+ if ( scope.validHours && scope.hours < 10) {
+ scope.$apply( function() {
+ scope.hours = padFilter( scope.hours );
+ });
+ }
+ });
+
+ scope.updateMinutes = function() {
+ var minutes = parseInt(scope.minutes, 10);
+ if ( minutes >= 0 && minutes < 60 ) {
+ keyboardChange = 'm';
+ if ( scope.model === null ) {
+ scope.model = new Date( selected );
+ }
+ scope.model.setMinutes( minutes );
+ } else {
+ sco
<TRUNCATED>
[7/7] git commit: Replaced bootstrap.js with angular-ui.js
Posted by bm...@apache.org.
Replaced bootstrap.js with angular-ui.js
From: Ross Allen <ro...@mesosphe.re>
Review: https://reviews.apache.org/r/12395
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9929d2b8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9929d2b8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9929d2b8
Branch: refs/heads/master
Commit: 9929d2b8c046460298e94372847fd8055f5ffd41
Parents: 9dac716
Author: Benjamin Mahler <bm...@twitter.com>
Authored: Fri Jul 12 15:15:27 2013 -0700
Committer: Benjamin Mahler <bm...@twitter.com>
Committed: Fri Jul 12 15:15:27 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 17 +-
src/webui/master/static/app.js | 7 +-
.../static/bootstrap/js/bootstrap-alert.js | 90 -
.../static/bootstrap/js/bootstrap-button.js | 96 -
.../static/bootstrap/js/bootstrap-carousel.js | 169 -
.../static/bootstrap/js/bootstrap-collapse.js | 157 -
.../static/bootstrap/js/bootstrap-dropdown.js | 100 -
.../static/bootstrap/js/bootstrap-modal.js | 218 --
.../static/bootstrap/js/bootstrap-popover.js | 98 -
.../static/bootstrap/js/bootstrap-scrollspy.js | 151 -
.../master/static/bootstrap/js/bootstrap-tab.js | 135 -
.../static/bootstrap/js/bootstrap-tooltip.js | 275 --
.../static/bootstrap/js/bootstrap-transition.js | 61 -
.../static/bootstrap/js/bootstrap-typeahead.js | 285 --
.../master/static/bootstrap/js/bootstrap.js | 1824 ----------
.../master/static/bootstrap/js/bootstrap.min.js | 6 -
src/webui/master/static/controllers.js | 51 +-
src/webui/master/static/framework.html | 10 +-
src/webui/master/static/frameworks.html | 15 +-
src/webui/master/static/home.html | 57 +-
src/webui/master/static/index.html | 12 +-
src/webui/master/static/popovers.js | 48 -
src/webui/master/static/slave.html | 32 +-
src/webui/master/static/slaves.html | 10 +-
.../master/static/ui-bootstrap-tpls-0.4.0.js | 3165 ++++++++++++++++++
.../static/ui-bootstrap-tpls-0.4.0.min.js | 2 +
26 files changed, 3288 insertions(+), 3803 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 29337df..d7eb946 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -369,7 +369,6 @@ nobase_dist_webui_DATA += \
webui/master/static/controllers.js \
webui/master/static/app.js \
webui/master/static/dashboard.js \
- webui/master/static/popovers.js \
webui/master/static/jquery.pailer.js
# Need to distribute/install webui CSS.
@@ -398,6 +397,8 @@ nobase_dist_webui_DATA += webui/master/static/loading.gif
nobase_dist_webui_DATA += \
webui/master/static/angular-1.0.7.js \
webui/master/static/angular-1.0.7.min.js \
+ webui/master/static/ui-bootstrap-tpls-0.4.0.js \
+ webui/master/static/ui-bootstrap-tpls-0.4.0.min.js \
webui/master/static/underscore-1.4.3.js \
webui/master/static/underscore-1.4.3.min.js \
webui/master/static/cubism.v1.js \
@@ -437,20 +438,6 @@ nobase_dist_webui_DATA += \
webui/master/static/bootstrap/img/less-small.png \
webui/master/static/bootstrap/img/responsive-illustrations.png \
webui/master/static/bootstrap/js/application.js \
- webui/master/static/bootstrap/js/bootstrap-alert.js \
- webui/master/static/bootstrap/js/bootstrap-button.js \
- webui/master/static/bootstrap/js/bootstrap-carousel.js \
- webui/master/static/bootstrap/js/bootstrap-collapse.js \
- webui/master/static/bootstrap/js/bootstrap-dropdown.js \
- webui/master/static/bootstrap/js/bootstrap-modal.js \
- webui/master/static/bootstrap/js/bootstrap-popover.js \
- webui/master/static/bootstrap/js/bootstrap-scrollspy.js \
- webui/master/static/bootstrap/js/bootstrap-tab.js \
- webui/master/static/bootstrap/js/bootstrap-tooltip.js \
- webui/master/static/bootstrap/js/bootstrap-transition.js \
- webui/master/static/bootstrap/js/bootstrap-typeahead.js \
- webui/master/static/bootstrap/js/bootstrap.js \
- webui/master/static/bootstrap/js/bootstrap.min.js \
webui/master/static/bootstrap/js/google-code-prettify/prettify.css \
webui/master/static/bootstrap/js/google-code-prettify/prettify.js \
webui/master/static/bootstrap/js/jquery-1.7.1.js \
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/app.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/app.js b/src/webui/master/static/app.js
index 2578299..2bfcedf 100644
--- a/src/webui/master/static/app.js
+++ b/src/webui/master/static/app.js
@@ -1,7 +1,7 @@
'use strict';
-angular.module('mesos', []).
- config(['$routeProvider', function($routeProvider) {
+angular.module('mesos', ['ui.bootstrap']).
+ config(['$dialogProvider', '$routeProvider', function($dialogProvider, $routeProvider) {
$routeProvider
.when('/', {templateUrl: 'static/home.html', controller: HomeCtrl})
.when('/dashboard', {templateUrl: 'static/dashboard.html', controller: DashboardCtrl})
@@ -13,6 +13,9 @@ angular.module('mesos', []).
.when('/slaves/:slave_id/frameworks/:framework_id/executors/:executor_id', {templateUrl: 'static/slave_executor.html', controller: SlaveExecutorCtrl})
.when('/slaves/:slave_id/browse', {templateUrl: 'static/browse.html', controller: BrowseCtrl})
.otherwise({redirectTo: '/'});
+
+ $dialogProvider.options({dialogFade: true});
+
}])
.filter('truncateMesosID', function() {
return function(id) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-alert.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-alert.js b/src/webui/master/static/bootstrap/js/bootstrap-alert.js
deleted file mode 100644
index fa0806e..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-alert.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ==========================================================
- * bootstrap-alert.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#alerts
- * ==========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* ALERT CLASS DEFINITION
- * ====================== */
-
- var dismiss = '[data-dismiss="alert"]'
- , Alert = function (el) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.prototype.close = function (e) {
- var $this = $(this)
- , selector = $this.attr('data-target')
- , $parent
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
-
- e && e.preventDefault()
-
- $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
-
- $parent.trigger(e = $.Event('close'))
-
- if (e.isDefaultPrevented()) return
-
- $parent.removeClass('in')
-
- function removeElement() {
- $parent
- .trigger('closed')
- .remove()
- }
-
- $.support.transition && $parent.hasClass('fade') ?
- $parent.on($.support.transition.end, removeElement) :
- removeElement()
- }
-
-
- /* ALERT PLUGIN DEFINITION
- * ======================= */
-
- $.fn.alert = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('alert')
- if (!data) $this.data('alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.alert.Constructor = Alert
-
-
- /* ALERT DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-button.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-button.js b/src/webui/master/static/bootstrap/js/bootstrap-button.js
deleted file mode 100644
index a9e6ba7..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-button.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ============================================================
- * bootstrap-button.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#buttons
- * ============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* BUTTON PUBLIC CLASS DEFINITION
- * ============================== */
-
- var Button = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.button.defaults, options)
- }
-
- Button.prototype.setState = function (state) {
- var d = 'disabled'
- , $el = this.$element
- , data = $el.data()
- , val = $el.is('input') ? 'val' : 'html'
-
- state = state + 'Text'
- data.resetText || $el.data('resetText', $el[val]())
-
- $el[val](data[state] || this.options[state])
-
- // push to event loop to allow forms to submit
- setTimeout(function () {
- state == 'loadingText' ?
- $el.addClass(d).attr(d, d) :
- $el.removeClass(d).removeAttr(d)
- }, 0)
- }
-
- Button.prototype.toggle = function () {
- var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
-
- $parent && $parent
- .find('.active')
- .removeClass('active')
-
- this.$element.toggleClass('active')
- }
-
-
- /* BUTTON PLUGIN DEFINITION
- * ======================== */
-
- $.fn.button = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('button')
- , options = typeof option == 'object' && option
- if (!data) $this.data('button', (data = new Button(this, options)))
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
-
- $.fn.button.defaults = {
- loadingText: 'loading...'
- }
-
- $.fn.button.Constructor = Button
-
-
- /* BUTTON DATA-API
- * =============== */
-
- $(function () {
- $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
- var $btn = $(e.target)
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
- $btn.button('toggle')
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-carousel.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-carousel.js b/src/webui/master/static/bootstrap/js/bootstrap-carousel.js
deleted file mode 100644
index 96e5a81..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-carousel.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ==========================================================
- * bootstrap-carousel.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#carousel
- * ==========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* CAROUSEL CLASS DEFINITION
- * ========================= */
-
- var Carousel = function (element, options) {
- this.$element = $(element)
- this.options = options
- this.options.slide && this.slide(this.options.slide)
- this.options.pause == 'hover' && this.$element
- .on('mouseenter', $.proxy(this.pause, this))
- .on('mouseleave', $.proxy(this.cycle, this))
- }
-
- Carousel.prototype = {
-
- cycle: function (e) {
- if (!e) this.paused = false
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
- return this
- }
-
- , to: function (pos) {
- var $active = this.$element.find('.active')
- , children = $active.parent().children()
- , activePos = children.index($active)
- , that = this
-
- if (pos > (children.length - 1) || pos < 0) return
-
- if (this.sliding) {
- return this.$element.one('slid', function () {
- that.to(pos)
- })
- }
-
- if (activePos == pos) {
- return this.pause().cycle()
- }
-
- return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
- }
-
- , pause: function (e) {
- if (!e) this.paused = true
- clearInterval(this.interval)
- this.interval = null
- return this
- }
-
- , next: function () {
- if (this.sliding) return
- return this.slide('next')
- }
-
- , prev: function () {
- if (this.sliding) return
- return this.slide('prev')
- }
-
- , slide: function (type, next) {
- var $active = this.$element.find('.active')
- , $next = next || $active[type]()
- , isCycling = this.interval
- , direction = type == 'next' ? 'left' : 'right'
- , fallback = type == 'next' ? 'first' : 'last'
- , that = this
- , e = $.Event('slide')
-
- this.sliding = true
-
- isCycling && this.pause()
-
- $next = $next.length ? $next : this.$element.find('.item')[fallback]()
-
- if ($next.hasClass('active')) return
-
- if ($.support.transition && this.$element.hasClass('slide')) {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- this.$element.one($.support.transition.end, function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () { that.$element.trigger('slid') }, 0)
- })
- } else {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger('slid')
- }
-
- isCycling && this.cycle()
-
- return this
- }
-
- }
-
-
- /* CAROUSEL PLUGIN DEFINITION
- * ========================== */
-
- $.fn.carousel = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('carousel')
- , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
- if (!data) $this.data('carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (typeof option == 'string' || (option = options.slide)) data[option]()
- else if (options.interval) data.cycle()
- })
- }
-
- $.fn.carousel.defaults = {
- interval: 5000
- , pause: 'hover'
- }
-
- $.fn.carousel.Constructor = Carousel
-
-
- /* CAROUSEL DATA-API
- * ================= */
-
- $(function () {
- $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
- $target.carousel(options)
- e.preventDefault()
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-collapse.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-collapse.js b/src/webui/master/static/bootstrap/js/bootstrap-collapse.js
deleted file mode 100644
index d02f6fd..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-collapse.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* =============================================================
- * bootstrap-collapse.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#collapse
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* COLLAPSE PUBLIC CLASS DEFINITION
- * ================================ */
-
- var Collapse = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.collapse.defaults, options)
-
- if (this.options.parent) {
- this.$parent = $(this.options.parent)
- }
-
- this.options.toggle && this.toggle()
- }
-
- Collapse.prototype = {
-
- constructor: Collapse
-
- , dimension: function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
-
- , show: function () {
- var dimension
- , scroll
- , actives
- , hasData
-
- if (this.transitioning) return
-
- dimension = this.dimension()
- scroll = $.camelCase(['scroll', dimension].join('-'))
- actives = this.$parent && this.$parent.find('> .accordion-group > .in')
-
- if (actives && actives.length) {
- hasData = actives.data('collapse')
- if (hasData && hasData.transitioning) return
- actives.collapse('hide')
- hasData || actives.data('collapse', null)
- }
-
- this.$element[dimension](0)
- this.transition('addClass', $.Event('show'), 'shown')
- this.$element[dimension](this.$element[0][scroll])
- }
-
- , hide: function () {
- var dimension
- if (this.transitioning) return
- dimension = this.dimension()
- this.reset(this.$element[dimension]())
- this.transition('removeClass', $.Event('hide'), 'hidden')
- this.$element[dimension](0)
- }
-
- , reset: function (size) {
- var dimension = this.dimension()
-
- this.$element
- .removeClass('collapse')
- [dimension](size || 'auto')
- [0].offsetWidth
-
- this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
-
- return this
- }
-
- , transition: function (method, startEvent, completeEvent) {
- var that = this
- , complete = function () {
- if (startEvent.type == 'show') that.reset()
- that.transitioning = 0
- that.$element.trigger(completeEvent)
- }
-
- this.$element.trigger(startEvent)
-
- if (startEvent.isDefaultPrevented()) return
-
- this.transitioning = 1
-
- this.$element[method]('in')
-
- $.support.transition && this.$element.hasClass('collapse') ?
- this.$element.one($.support.transition.end, complete) :
- complete()
- }
-
- , toggle: function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
-
- /* COLLAPSIBLE PLUGIN DEFINITION
- * ============================== */
-
- $.fn.collapse = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('collapse')
- , options = typeof option == 'object' && option
- if (!data) $this.data('collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.collapse.defaults = {
- toggle: true
- }
-
- $.fn.collapse.Constructor = Collapse
-
-
- /* COLLAPSIBLE DATA-API
- * ==================== */
-
- $(function () {
- $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
- var $this = $(this), href
- , target = $this.attr('data-target')
- || e.preventDefault()
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
- , option = $(target).data('collapse') ? 'toggle' : $this.data()
- $(target).collapse(option)
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-dropdown.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-dropdown.js b/src/webui/master/static/bootstrap/js/bootstrap-dropdown.js
deleted file mode 100644
index ec0588d..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-dropdown.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* ============================================================
- * bootstrap-dropdown.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#dropdowns
- * ============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* DROPDOWN CLASS DEFINITION
- * ========================= */
-
- var toggle = '[data-toggle="dropdown"]'
- , Dropdown = function (element) {
- var $el = $(element).on('click.dropdown.data-api', this.toggle)
- $('html').on('click.dropdown.data-api', function () {
- $el.parent().removeClass('open')
- })
- }
-
- Dropdown.prototype = {
-
- constructor: Dropdown
-
- , toggle: function (e) {
- var $this = $(this)
- , $parent
- , selector
- , isActive
-
- if ($this.is('.disabled, :disabled')) return
-
- selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
- $parent.length || ($parent = $this.parent())
-
- isActive = $parent.hasClass('open')
-
- clearMenus()
-
- if (!isActive) $parent.toggleClass('open')
-
- return false
- }
-
- }
-
- function clearMenus() {
- $(toggle).parent().removeClass('open')
- }
-
-
- /* DROPDOWN PLUGIN DEFINITION
- * ========================== */
-
- $.fn.dropdown = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('dropdown')
- if (!data) $this.data('dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.dropdown.Constructor = Dropdown
-
-
- /* APPLY TO STANDARD DROPDOWN ELEMENTS
- * =================================== */
-
- $(function () {
- $('html').on('click.dropdown.data-api', clearMenus)
- $('body')
- .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() })
- .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-modal.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-modal.js b/src/webui/master/static/bootstrap/js/bootstrap-modal.js
deleted file mode 100644
index c831de6..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-modal.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/* =========================================================
- * bootstrap-modal.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#modals
- * =========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================= */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* MODAL CLASS DEFINITION
- * ====================== */
-
- var Modal = function (content, options) {
- this.options = options
- this.$element = $(content)
- .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
- }
-
- Modal.prototype = {
-
- constructor: Modal
-
- , toggle: function () {
- return this[!this.isShown ? 'show' : 'hide']()
- }
-
- , show: function () {
- var that = this
- , e = $.Event('show')
-
- this.$element.trigger(e)
-
- if (this.isShown || e.isDefaultPrevented()) return
-
- $('body').addClass('modal-open')
-
- this.isShown = true
-
- escape.call(this)
- backdrop.call(this, function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
-
- if (!that.$element.parent().length) {
- that.$element.appendTo(document.body) //don't move modals dom position
- }
-
- that.$element
- .show()
-
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
-
- that.$element.addClass('in')
-
- transition ?
- that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
- that.$element.trigger('shown')
-
- })
- }
-
- , hide: function (e) {
- e && e.preventDefault()
-
- var that = this
-
- e = $.Event('hide')
-
- this.$element.trigger(e)
-
- if (!this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = false
-
- $('body').removeClass('modal-open')
-
- escape.call(this)
-
- this.$element.removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade') ?
- hideWithTransition.call(this) :
- hideModal.call(this)
- }
-
- }
-
-
- /* MODAL PRIVATE METHODS
- * ===================== */
-
- function hideWithTransition() {
- var that = this
- , timeout = setTimeout(function () {
- that.$element.off($.support.transition.end)
- hideModal.call(that)
- }, 500)
-
- this.$element.one($.support.transition.end, function () {
- clearTimeout(timeout)
- hideModal.call(that)
- })
- }
-
- function hideModal(that) {
- this.$element
- .hide()
- .trigger('hidden')
-
- backdrop.call(this)
- }
-
- function backdrop(callback) {
- var that = this
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
-
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
-
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(document.body)
-
- if (this.options.backdrop != 'static') {
- this.$backdrop.click($.proxy(this.hide, this))
- }
-
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
- this.$backdrop.addClass('in')
-
- doAnimate ?
- this.$backdrop.one($.support.transition.end, callback) :
- callback()
-
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade')?
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
- removeBackdrop.call(this)
-
- } else if (callback) {
- callback()
- }
- }
-
- function removeBackdrop() {
- this.$backdrop.remove()
- this.$backdrop = null
- }
-
- function escape() {
- var that = this
- if (this.isShown && this.options.keyboard) {
- $(document).on('keyup.dismiss.modal', function ( e ) {
- e.which == 27 && that.hide()
- })
- } else if (!this.isShown) {
- $(document).off('keyup.dismiss.modal')
- }
- }
-
-
- /* MODAL PLUGIN DEFINITION
- * ======================= */
-
- $.fn.modal = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('modal')
- , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
- if (!data) $this.data('modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option]()
- else if (options.show) data.show()
- })
- }
-
- $.fn.modal.defaults = {
- backdrop: true
- , keyboard: true
- , show: true
- }
-
- $.fn.modal.Constructor = Modal
-
-
- /* MODAL DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
-
- e.preventDefault()
- $target.modal(option)
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-popover.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-popover.js b/src/webui/master/static/bootstrap/js/bootstrap-popover.js
deleted file mode 100644
index d5ecfa9..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-popover.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ===========================================================
- * bootstrap-popover.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#popovers
- * ===========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * =========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* POPOVER PUBLIC CLASS DEFINITION
- * =============================== */
-
- var Popover = function ( element, options ) {
- this.init('popover', element, options)
- }
-
-
- /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
- ========================================== */
-
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
-
- constructor: Popover
-
- , setContent: function () {
- var $tip = this.tip()
- , title = this.getTitle()
- , content = this.getContent()
-
- $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
- $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
-
- $tip.removeClass('fade top bottom left right in')
- }
-
- , hasContent: function () {
- return this.getTitle() || this.getContent()
- }
-
- , getContent: function () {
- var content
- , $e = this.$element
- , o = this.options
-
- content = $e.attr('data-content')
- || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
-
- return content
- }
-
- , tip: function () {
- if (!this.$tip) {
- this.$tip = $(this.options.template)
- }
- return this.$tip
- }
-
- })
-
-
- /* POPOVER PLUGIN DEFINITION
- * ======================= */
-
- $.fn.popover = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('popover')
- , options = typeof option == 'object' && option
- if (!data) $this.data('popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.popover.Constructor = Popover
-
- $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
- placement: 'right'
- , content: ''
- , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-scrollspy.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-scrollspy.js b/src/webui/master/static/bootstrap/js/bootstrap-scrollspy.js
deleted file mode 100644
index 4946ee9..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-scrollspy.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/* =============================================================
- * bootstrap-scrollspy.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#scrollspy
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* SCROLLSPY CLASS DEFINITION
- * ========================== */
-
- function ScrollSpy( element, options) {
- var process = $.proxy(this.process, this)
- , $element = $(element).is('body') ? $(window) : $(element)
- , href
- this.options = $.extend({}, $.fn.scrollspy.defaults, options)
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
- this.selector = (this.options.target
- || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- || '') + ' .nav li > a'
- this.$body = $('body')
- this.refresh()
- this.process()
- }
-
- ScrollSpy.prototype = {
-
- constructor: ScrollSpy
-
- , refresh: function () {
- var self = this
- , $targets
-
- this.offsets = $([])
- this.targets = $([])
-
- $targets = this.$body
- .find(this.selector)
- .map(function () {
- var $el = $(this)
- , href = $el.data('target') || $el.attr('href')
- , $href = /^#\w/.test(href) && $(href)
- return ( $href
- && href.length
- && [[ $href.position().top, href ]] ) || null
- })
- .sort(function (a, b) { return a[0] - b[0] })
- .each(function () {
- self.offsets.push(this[0])
- self.targets.push(this[1])
- })
- }
-
- , process: function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
- , maxScroll = scrollHeight - this.$scrollElement.height()
- , offsets = this.offsets
- , targets = this.targets
- , activeTarget = this.activeTarget
- , i
-
- if (scrollTop >= maxScroll) {
- return activeTarget != (i = targets.last()[0])
- && this.activate ( i )
- }
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
- && this.activate( targets[i] )
- }
- }
-
- , activate: function (target) {
- var active
- , selector
-
- this.activeTarget = target
-
- $(this.selector)
- .parent('.active')
- .removeClass('active')
-
- selector = this.selector
- + '[data-target="' + target + '"],'
- + this.selector + '[href="' + target + '"]'
-
- active = $(selector)
- .parent('li')
- .addClass('active')
-
- if (active.parent('.dropdown-menu')) {
- active = active.closest('li.dropdown').addClass('active')
- }
-
- active.trigger('activate')
- }
-
- }
-
-
- /* SCROLLSPY PLUGIN DEFINITION
- * =========================== */
-
- $.fn.scrollspy = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('scrollspy')
- , options = typeof option == 'object' && option
- if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.scrollspy.Constructor = ScrollSpy
-
- $.fn.scrollspy.defaults = {
- offset: 10
- }
-
-
- /* SCROLLSPY DATA-API
- * ================== */
-
- $(function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- $spy.scrollspy($spy.data())
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-tab.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-tab.js b/src/webui/master/static/bootstrap/js/bootstrap-tab.js
deleted file mode 100644
index 88641de..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-tab.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ========================================================
- * bootstrap-tab.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#tabs
- * ========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ======================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* TAB CLASS DEFINITION
- * ==================== */
-
- var Tab = function ( element ) {
- this.element = $(element)
- }
-
- Tab.prototype = {
-
- constructor: Tab
-
- , show: function () {
- var $this = this.element
- , $ul = $this.closest('ul:not(.dropdown-menu)')
- , selector = $this.attr('data-target')
- , previous
- , $target
- , e
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- if ( $this.parent('li').hasClass('active') ) return
-
- previous = $ul.find('.active a').last()[0]
-
- e = $.Event('show', {
- relatedTarget: previous
- })
-
- $this.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- $target = $(selector)
-
- this.activate($this.parent('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $this.trigger({
- type: 'shown'
- , relatedTarget: previous
- })
- })
- }
-
- , activate: function ( element, container, callback) {
- var $active = container.find('> .active')
- , transition = callback
- && $.support.transition
- && $active.hasClass('fade')
-
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
-
- element.addClass('active')
-
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
-
- if ( element.parent('.dropdown-menu') ) {
- element.closest('li.dropdown').addClass('active')
- }
-
- callback && callback()
- }
-
- transition ?
- $active.one($.support.transition.end, next) :
- next()
-
- $active.removeClass('in')
- }
- }
-
-
- /* TAB PLUGIN DEFINITION
- * ===================== */
-
- $.fn.tab = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tab')
- if (!data) $this.data('tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tab.Constructor = Tab
-
-
- /* TAB DATA-API
- * ============ */
-
- $(function () {
- $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
- e.preventDefault()
- $(this).tab('show')
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-tooltip.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-tooltip.js b/src/webui/master/static/bootstrap/js/bootstrap-tooltip.js
deleted file mode 100644
index 577ead4..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-tooltip.js
+++ /dev/null
@@ -1,275 +0,0 @@
-/* ===========================================================
- * bootstrap-tooltip.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#tooltips
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ===========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* TOOLTIP PUBLIC CLASS DEFINITION
- * =============================== */
-
- var Tooltip = function (element, options) {
- this.init('tooltip', element, options)
- }
-
- Tooltip.prototype = {
-
- constructor: Tooltip
-
- , init: function (type, element, options) {
- var eventIn
- , eventOut
-
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.enabled = true
-
- if (this.options.trigger != 'manual') {
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
- eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
- }
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
- }
-
- , getOptions: function (options) {
- options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
-
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay
- , hide: options.delay
- }
- }
-
- return options
- }
-
- , enter: function (e) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.show) return self.show()
-
- clearTimeout(this.timeout)
- self.hoverState = 'in'
- this.timeout = setTimeout(function() {
- if (self.hoverState == 'in') self.show()
- }, self.options.delay.show)
- }
-
- , leave: function (e) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
- clearTimeout(this.timeout)
- self.hoverState = 'out'
- this.timeout = setTimeout(function() {
- if (self.hoverState == 'out') self.hide()
- }, self.options.delay.hide)
- }
-
- , show: function () {
- var $tip
- , inside
- , pos
- , actualWidth
- , actualHeight
- , placement
- , tp
-
- if (this.hasContent() && this.enabled) {
- $tip = this.tip()
- this.setContent()
-
- if (this.options.animation) {
- $tip.addClass('fade')
- }
-
- placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
-
- inside = /in/.test(placement)
-
- $tip
- .remove()
- .css({ top: 0, left: 0, display: 'block' })
- .appendTo(inside ? this.$element : document.body)
-
- pos = this.getPosition(inside)
-
- actualWidth = $tip[0].offsetWidth
- actualHeight = $tip[0].offsetHeight
-
- switch (inside ? placement.split(' ')[1] : placement) {
- case 'bottom':
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'top':
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'left':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
- break
- case 'right':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
- break
- }
-
- $tip
- .css(tp)
- .addClass(placement)
- .addClass('in')
- }
- }
-
- , isHTML: function(text) {
- // html string detection logic adapted from jQuery
- return typeof text != 'string'
- || ( text.charAt(0) === "<"
- && text.charAt( text.length - 1 ) === ">"
- && text.length >= 3
- ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text)
- }
-
- , setContent: function () {
- var $tip = this.tip()
- , title = this.getTitle()
-
- $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title)
- $tip.removeClass('fade in top bottom left right')
- }
-
- , hide: function () {
- var that = this
- , $tip = this.tip()
-
- $tip.removeClass('in')
-
- function removeWithAnimation() {
- var timeout = setTimeout(function () {
- $tip.off($.support.transition.end).remove()
- }, 500)
-
- $tip.one($.support.transition.end, function () {
- clearTimeout(timeout)
- $tip.remove()
- })
- }
-
- $.support.transition && this.$tip.hasClass('fade') ?
- removeWithAnimation() :
- $tip.remove()
- }
-
- , fixTitle: function () {
- var $e = this.$element
- if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
- }
- }
-
- , hasContent: function () {
- return this.getTitle()
- }
-
- , getPosition: function (inside) {
- return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
- width: this.$element[0].offsetWidth
- , height: this.$element[0].offsetHeight
- })
- }
-
- , getTitle: function () {
- var title
- , $e = this.$element
- , o = this.options
-
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
-
- return title
- }
-
- , tip: function () {
- return this.$tip = this.$tip || $(this.options.template)
- }
-
- , validate: function () {
- if (!this.$element[0].parentNode) {
- this.hide()
- this.$element = null
- this.options = null
- }
- }
-
- , enable: function () {
- this.enabled = true
- }
-
- , disable: function () {
- this.enabled = false
- }
-
- , toggleEnabled: function () {
- this.enabled = !this.enabled
- }
-
- , toggle: function () {
- this[this.tip().hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
-
- /* TOOLTIP PLUGIN DEFINITION
- * ========================= */
-
- $.fn.tooltip = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tooltip')
- , options = typeof option == 'object' && option
- if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tooltip.Constructor = Tooltip
-
- $.fn.tooltip.defaults = {
- animation: true
- , placement: 'top'
- , selector: false
- , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
- , trigger: 'hover'
- , title: ''
- , delay: 0
- }
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-transition.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-transition.js b/src/webui/master/static/bootstrap/js/bootstrap-transition.js
deleted file mode 100644
index 7e29b2f..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-transition.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ===================================================
- * bootstrap-transition.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#transitions
- * ===================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- $(function () {
-
- "use strict"; // jshint ;_;
-
-
- /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
- * ======================================================= */
-
- $.support.transition = (function () {
-
- var transitionEnd = (function () {
-
- var el = document.createElement('bootstrap')
- , transEndEventNames = {
- 'WebkitTransition' : 'webkitTransitionEnd'
- , 'MozTransition' : 'transitionend'
- , 'OTransition' : 'oTransitionEnd'
- , 'msTransition' : 'MSTransitionEnd'
- , 'transition' : 'transitionend'
- }
- , name
-
- for (name in transEndEventNames){
- if (el.style[name] !== undefined) {
- return transEndEventNames[name]
- }
- }
-
- }())
-
- return transitionEnd && {
- end: transitionEnd
- }
-
- })()
-
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap-typeahead.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap-typeahead.js b/src/webui/master/static/bootstrap/js/bootstrap-typeahead.js
deleted file mode 100644
index 95a0fcd..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap-typeahead.js
+++ /dev/null
@@ -1,285 +0,0 @@
-/* =============================================================
- * bootstrap-typeahead.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#typeahead
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function($){
-
- "use strict"; // jshint ;_;
-
-
- /* TYPEAHEAD PUBLIC CLASS DEFINITION
- * ================================= */
-
- var Typeahead = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.typeahead.defaults, options)
- this.matcher = this.options.matcher || this.matcher
- this.sorter = this.options.sorter || this.sorter
- this.highlighter = this.options.highlighter || this.highlighter
- this.updater = this.options.updater || this.updater
- this.$menu = $(this.options.menu).appendTo('body')
- this.source = this.options.source
- this.shown = false
- this.listen()
- }
-
- Typeahead.prototype = {
-
- constructor: Typeahead
-
- , select: function () {
- var val = this.$menu.find('.active').attr('data-value')
- this.$element
- .val(this.updater(val))
- .change()
- return this.hide()
- }
-
- , updater: function (item) {
- return item
- }
-
- , show: function () {
- var pos = $.extend({}, this.$element.offset(), {
- height: this.$element[0].offsetHeight
- })
-
- this.$menu.css({
- top: pos.top + pos.height
- , left: pos.left
- })
-
- this.$menu.show()
- this.shown = true
- return this
- }
-
- , hide: function () {
- this.$menu.hide()
- this.shown = false
- return this
- }
-
- , lookup: function (event) {
- var that = this
- , items
- , q
-
- this.query = this.$element.val()
-
- if (!this.query) {
- return this.shown ? this.hide() : this
- }
-
- items = $.grep(this.source, function (item) {
- return that.matcher(item)
- })
-
- items = this.sorter(items)
-
- if (!items.length) {
- return this.shown ? this.hide() : this
- }
-
- return this.render(items.slice(0, this.options.items)).show()
- }
-
- , matcher: function (item) {
- return ~item.toLowerCase().indexOf(this.query.toLowerCase())
- }
-
- , sorter: function (items) {
- var beginswith = []
- , caseSensitive = []
- , caseInsensitive = []
- , item
-
- while (item = items.shift()) {
- if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
- else if (~item.indexOf(this.query)) caseSensitive.push(item)
- else caseInsensitive.push(item)
- }
-
- return beginswith.concat(caseSensitive, caseInsensitive)
- }
-
- , highlighter: function (item) {
- var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
- return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
- return '<strong>' + match + '</strong>'
- })
- }
-
- , render: function (items) {
- var that = this
-
- items = $(items).map(function (i, item) {
- i = $(that.options.item).attr('data-value', item)
- i.find('a').html(that.highlighter(item))
- return i[0]
- })
-
- items.first().addClass('active')
- this.$menu.html(items)
- return this
- }
-
- , next: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , next = active.next()
-
- if (!next.length) {
- next = $(this.$menu.find('li')[0])
- }
-
- next.addClass('active')
- }
-
- , prev: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , prev = active.prev()
-
- if (!prev.length) {
- prev = this.$menu.find('li').last()
- }
-
- prev.addClass('active')
- }
-
- , listen: function () {
- this.$element
- .on('blur', $.proxy(this.blur, this))
- .on('keypress', $.proxy(this.keypress, this))
- .on('keyup', $.proxy(this.keyup, this))
-
- if ($.browser.webkit || $.browser.msie) {
- this.$element.on('keydown', $.proxy(this.keypress, this))
- }
-
- this.$menu
- .on('click', $.proxy(this.click, this))
- .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
- }
-
- , keyup: function (e) {
- switch(e.keyCode) {
- case 40: // down arrow
- case 38: // up arrow
- break
-
- case 9: // tab
- case 13: // enter
- if (!this.shown) return
- this.select()
- break
-
- case 27: // escape
- if (!this.shown) return
- this.hide()
- break
-
- default:
- this.lookup()
- }
-
- e.stopPropagation()
- e.preventDefault()
- }
-
- , keypress: function (e) {
- if (!this.shown) return
-
- switch(e.keyCode) {
- case 9: // tab
- case 13: // enter
- case 27: // escape
- e.preventDefault()
- break
-
- case 38: // up arrow
- if (e.type != 'keydown') break
- e.preventDefault()
- this.prev()
- break
-
- case 40: // down arrow
- if (e.type != 'keydown') break
- e.preventDefault()
- this.next()
- break
- }
-
- e.stopPropagation()
- }
-
- , blur: function (e) {
- var that = this
- setTimeout(function () { that.hide() }, 150)
- }
-
- , click: function (e) {
- e.stopPropagation()
- e.preventDefault()
- this.select()
- }
-
- , mouseenter: function (e) {
- this.$menu.find('.active').removeClass('active')
- $(e.currentTarget).addClass('active')
- }
-
- }
-
-
- /* TYPEAHEAD PLUGIN DEFINITION
- * =========================== */
-
- $.fn.typeahead = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('typeahead')
- , options = typeof option == 'object' && option
- if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.typeahead.defaults = {
- source: []
- , items: 8
- , menu: '<ul class="typeahead dropdown-menu"></ul>'
- , item: '<li><a href="#"></a></li>'
- }
-
- $.fn.typeahead.Constructor = Typeahead
-
-
- /* TYPEAHEAD DATA-API
- * ================== */
-
- $(function () {
- $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
- var $this = $(this)
- if ($this.data('typeahead')) return
- e.preventDefault()
- $this.typeahead($this.data())
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
[5/7] Replaced bootstrap.js with angular-ui.js
Posted by bm...@apache.org.
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/index.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/index.html b/src/webui/master/static/index.html
index 0ea3094..0a9c52f 100644
--- a/src/webui/master/static/index.html
+++ b/src/webui/master/static/index.html
@@ -64,28 +64,25 @@
<div ng-view></div>
</div>
- <div class="modal hide fade" style="display: none;" id="error-modal">
+ <div modal="errorModalOpen" style="display:none;">
<div class="modal-header">
- <button class="close" data-dismiss="modal">×</button>
<h3>Failed to connect to {{$location.host()}}:{{$location.port()}}!</h3>
</div>
<div class="modal-body">
<p>
- Retrying in <b>{{retry / 1000}}</b> seconds ...
- <a href="{{$location.path()}}" data-dismiss="modal">try now</a>.
+ Retrying in <b>{{retry / 1000}}</b> seconds...
</p>
</div>
<div class="modal-footer">
+ <button class="btn" ng-click="errorModalClose()">Try now</button>
</div>
</div>
-
</div>
<script src="/static/bootstrap/js/jquery-1.7.1.min.js"></script>
- <script src="/static/bootstrap/js/bootstrap.min.js"></script>
-
<script src="/static/underscore-1.4.3.min.js"></script>
<script src="/static/angular-1.0.7.min.js"></script>
+ <script src="/static/ui-bootstrap-tpls-0.4.0.min.js"></script>
<script src="/static/d3.v2.min.js"></script>
<script src="/static/cubism.v1.min.js"></script>
@@ -94,6 +91,5 @@
<script src="/static/app.js"></script>
<script src="/static/controllers.js"></script>
<script src="/static/dashboard.js"></script>
- <script src="/static/popovers.js"></script>
</body>
</html>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/popovers.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/popovers.js b/src/webui/master/static/popovers.js
deleted file mode 100644
index 28666dd..0000000
--- a/src/webui/master/static/popovers.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// An abstraction for handling popovers.
-var Popovers = {
- exist: false, // Indicates whether a popover is currently open or not.
-
- initialize: function() {
- // Turn off popovers if one is shown and we click on something
- // else (other than some part of the popover itself).
- $(document).click(function(event) {
- var target = $(event.target);
-
- if (target.parent().is('.popover-content') ||
- target.parent().is('.popover-inner') ||
- target.parent().is('.popover')) {
- return;
- }
-
- if (Popovers.exist && event.target.rel != 'popover') {
- Popovers.hide();
- }
- });
- },
-
- show: function(event, placement) {
- Popovers.hide(); // Hide any popovers if some are currently shown.
-
- var target = $(event.target);
- target.popover({
- html: true,
- placement: placement,
- trigger: 'manual'
- });
-
- target.popover('show');
- Popovers.exist = true;
- // TODO(benh): event.preventDefault();
- },
-
- hide: function() {
- // We can't just keep a reference to the element that triggered
- // the popover because the DOM might have changed (e.g., if using
- // something like AngularJS) and so the best we can do is just
- // remove (i.e., hide) all "popovers".
- $('.popover').each(function() {
- $(this).remove();
- });
- Popovers.exist = false;
- }
-}
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/slave.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slave.html b/src/webui/master/static/slave.html
index 378079c..a80b837 100644
--- a/src/webui/master/static/slave.html
+++ b/src/webui/master/static/slave.html
@@ -14,18 +14,6 @@
<strong>{{alert_message}}</strong>
</div>
-<div class="modal hide fade" style="display: none;" id="no-log-dir-modal">
- <div class="modal-header">
- <button class="close" data-dismiss="modal">x</button>
- <h3>Logging to a file is not enabled!</h3>
- </div>
- <div class="modal-body">
- <p>Set the 'log_dir' option if you wish to access the logs.</p>
- </div>
- <div class="modal-footer">
- </div>
-</div>
-
<div class="row hide" id="slave">
<div class="span3">
<div class="well">
@@ -36,13 +24,19 @@
<dd>{{state.master_hostname}}</dd>
<dt>Started:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{state.start_time * 1000 | mesosDate}}" data-original-title="Started">
+ <a href="javascript:void(0)"
+ popover="{{state.start_time * 1000 | mesosDate}}"
+ popover-placement="right"
+ popover-title="Started">
{{state.start_time * 1000 | relativeDate}}
</a>
</dd>
<dt>Built:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{state.build_time * 1000 | mesosDate}}" data-original-title="Built">
+ <a href="javascript:void(0)"
+ popover="{{state.build_time * 1000 | mesosDate}}"
+ popover-placement="right"
+ popover-title="Built">
{{state.build_time * 1000 | relativeDate}}
</a> by <i>{{state.build_user}}</i>
</dd>
@@ -137,7 +131,10 @@
<tbody>
<tr ng-repeat="framework in _.values(slave.frameworks) | orderBy:tables['frameworks'].selected_column:tables['frameworks'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{framework.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{framework.id | truncateMesosID}}
</a>
</td>
@@ -187,7 +184,10 @@
<tbody>
<tr ng-repeat="completed_framework in _.values(slave.completed_frameworks) | orderBy:tables['completed_frameworks'].selected_column:tables['completed_frameworks'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{completed_framework.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{completed_framework.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{completed_framework.id | truncateMesosID}}
</a>
</td>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/slaves.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/slaves.html b/src/webui/master/static/slaves.html
index 64baba9..d9fd0f3 100644
--- a/src/webui/master/static/slaves.html
+++ b/src/webui/master/static/slaves.html
@@ -40,7 +40,10 @@
</thead>
<tr ng-repeat="slave in _.values(slaves) | orderBy:tables['slaves'].selected_column:tables['slaves'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{slave.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{slave.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{slave.id | truncateMesosID}}
</a>
</td>
@@ -49,7 +52,10 @@
<td>{{slave.resources.mem * (1024 * 1024) | dataSize}}</td>
<td>{{slave.resources.disk * (1024 * 1024) | dataSize}}</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{slave.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{slave.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{slave.registered_time * 1000 | relativeDate}}
</a>
</td>
[6/7] Replaced bootstrap.js with angular-ui.js
Posted by bm...@apache.org.
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap.js b/src/webui/master/static/bootstrap/js/bootstrap.js
deleted file mode 100644
index 7244954..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap.js
+++ /dev/null
@@ -1,1824 +0,0 @@
-/* ===================================================
- * bootstrap-transition.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#transitions
- * ===================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- $(function () {
-
- "use strict"; // jshint ;_;
-
-
- /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
- * ======================================================= */
-
- $.support.transition = (function () {
-
- var transitionEnd = (function () {
-
- var el = document.createElement('bootstrap')
- , transEndEventNames = {
- 'WebkitTransition' : 'webkitTransitionEnd'
- , 'MozTransition' : 'transitionend'
- , 'OTransition' : 'oTransitionEnd'
- , 'msTransition' : 'MSTransitionEnd'
- , 'transition' : 'transitionend'
- }
- , name
-
- for (name in transEndEventNames){
- if (el.style[name] !== undefined) {
- return transEndEventNames[name]
- }
- }
-
- }())
-
- return transitionEnd && {
- end: transitionEnd
- }
-
- })()
-
- })
-
-}(window.jQuery);/* ==========================================================
- * bootstrap-alert.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#alerts
- * ==========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* ALERT CLASS DEFINITION
- * ====================== */
-
- var dismiss = '[data-dismiss="alert"]'
- , Alert = function (el) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.prototype.close = function (e) {
- var $this = $(this)
- , selector = $this.attr('data-target')
- , $parent
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
-
- e && e.preventDefault()
-
- $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
-
- $parent.trigger(e = $.Event('close'))
-
- if (e.isDefaultPrevented()) return
-
- $parent.removeClass('in')
-
- function removeElement() {
- $parent
- .trigger('closed')
- .remove()
- }
-
- $.support.transition && $parent.hasClass('fade') ?
- $parent.on($.support.transition.end, removeElement) :
- removeElement()
- }
-
-
- /* ALERT PLUGIN DEFINITION
- * ======================= */
-
- $.fn.alert = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('alert')
- if (!data) $this.data('alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.alert.Constructor = Alert
-
-
- /* ALERT DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
- })
-
-}(window.jQuery);/* ============================================================
- * bootstrap-button.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#buttons
- * ============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* BUTTON PUBLIC CLASS DEFINITION
- * ============================== */
-
- var Button = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.button.defaults, options)
- }
-
- Button.prototype.setState = function (state) {
- var d = 'disabled'
- , $el = this.$element
- , data = $el.data()
- , val = $el.is('input') ? 'val' : 'html'
-
- state = state + 'Text'
- data.resetText || $el.data('resetText', $el[val]())
-
- $el[val](data[state] || this.options[state])
-
- // push to event loop to allow forms to submit
- setTimeout(function () {
- state == 'loadingText' ?
- $el.addClass(d).attr(d, d) :
- $el.removeClass(d).removeAttr(d)
- }, 0)
- }
-
- Button.prototype.toggle = function () {
- var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
-
- $parent && $parent
- .find('.active')
- .removeClass('active')
-
- this.$element.toggleClass('active')
- }
-
-
- /* BUTTON PLUGIN DEFINITION
- * ======================== */
-
- $.fn.button = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('button')
- , options = typeof option == 'object' && option
- if (!data) $this.data('button', (data = new Button(this, options)))
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
-
- $.fn.button.defaults = {
- loadingText: 'loading...'
- }
-
- $.fn.button.Constructor = Button
-
-
- /* BUTTON DATA-API
- * =============== */
-
- $(function () {
- $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
- var $btn = $(e.target)
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
- $btn.button('toggle')
- })
- })
-
-}(window.jQuery);/* ==========================================================
- * bootstrap-carousel.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#carousel
- * ==========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* CAROUSEL CLASS DEFINITION
- * ========================= */
-
- var Carousel = function (element, options) {
- this.$element = $(element)
- this.options = options
- this.options.slide && this.slide(this.options.slide)
- this.options.pause == 'hover' && this.$element
- .on('mouseenter', $.proxy(this.pause, this))
- .on('mouseleave', $.proxy(this.cycle, this))
- }
-
- Carousel.prototype = {
-
- cycle: function (e) {
- if (!e) this.paused = false
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
- return this
- }
-
- , to: function (pos) {
- var $active = this.$element.find('.active')
- , children = $active.parent().children()
- , activePos = children.index($active)
- , that = this
-
- if (pos > (children.length - 1) || pos < 0) return
-
- if (this.sliding) {
- return this.$element.one('slid', function () {
- that.to(pos)
- })
- }
-
- if (activePos == pos) {
- return this.pause().cycle()
- }
-
- return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
- }
-
- , pause: function (e) {
- if (!e) this.paused = true
- clearInterval(this.interval)
- this.interval = null
- return this
- }
-
- , next: function () {
- if (this.sliding) return
- return this.slide('next')
- }
-
- , prev: function () {
- if (this.sliding) return
- return this.slide('prev')
- }
-
- , slide: function (type, next) {
- var $active = this.$element.find('.active')
- , $next = next || $active[type]()
- , isCycling = this.interval
- , direction = type == 'next' ? 'left' : 'right'
- , fallback = type == 'next' ? 'first' : 'last'
- , that = this
- , e = $.Event('slide')
-
- this.sliding = true
-
- isCycling && this.pause()
-
- $next = $next.length ? $next : this.$element.find('.item')[fallback]()
-
- if ($next.hasClass('active')) return
-
- if ($.support.transition && this.$element.hasClass('slide')) {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- this.$element.one($.support.transition.end, function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () { that.$element.trigger('slid') }, 0)
- })
- } else {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger('slid')
- }
-
- isCycling && this.cycle()
-
- return this
- }
-
- }
-
-
- /* CAROUSEL PLUGIN DEFINITION
- * ========================== */
-
- $.fn.carousel = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('carousel')
- , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
- if (!data) $this.data('carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (typeof option == 'string' || (option = options.slide)) data[option]()
- else if (options.interval) data.cycle()
- })
- }
-
- $.fn.carousel.defaults = {
- interval: 5000
- , pause: 'hover'
- }
-
- $.fn.carousel.Constructor = Carousel
-
-
- /* CAROUSEL DATA-API
- * ================= */
-
- $(function () {
- $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
- $target.carousel(options)
- e.preventDefault()
- })
- })
-
-}(window.jQuery);/* =============================================================
- * bootstrap-collapse.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#collapse
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* COLLAPSE PUBLIC CLASS DEFINITION
- * ================================ */
-
- var Collapse = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.collapse.defaults, options)
-
- if (this.options.parent) {
- this.$parent = $(this.options.parent)
- }
-
- this.options.toggle && this.toggle()
- }
-
- Collapse.prototype = {
-
- constructor: Collapse
-
- , dimension: function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
-
- , show: function () {
- var dimension
- , scroll
- , actives
- , hasData
-
- if (this.transitioning) return
-
- dimension = this.dimension()
- scroll = $.camelCase(['scroll', dimension].join('-'))
- actives = this.$parent && this.$parent.find('> .accordion-group > .in')
-
- if (actives && actives.length) {
- hasData = actives.data('collapse')
- if (hasData && hasData.transitioning) return
- actives.collapse('hide')
- hasData || actives.data('collapse', null)
- }
-
- this.$element[dimension](0)
- this.transition('addClass', $.Event('show'), 'shown')
- this.$element[dimension](this.$element[0][scroll])
- }
-
- , hide: function () {
- var dimension
- if (this.transitioning) return
- dimension = this.dimension()
- this.reset(this.$element[dimension]())
- this.transition('removeClass', $.Event('hide'), 'hidden')
- this.$element[dimension](0)
- }
-
- , reset: function (size) {
- var dimension = this.dimension()
-
- this.$element
- .removeClass('collapse')
- [dimension](size || 'auto')
- [0].offsetWidth
-
- this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
-
- return this
- }
-
- , transition: function (method, startEvent, completeEvent) {
- var that = this
- , complete = function () {
- if (startEvent.type == 'show') that.reset()
- that.transitioning = 0
- that.$element.trigger(completeEvent)
- }
-
- this.$element.trigger(startEvent)
-
- if (startEvent.isDefaultPrevented()) return
-
- this.transitioning = 1
-
- this.$element[method]('in')
-
- $.support.transition && this.$element.hasClass('collapse') ?
- this.$element.one($.support.transition.end, complete) :
- complete()
- }
-
- , toggle: function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
-
- /* COLLAPSIBLE PLUGIN DEFINITION
- * ============================== */
-
- $.fn.collapse = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('collapse')
- , options = typeof option == 'object' && option
- if (!data) $this.data('collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.collapse.defaults = {
- toggle: true
- }
-
- $.fn.collapse.Constructor = Collapse
-
-
- /* COLLAPSIBLE DATA-API
- * ==================== */
-
- $(function () {
- $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
- var $this = $(this), href
- , target = $this.attr('data-target')
- || e.preventDefault()
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
- , option = $(target).data('collapse') ? 'toggle' : $this.data()
- $(target).collapse(option)
- })
- })
-
-}(window.jQuery);/* ============================================================
- * bootstrap-dropdown.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#dropdowns
- * ============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* DROPDOWN CLASS DEFINITION
- * ========================= */
-
- var toggle = '[data-toggle="dropdown"]'
- , Dropdown = function (element) {
- var $el = $(element).on('click.dropdown.data-api', this.toggle)
- $('html').on('click.dropdown.data-api', function () {
- $el.parent().removeClass('open')
- })
- }
-
- Dropdown.prototype = {
-
- constructor: Dropdown
-
- , toggle: function (e) {
- var $this = $(this)
- , $parent
- , selector
- , isActive
-
- if ($this.is('.disabled, :disabled')) return
-
- selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
- $parent.length || ($parent = $this.parent())
-
- isActive = $parent.hasClass('open')
-
- clearMenus()
-
- if (!isActive) $parent.toggleClass('open')
-
- return false
- }
-
- }
-
- function clearMenus() {
- $(toggle).parent().removeClass('open')
- }
-
-
- /* DROPDOWN PLUGIN DEFINITION
- * ========================== */
-
- $.fn.dropdown = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('dropdown')
- if (!data) $this.data('dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.dropdown.Constructor = Dropdown
-
-
- /* APPLY TO STANDARD DROPDOWN ELEMENTS
- * =================================== */
-
- $(function () {
- $('html').on('click.dropdown.data-api', clearMenus)
- $('body')
- .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() })
- .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- })
-
-}(window.jQuery);/* =========================================================
- * bootstrap-modal.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#modals
- * =========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================= */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* MODAL CLASS DEFINITION
- * ====================== */
-
- var Modal = function (content, options) {
- this.options = options
- this.$element = $(content)
- .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
- }
-
- Modal.prototype = {
-
- constructor: Modal
-
- , toggle: function () {
- return this[!this.isShown ? 'show' : 'hide']()
- }
-
- , show: function () {
- var that = this
- , e = $.Event('show')
-
- this.$element.trigger(e)
-
- if (this.isShown || e.isDefaultPrevented()) return
-
- $('body').addClass('modal-open')
-
- this.isShown = true
-
- escape.call(this)
- backdrop.call(this, function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
-
- if (!that.$element.parent().length) {
- that.$element.appendTo(document.body) //don't move modals dom position
- }
-
- that.$element
- .show()
-
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
-
- that.$element.addClass('in')
-
- transition ?
- that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
- that.$element.trigger('shown')
-
- })
- }
-
- , hide: function (e) {
- e && e.preventDefault()
-
- var that = this
-
- e = $.Event('hide')
-
- this.$element.trigger(e)
-
- if (!this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = false
-
- $('body').removeClass('modal-open')
-
- escape.call(this)
-
- this.$element.removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade') ?
- hideWithTransition.call(this) :
- hideModal.call(this)
- }
-
- }
-
-
- /* MODAL PRIVATE METHODS
- * ===================== */
-
- function hideWithTransition() {
- var that = this
- , timeout = setTimeout(function () {
- that.$element.off($.support.transition.end)
- hideModal.call(that)
- }, 500)
-
- this.$element.one($.support.transition.end, function () {
- clearTimeout(timeout)
- hideModal.call(that)
- })
- }
-
- function hideModal(that) {
- this.$element
- .hide()
- .trigger('hidden')
-
- backdrop.call(this)
- }
-
- function backdrop(callback) {
- var that = this
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
-
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
-
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(document.body)
-
- if (this.options.backdrop != 'static') {
- this.$backdrop.click($.proxy(this.hide, this))
- }
-
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
- this.$backdrop.addClass('in')
-
- doAnimate ?
- this.$backdrop.one($.support.transition.end, callback) :
- callback()
-
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade')?
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
- removeBackdrop.call(this)
-
- } else if (callback) {
- callback()
- }
- }
-
- function removeBackdrop() {
- this.$backdrop.remove()
- this.$backdrop = null
- }
-
- function escape() {
- var that = this
- if (this.isShown && this.options.keyboard) {
- $(document).on('keyup.dismiss.modal', function ( e ) {
- e.which == 27 && that.hide()
- })
- } else if (!this.isShown) {
- $(document).off('keyup.dismiss.modal')
- }
- }
-
-
- /* MODAL PLUGIN DEFINITION
- * ======================= */
-
- $.fn.modal = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('modal')
- , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
- if (!data) $this.data('modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option]()
- else if (options.show) data.show()
- })
- }
-
- $.fn.modal.defaults = {
- backdrop: true
- , keyboard: true
- , show: true
- }
-
- $.fn.modal.Constructor = Modal
-
-
- /* MODAL DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
-
- e.preventDefault()
- $target.modal(option)
- })
- })
-
-}(window.jQuery);/* ===========================================================
- * bootstrap-tooltip.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#tooltips
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ===========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* TOOLTIP PUBLIC CLASS DEFINITION
- * =============================== */
-
- var Tooltip = function (element, options) {
- this.init('tooltip', element, options)
- }
-
- Tooltip.prototype = {
-
- constructor: Tooltip
-
- , init: function (type, element, options) {
- var eventIn
- , eventOut
-
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.enabled = true
-
- if (this.options.trigger != 'manual') {
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
- eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
- }
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
- }
-
- , getOptions: function (options) {
- options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
-
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay
- , hide: options.delay
- }
- }
-
- return options
- }
-
- , enter: function (e) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.show) return self.show()
-
- clearTimeout(this.timeout)
- self.hoverState = 'in'
- this.timeout = setTimeout(function() {
- if (self.hoverState == 'in') self.show()
- }, self.options.delay.show)
- }
-
- , leave: function (e) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
- clearTimeout(this.timeout)
- self.hoverState = 'out'
- this.timeout = setTimeout(function() {
- if (self.hoverState == 'out') self.hide()
- }, self.options.delay.hide)
- }
-
- , show: function () {
- var $tip
- , inside
- , pos
- , actualWidth
- , actualHeight
- , placement
- , tp
-
- if (this.hasContent() && this.enabled) {
- $tip = this.tip()
- this.setContent()
-
- if (this.options.animation) {
- $tip.addClass('fade')
- }
-
- placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
-
- inside = /in/.test(placement)
-
- $tip
- .remove()
- .css({ top: 0, left: 0, display: 'block' })
- .appendTo(inside ? this.$element : document.body)
-
- pos = this.getPosition(inside)
-
- actualWidth = $tip[0].offsetWidth
- actualHeight = $tip[0].offsetHeight
-
- switch (inside ? placement.split(' ')[1] : placement) {
- case 'bottom':
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'top':
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'left':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
- break
- case 'right':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
- break
- }
-
- $tip
- .css(tp)
- .addClass(placement)
- .addClass('in')
- }
- }
-
- , isHTML: function(text) {
- // html string detection logic adapted from jQuery
- return typeof text != 'string'
- || ( text.charAt(0) === "<"
- && text.charAt( text.length - 1 ) === ">"
- && text.length >= 3
- ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text)
- }
-
- , setContent: function () {
- var $tip = this.tip()
- , title = this.getTitle()
-
- $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title)
- $tip.removeClass('fade in top bottom left right')
- }
-
- , hide: function () {
- var that = this
- , $tip = this.tip()
-
- $tip.removeClass('in')
-
- function removeWithAnimation() {
- var timeout = setTimeout(function () {
- $tip.off($.support.transition.end).remove()
- }, 500)
-
- $tip.one($.support.transition.end, function () {
- clearTimeout(timeout)
- $tip.remove()
- })
- }
-
- $.support.transition && this.$tip.hasClass('fade') ?
- removeWithAnimation() :
- $tip.remove()
- }
-
- , fixTitle: function () {
- var $e = this.$element
- if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
- }
- }
-
- , hasContent: function () {
- return this.getTitle()
- }
-
- , getPosition: function (inside) {
- return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
- width: this.$element[0].offsetWidth
- , height: this.$element[0].offsetHeight
- })
- }
-
- , getTitle: function () {
- var title
- , $e = this.$element
- , o = this.options
-
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
-
- return title
- }
-
- , tip: function () {
- return this.$tip = this.$tip || $(this.options.template)
- }
-
- , validate: function () {
- if (!this.$element[0].parentNode) {
- this.hide()
- this.$element = null
- this.options = null
- }
- }
-
- , enable: function () {
- this.enabled = true
- }
-
- , disable: function () {
- this.enabled = false
- }
-
- , toggleEnabled: function () {
- this.enabled = !this.enabled
- }
-
- , toggle: function () {
- this[this.tip().hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
-
- /* TOOLTIP PLUGIN DEFINITION
- * ========================= */
-
- $.fn.tooltip = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tooltip')
- , options = typeof option == 'object' && option
- if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tooltip.Constructor = Tooltip
-
- $.fn.tooltip.defaults = {
- animation: true
- , placement: 'top'
- , selector: false
- , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
- , trigger: 'hover'
- , title: ''
- , delay: 0
- }
-
-}(window.jQuery);/* ===========================================================
- * bootstrap-popover.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#popovers
- * ===========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * =========================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* POPOVER PUBLIC CLASS DEFINITION
- * =============================== */
-
- var Popover = function ( element, options ) {
- this.init('popover', element, options)
- }
-
-
- /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
- ========================================== */
-
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
-
- constructor: Popover
-
- , setContent: function () {
- var $tip = this.tip()
- , title = this.getTitle()
- , content = this.getContent()
-
- $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
- $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
-
- $tip.removeClass('fade top bottom left right in')
- }
-
- , hasContent: function () {
- return this.getTitle() || this.getContent()
- }
-
- , getContent: function () {
- var content
- , $e = this.$element
- , o = this.options
-
- content = $e.attr('data-content')
- || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
-
- return content
- }
-
- , tip: function () {
- if (!this.$tip) {
- this.$tip = $(this.options.template)
- }
- return this.$tip
- }
-
- })
-
-
- /* POPOVER PLUGIN DEFINITION
- * ======================= */
-
- $.fn.popover = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('popover')
- , options = typeof option == 'object' && option
- if (!data) $this.data('popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.popover.Constructor = Popover
-
- $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
- placement: 'right'
- , content: ''
- , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
- })
-
-}(window.jQuery);/* =============================================================
- * bootstrap-scrollspy.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#scrollspy
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* SCROLLSPY CLASS DEFINITION
- * ========================== */
-
- function ScrollSpy( element, options) {
- var process = $.proxy(this.process, this)
- , $element = $(element).is('body') ? $(window) : $(element)
- , href
- this.options = $.extend({}, $.fn.scrollspy.defaults, options)
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
- this.selector = (this.options.target
- || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- || '') + ' .nav li > a'
- this.$body = $('body')
- this.refresh()
- this.process()
- }
-
- ScrollSpy.prototype = {
-
- constructor: ScrollSpy
-
- , refresh: function () {
- var self = this
- , $targets
-
- this.offsets = $([])
- this.targets = $([])
-
- $targets = this.$body
- .find(this.selector)
- .map(function () {
- var $el = $(this)
- , href = $el.data('target') || $el.attr('href')
- , $href = /^#\w/.test(href) && $(href)
- return ( $href
- && href.length
- && [[ $href.position().top, href ]] ) || null
- })
- .sort(function (a, b) { return a[0] - b[0] })
- .each(function () {
- self.offsets.push(this[0])
- self.targets.push(this[1])
- })
- }
-
- , process: function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
- , maxScroll = scrollHeight - this.$scrollElement.height()
- , offsets = this.offsets
- , targets = this.targets
- , activeTarget = this.activeTarget
- , i
-
- if (scrollTop >= maxScroll) {
- return activeTarget != (i = targets.last()[0])
- && this.activate ( i )
- }
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
- && this.activate( targets[i] )
- }
- }
-
- , activate: function (target) {
- var active
- , selector
-
- this.activeTarget = target
-
- $(this.selector)
- .parent('.active')
- .removeClass('active')
-
- selector = this.selector
- + '[data-target="' + target + '"],'
- + this.selector + '[href="' + target + '"]'
-
- active = $(selector)
- .parent('li')
- .addClass('active')
-
- if (active.parent('.dropdown-menu')) {
- active = active.closest('li.dropdown').addClass('active')
- }
-
- active.trigger('activate')
- }
-
- }
-
-
- /* SCROLLSPY PLUGIN DEFINITION
- * =========================== */
-
- $.fn.scrollspy = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('scrollspy')
- , options = typeof option == 'object' && option
- if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.scrollspy.Constructor = ScrollSpy
-
- $.fn.scrollspy.defaults = {
- offset: 10
- }
-
-
- /* SCROLLSPY DATA-API
- * ================== */
-
- $(function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- $spy.scrollspy($spy.data())
- })
- })
-
-}(window.jQuery);/* ========================================================
- * bootstrap-tab.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#tabs
- * ========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ======================================================== */
-
-
-!function ($) {
-
- "use strict"; // jshint ;_;
-
-
- /* TAB CLASS DEFINITION
- * ==================== */
-
- var Tab = function ( element ) {
- this.element = $(element)
- }
-
- Tab.prototype = {
-
- constructor: Tab
-
- , show: function () {
- var $this = this.element
- , $ul = $this.closest('ul:not(.dropdown-menu)')
- , selector = $this.attr('data-target')
- , previous
- , $target
- , e
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- if ( $this.parent('li').hasClass('active') ) return
-
- previous = $ul.find('.active a').last()[0]
-
- e = $.Event('show', {
- relatedTarget: previous
- })
-
- $this.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- $target = $(selector)
-
- this.activate($this.parent('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $this.trigger({
- type: 'shown'
- , relatedTarget: previous
- })
- })
- }
-
- , activate: function ( element, container, callback) {
- var $active = container.find('> .active')
- , transition = callback
- && $.support.transition
- && $active.hasClass('fade')
-
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
-
- element.addClass('active')
-
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
-
- if ( element.parent('.dropdown-menu') ) {
- element.closest('li.dropdown').addClass('active')
- }
-
- callback && callback()
- }
-
- transition ?
- $active.one($.support.transition.end, next) :
- next()
-
- $active.removeClass('in')
- }
- }
-
-
- /* TAB PLUGIN DEFINITION
- * ===================== */
-
- $.fn.tab = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tab')
- if (!data) $this.data('tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tab.Constructor = Tab
-
-
- /* TAB DATA-API
- * ============ */
-
- $(function () {
- $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
- e.preventDefault()
- $(this).tab('show')
- })
- })
-
-}(window.jQuery);/* =============================================================
- * bootstrap-typeahead.js v2.0.3
- * http://twitter.github.com/bootstrap/javascript.html#typeahead
- * =============================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============================================================ */
-
-
-!function($){
-
- "use strict"; // jshint ;_;
-
-
- /* TYPEAHEAD PUBLIC CLASS DEFINITION
- * ================================= */
-
- var Typeahead = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.typeahead.defaults, options)
- this.matcher = this.options.matcher || this.matcher
- this.sorter = this.options.sorter || this.sorter
- this.highlighter = this.options.highlighter || this.highlighter
- this.updater = this.options.updater || this.updater
- this.$menu = $(this.options.menu).appendTo('body')
- this.source = this.options.source
- this.shown = false
- this.listen()
- }
-
- Typeahead.prototype = {
-
- constructor: Typeahead
-
- , select: function () {
- var val = this.$menu.find('.active').attr('data-value')
- this.$element
- .val(this.updater(val))
- .change()
- return this.hide()
- }
-
- , updater: function (item) {
- return item
- }
-
- , show: function () {
- var pos = $.extend({}, this.$element.offset(), {
- height: this.$element[0].offsetHeight
- })
-
- this.$menu.css({
- top: pos.top + pos.height
- , left: pos.left
- })
-
- this.$menu.show()
- this.shown = true
- return this
- }
-
- , hide: function () {
- this.$menu.hide()
- this.shown = false
- return this
- }
-
- , lookup: function (event) {
- var that = this
- , items
- , q
-
- this.query = this.$element.val()
-
- if (!this.query) {
- return this.shown ? this.hide() : this
- }
-
- items = $.grep(this.source, function (item) {
- return that.matcher(item)
- })
-
- items = this.sorter(items)
-
- if (!items.length) {
- return this.shown ? this.hide() : this
- }
-
- return this.render(items.slice(0, this.options.items)).show()
- }
-
- , matcher: function (item) {
- return ~item.toLowerCase().indexOf(this.query.toLowerCase())
- }
-
- , sorter: function (items) {
- var beginswith = []
- , caseSensitive = []
- , caseInsensitive = []
- , item
-
- while (item = items.shift()) {
- if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
- else if (~item.indexOf(this.query)) caseSensitive.push(item)
- else caseInsensitive.push(item)
- }
-
- return beginswith.concat(caseSensitive, caseInsensitive)
- }
-
- , highlighter: function (item) {
- var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
- return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
- return '<strong>' + match + '</strong>'
- })
- }
-
- , render: function (items) {
- var that = this
-
- items = $(items).map(function (i, item) {
- i = $(that.options.item).attr('data-value', item)
- i.find('a').html(that.highlighter(item))
- return i[0]
- })
-
- items.first().addClass('active')
- this.$menu.html(items)
- return this
- }
-
- , next: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , next = active.next()
-
- if (!next.length) {
- next = $(this.$menu.find('li')[0])
- }
-
- next.addClass('active')
- }
-
- , prev: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , prev = active.prev()
-
- if (!prev.length) {
- prev = this.$menu.find('li').last()
- }
-
- prev.addClass('active')
- }
-
- , listen: function () {
- this.$element
- .on('blur', $.proxy(this.blur, this))
- .on('keypress', $.proxy(this.keypress, this))
- .on('keyup', $.proxy(this.keyup, this))
-
- if ($.browser.webkit || $.browser.msie) {
- this.$element.on('keydown', $.proxy(this.keypress, this))
- }
-
- this.$menu
- .on('click', $.proxy(this.click, this))
- .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
- }
-
- , keyup: function (e) {
- switch(e.keyCode) {
- case 40: // down arrow
- case 38: // up arrow
- break
-
- case 9: // tab
- case 13: // enter
- if (!this.shown) return
- this.select()
- break
-
- case 27: // escape
- if (!this.shown) return
- this.hide()
- break
-
- default:
- this.lookup()
- }
-
- e.stopPropagation()
- e.preventDefault()
- }
-
- , keypress: function (e) {
- if (!this.shown) return
-
- switch(e.keyCode) {
- case 9: // tab
- case 13: // enter
- case 27: // escape
- e.preventDefault()
- break
-
- case 38: // up arrow
- if (e.type != 'keydown') break
- e.preventDefault()
- this.prev()
- break
-
- case 40: // down arrow
- if (e.type != 'keydown') break
- e.preventDefault()
- this.next()
- break
- }
-
- e.stopPropagation()
- }
-
- , blur: function (e) {
- var that = this
- setTimeout(function () { that.hide() }, 150)
- }
-
- , click: function (e) {
- e.stopPropagation()
- e.preventDefault()
- this.select()
- }
-
- , mouseenter: function (e) {
- this.$menu.find('.active').removeClass('active')
- $(e.currentTarget).addClass('active')
- }
-
- }
-
-
- /* TYPEAHEAD PLUGIN DEFINITION
- * =========================== */
-
- $.fn.typeahead = function (option) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('typeahead')
- , options = typeof option == 'object' && option
- if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.typeahead.defaults = {
- source: []
- , items: 8
- , menu: '<ul class="typeahead dropdown-menu"></ul>'
- , item: '<li><a href="#"></a></li>'
- }
-
- $.fn.typeahead.Constructor = Typeahead
-
-
- /* TYPEAHEAD DATA-API
- * ================== */
-
- $(function () {
- $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
- var $this = $(this)
- if ($this.data('typeahead')) return
- e.preventDefault()
- $this.typeahead($this.data())
- })
- })
-
-}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/bootstrap/js/bootstrap.min.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/bootstrap/js/bootstrap.min.js b/src/webui/master/static/bootstrap/js/bootstrap.min.js
deleted file mode 100644
index 8c06421..0000000
--- a/src/webui/master/static/bootstrap/js/bootstrap.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
-* Bootstrap.js by @fat & @mdo
-* Copyright 2012 Twitter, Inc.
-* http://www.apache.org/licenses/LICENSE-2.0.txt
-*/
-!function(a){a(function(){"use strict",a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=n
ew c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(func
tion(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=c,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.prototype={cycle:function(b){return b||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(a){return a||(this.paused=!0),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding
)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this,j=a.Event("slide");this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h]();if(e.hasClass("active"))return;if(a.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(j);if(j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})}else{this.$element.trigger(j);if(j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){
var d=a(this),e=d.data("carousel"),f=a.extend({},a.fn.carousel.defaults,typeof c=="object"&&c);e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():f.interval&&e.cycle()})},a.fn.carousel.defaults={interval:5e3,pause:"hover"},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b,c,d,e;if(this.transitioning)return;b=this.dimension(),c=a.camelCase([
"scroll",b].join("-")),d=this.$parent&&this.$parent.find("> .accordion-group > .in");if(d&&d.length){e=d.data("collapse");if(e&&e.transitioning)return;d.collapse("hide"),e||d.data("collapse",null)}this.$element[b](0),this.transition("addClass",a.Event("show"),"shown"),this.$element[b](this.$element[0][c])},hide:function(){var b;if(this.transitioning)return;b=this.dimension(),this.reset(this.$element[b]()),this.transition("removeClass",a.Event("hide"),"hidden"),this.$element[b](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a!==null?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c.type=="show"&&e.reset(),e.transitioning=0,e.$element.trigger(d)};this.$element.trigger(c);if(c.isDefaultPrevented())return;this.transitioning=1,this.$element[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},t
oggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e,f,g;if(c.is(".disabled, :disabled"))return;return f=c.attr("data-target"),f||(f=c.at
tr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,"")),e=a(f),e.length||(e=c.parent()),g=e.hasClass("open"),d(),g||e.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown",".dropdown form",function(a){a.stopPropagation()}).on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendT
o(document.body),this.options.backdrop!="static"&&this.$backdrop.click(a.proxy(this.hide,this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),e?this.$backdrop.one(a.support.transition.end,b):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,a.proxy(f,this)):f.call(this)):b&&b()}function f(){this.$backdrop.remove(),this.$backdrop=null}function g(){var b=this;this.isShown&&this.options.keyboard?a(document).on("keyup.dismiss.modal",function(a){a.which==27&&b.hide()}):this.isShown||a(document).off("keyup.dismiss.modal")}"use strict";var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this))};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrev
ented())return;a("body").addClass("modal-open"),this.isShown=!0,g.call(this),e.call(this,function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in"),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var e=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),g.call(this),this.$element.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?c.call(this):d.call(this)}},a.fn.modal=function(c){return this.each(function(){var d=a(this),e=d.data("modal"),f=a.extend({},a.fn.modal.defaults,d.data(),typeof c=="object"&&c);e||d.data("modal",e=new b(this,f)),typeof c=="string"?e[c]():f.show&&e.show()})},a.fn.modal.defaults={backdrop:!0,keyboard:
!0,show:!0},a.fn.modal.Constructor=b,a(function(){a("body").on("click.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({},e.data(),c.data());b.preventDefault(),e.modal(f)})})}(window.jQuery),!function(a){"use strict";var b=function(a,b){this.init("tooltip",a,b)};b.prototype={constructor:b,init:function(b,c,d){var e,f;this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.enabled=!0,this.options.trigger!="manual"&&(e=this.options.trigger=="hover"?"mouseenter":"focus",f=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(e,this.options.selector,a.proxy(this.enter,this)),this.$element.on(f,this.options.selector,a.proxy(this.leave,this))),this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(b){return b=a.extend({},a.fn[this.type].defaults,b,this.$eleme
nt.data()),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},enter:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.show)return c.show();clearTimeout(this.timeout),c.hoverState="in",this.timeout=setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show)},leave:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);if(!c.options.delay||!c.options.delay.hide)return c.hide();clearTimeout(this.timeout),c.hoverState="out",this.timeout=setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide)},show:function(){var a,b,c,d,e,f,g;if(this.hasContent()&&this.enabled){a=this.tip(),this.setContent(),this.options.animation&&a.addClass("fade"),f=typeof this.options.placement=="function"?this.options.placement.call(this,a[0],this.$element[0]):this.options.placement,b=/in/.test(f),a.remove().css({top:0,left:0,display:"block"}).appendTo(b?this.$element:
document.body),c=this.getPosition(b),d=a[0].offsetWidth,e=a[0].offsetHeight;switch(b?f.split(" ")[1]:f){case"bottom":g={top:c.top+c.height,left:c.left+c.width/2-d/2};break;case"top":g={top:c.top-e,left:c.left+c.width/2-d/2};break;case"left":g={top:c.top+c.height/2-e/2,left:c.left-d};break;case"right":g={top:c.top+c.height/2-e/2,left:c.left+c.width}}a.css(g).addClass(f).addClass("in")}},isHTML:function(a){return typeof a!="string"||a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3||/^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(a)},setContent:function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.isHTML(b)?"html":"text"](b),a.removeClass("fade in top bottom left right")},hide:function(){function d(){var b=setTimeout(function(){c.off(a.support.transition.end).remove()},500);c.one(a.support.transition.end,function(){clearTimeout(b),c.remove()})}var b=this,c=this.tip();c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d():c.remove()},fixTitle:function(
){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(b){return a.extend({},b?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a},tip:function(){return this.$tip=this.$tip||a(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()}},a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("tooltip"),f=typeof c=="object"&&c;e||
d.data("tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0}}(window.jQuery),!function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype,{constructor:b,setContent:function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.isHTML(b)?"html":"text"](b),a.find(".popover-content > *")[this.isHTML(c)?"html":"text"](c),a.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-content")||(typeof c.content=="function"?c.content.call(b[0]):c.content),a},tip:function(){return this.$tip||(this.$tip=a(this.options.template)),th
is.$tip}}),a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("popover"),f=typeof c=="object"&&c;e||d.data("popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.defaults=a.extend({},a.fn.tooltip.defaults,{placement:"right",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'})}(window.jQuery),!function(a){function b(b,c){var d=a.proxy(this.process,this),e=a(b).is("body")?a(window):a(b),f;this.options=a.extend({},a.fn.scrollspy.defaults,c),this.$scrollElement=e.on("scroll.scroll.data-api",d),this.selector=(this.options.target||(f=a(b).attr("href"))&&f.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=a("body"),this.refresh(),this.process()}"use strict",b.prototype={constructor:b,refresh:function(){var b=this,c;this.offsets=a([]),this.targets=a([]),c=this.$body.find(this.selector).m
ap(function(){var b=a(this),c=b.data("target")||b.attr("href"),d=/^#\w/.test(c)&&a(c);return d&&c.length&&[[d.position().top,c]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},process:function(){var a=this.$scrollElement.scrollTop()+this.options.offset,b=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,c=b-this.$scrollElement.height(),d=this.offsets,e=this.targets,f=this.activeTarget,g;if(a>=c)return f!=(g=e.last()[0])&&this.activate(g);for(g=d.length;g--;)f!=e[g]&&a>=d[g]&&(!d[g+1]||a<=d[g+1])&&this.activate(e[g])},activate:function(b){var c,d;this.activeTarget=b,a(this.selector).parent(".active").removeClass("active"),d=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',c=a(d).parent("li").addClass("active"),c.parent(".dropdown-menu")&&(c=c.closest("li.dropdown").addClass("active")),c.trigger("activate")}},a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data
("scrollspy"),f=typeof c=="object"&&c;e||d.data("scrollspy",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.defaults={offset:10},a(function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),!function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype={constructor:b,show:function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target"),e,f,g;d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));if(b.parent("li").hasClass("active"))return;e=c.find(".active a").last()[0],g=a.Event("show",{relatedTarget:e}),b.trigger(g);if(g.isDefaultPrevented())return;f=a(d),this.activate(b.parent("li"),c),this.activate(f,f.parent(),function(){b.trigger({type:"shown",relatedTarget:e})})},activate:function(b,c,d){function g(){e.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),f?(b[0].offsetWidth,b.addClass("in")):b.remo
veClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var e=c.find("> .active"),f=d&&a.support.transition&&e.hasClass("fade");f?e.one(a.support.transition.end,g):g(),e.removeClass("in")}},a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("tab");e||d.data("tab",e=new b(this)),typeof c=="string"&&e[c]()})},a.fn.tab.Constructor=b,a(function(){a("body").on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.typeahead.defaults,c),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=a(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};b.prototype={co
nstructor:b,select:function(){var a=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(a)).change(),this.hide()},updater:function(a){return a},show:function(){var b=a.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:b.top+b.height,left:b.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(b){var c=this,d,e;return this.query=this.$element.val(),this.query?(d=a.grep(this.source,function(a){return c.matcher(a)}),d=this.sorter(d),d.length?this.render(d.slice(0,this.options.items)).show():this.shown?this.hide():this):this.shown?this.hide():this},matcher:function(a){return~a.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){var b=[],c=[],d=[],e;while(e=a.shift())e.toLowerCase().indexOf(this.query.toLowerCase())?~e.indexOf(this.query)?c.push(e):d.push(e):b.push(e);return b.concat(c,d)},highlighter:function(a){var b=this.
query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return a.replace(new RegExp("("+b+")","ig"),function(a,b){return"<strong>"+b+"</strong>"})},render:function(b){var c=this;return b=a(b).map(function(b,d){return b=a(c.options.item).attr("data-value",d),b.find("a").html(c.highlighter(d)),b[0]}),b.first().addClass("active"),this.$menu.html(b),this},next:function(b){var c=this.$menu.find(".active").removeClass("active"),d=c.next();d.length||(d=a(this.$menu.find("li")[0])),d.addClass("active")},prev:function(a){var b=this.$menu.find(".active").removeClass("active"),c=b.prev();c.length||(c=this.$menu.find("li").last()),c.addClass("active")},listen:function(){this.$element.on("blur",a.proxy(this.blur,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),(a.browser.webkit||a.browser.msie)&&this.$element.on("keydown",a.proxy(this.keypress,this)),this.$menu.on("click",a.proxy(this.click,this)).on("mouseenter","li",a.proxy(this.mouseenter,this))},keyup:functi
on(a){switch(a.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}a.stopPropagation(),a.preventDefault()},keypress:function(a){if(!this.shown)return;switch(a.keyCode){case 9:case 13:case 27:a.preventDefault();break;case 38:if(a.type!="keydown")break;a.preventDefault(),this.prev();break;case 40:if(a.type!="keydown")break;a.preventDefault(),this.next()}a.stopPropagation()},blur:function(a){var b=this;setTimeout(function(){b.hide()},150)},click:function(a){a.stopPropagation(),a.preventDefault(),this.select()},mouseenter:function(b){this.$menu.find(".active").removeClass("active"),a(b.currentTarget).addClass("active")}},a.fn.typeahead=function(c){return this.each(function(){var d=a(this),e=d.data("typeahead"),f=typeof c=="object"&&c;e||d.data("typeahead",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-men
u"></ul>',item:'<li><a href="#"></a></li>'},a.fn.typeahead.Constructor=b,a(function(){a("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(b){var c=a(this);if(c.data("typeahead"))return;b.preventDefault(),c.typeahead(c.data())})})}(window.jQuery);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/controllers.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/controllers.js b/src/webui/master/static/controllers.js
index 2b3f01e..07d837a 100644
--- a/src/webui/master/static/controllers.js
+++ b/src/webui/master/static/controllers.js
@@ -275,11 +275,7 @@ function MainCntl($scope, $http, $route, $routeParams, $location, $timeout) {
path = path.substr(0, path.length - 1);
}
return path.substr(path.lastIndexOf('/') + 1);
- }
-
- // Initialize popovers and bind the function used to show a popover.
- Popovers.initialize();
- $scope.popover = Popovers.show;
+ };
$scope.$location = $location;
$scope.delay = 2000;
@@ -301,26 +297,31 @@ function MainCntl($scope, $http, $route, $routeParams, $location, $timeout) {
} else {
$scope.delay = $scope.delay * 2;
}
+
$scope.retry = $scope.delay;
var countdown = function() {
- if ($scope.retry == 0) {
- $('#error-modal').modal('hide');
+ if ($scope.retry === 0) {
+ $scope.errorModalClose();
} else {
$scope.retry = $scope.retry - 1000;
$scope.countdown = $timeout(countdown, 1000);
}
- }
+ };
+
countdown();
- $('#error-modal').modal('show');
+ $scope.errorModalOpen = true;
});
- }
+ };
// Make it such that everytime we hide the error-modal, we stop the
// countdown and restart the polling.
- $('#error-modal').on('hidden', function () {
- if ($scope.countdown != undefined) {
+ $scope.errorModalClose = function() {
+ $scope.errorModalOpen = false;
+
+ if ($scope.countdown != null) {
if ($timeout.cancel($scope.countdown)) {
- $scope.delay = 2000; // Restart since they cancelled the countdown.
+ // Restart since they cancelled the countdown.
+ $scope.delay = 2000;
}
}
@@ -328,13 +329,13 @@ function MainCntl($scope, $http, $route, $routeParams, $location, $timeout) {
// least a second because otherwise the error-modal won't get
// properly shown).
$timeout(poll, 1000);
- });
+ };
poll();
}
-function HomeCtrl($scope) {
+function HomeCtrl($dialog, $scope) {
setNavbarActiveTab('home');
$scope.tables = {};
@@ -348,14 +349,18 @@ function HomeCtrl($scope) {
$scope.log = function($event) {
if (!$scope.state.log_dir) {
- $('#no-log-dir-modal').modal('show');
+ $dialog.messageBox(
+ 'Logging to a file is not enabled',
+ "Set the 'log_dir' option if you wish to access the logs.",
+ [{label: 'Continue'}]
+ ).open();
} else {
pailer(
$scope.$location.host() + ':' + $scope.$location.port(),
'/master/log',
'Mesos Master');
}
- }
+ };
}
@@ -435,7 +440,7 @@ function SlavesCtrl($scope) {
}
-function SlaveCtrl($scope, $routeParams, $http, $q) {
+function SlaveCtrl($dialog, $scope, $routeParams, $http, $q) {
setNavbarActiveTab('slaves');
$scope.slave_id = $routeParams.slave_id;
@@ -457,15 +462,19 @@ function SlaveCtrl($scope, $routeParams, $http, $q) {
var pid = $scope.slaves[$routeParams.slave_id].pid;
var hostname = $scope.slaves[$routeParams.slave_id].hostname;
var id = pid.substring(0, pid.indexOf('@'));
- var host = hostname + ":" + pid.substring(pid.lastIndexOf(':') + 1)
+ var host = hostname + ":" + pid.substring(pid.lastIndexOf(':') + 1);
$scope.log = function($event) {
if (!$scope.state.log_dir) {
- $('#no-log-dir-modal').modal('show');
+ $dialog.messageBox(
+ 'Logging to a file is not enabled',
+ "Set the 'log_dir' option if you wish to access the logs.",
+ [{label: 'Continue'}]
+ ).open();
} else {
pailer(host, '/slave/log', 'Mesos Slave');
}
- }
+ };
var usageRequest = $http.jsonp(
'http://' + host + '/monitor/usage.json?jsonp=JSON_CALLBACK');
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/framework.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/framework.html b/src/webui/master/static/framework.html
index 3af4b83..97d25b7 100644
--- a/src/webui/master/static/framework.html
+++ b/src/webui/master/static/framework.html
@@ -24,13 +24,19 @@
<dd>{{framework.user}}</dd>
<dt>Registered:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{framework.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{framework.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{framework.registered_time * 1000 | relativeDate}}
</a>
</dd>
<dt>Re-registered:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.reregistered_time * 1000 | mesosDate}}" data-original-title="Reregistered">
+ <a href="javascript:void(0)"
+ popover="{{framework.reregistered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Reregistered">
{{framework.reregistered_time * 1000 | relativeDate}}
</a>
</dd>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/frameworks.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/frameworks.html b/src/webui/master/static/frameworks.html
index 49306ca..bcae436 100644
--- a/src/webui/master/static/frameworks.html
+++ b/src/webui/master/static/frameworks.html
@@ -55,7 +55,10 @@
<tbody>
<tr ng-repeat="framework in _.values(frameworks) | orderBy:tables['frameworks'].selected_column:tables['frameworks'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{framework.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{framework.id | truncateMesosID}}
</a>
</td>
@@ -66,12 +69,18 @@
<td>{{framework.resources.mem * (1024 * 1024) | dataSize}}</td>
<td>{{framework.max_share * 100 | number}}%</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{framework.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{framework.registered_time * 1000 | relativeDate}}
</a>
</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.reregistered_time * 1000 | mesosDate}}" data-original-title="Reregistered">
+ <a href="javascript:void(0)"
+ popover="{{framework.reregistered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Reregistered">
{{framework.reregistered_time * 1000 | relativeDate}}
</a>
</td>
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/home.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/home.html b/src/webui/master/static/home.html
index f08abbb..f06b364 100644
--- a/src/webui/master/static/home.html
+++ b/src/webui/master/static/home.html
@@ -1,15 +1,3 @@
-<div class="modal hide fade" style="display: none;" id="no-log-dir-modal">
- <div class="modal-header">
- <button class="close" data-dismiss="modal">×</button>
- <h3>Logging to a file is not enabled!</h3>
- </div>
- <div class="modal-body">
- <p>Set the 'log_dir' option if you wish to access the logs.</p>
- </div>
- <div class="modal-footer">
- </div>
-</div>
-
<ul class="breadcrumb">
<li class="active">
<span class="badge badge-type">Master</span>
@@ -27,13 +15,19 @@
<dd>{{state.pid.split("@")[1]}}</dd>
<dt>Built:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{state.build_time * 1000 | mesosDate}}" data-original-title="Built">
+ <a href="javascript:void(0)"
+ popover="{{state.build_time * 1000 | mesosDate}}"
+ popover-placement="right"
+ popover-title="Built">
{{state.build_time * 1000 | relativeDate}}
</a> by <i>{{state.build_user}}</i>
</dd>
<dt>Started:</dt>
<dd>
- <a href="" rel="popover" ng-click="popover($event, 'right')" data-content="{{state.start_time * 1000 | mesosDate}}" data-original-title="Started">
+ <a href="javascript:void(0)"
+ popover="{{state.start_time * 1000 | mesosDate}}"
+ popover-placement="right"
+ popover-title="Started">
{{state.start_time * 1000 | relativeDate}}
</a>
</dd>
@@ -171,7 +165,10 @@
<tbody>
<tr ng-repeat="framework in _.values(frameworks) | orderBy:tables['frameworks'].selected_column:tables['frameworks'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{framework.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{framework.id | truncateMesosID}}
</a>
</td>
@@ -182,12 +179,18 @@
<td>{{framework.resources.mem * (1024 * 1024) | dataSize}}</td>
<td>{{framework.max_share * 100 | number}}%</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{framework.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{framework.registered_time * 1000 | relativeDate}}
</a>
</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.reregistered_time * 1000 | mesosDate}}" data-original-title="Reregistered">
+ <a href="javascript:void(0)"
+ popover="{{framework.reregistered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Reregistered">
{{framework.reregistered_time * 1000 | relativeDate}}
</a>
</td>
@@ -230,7 +233,10 @@
</thead>
<tr ng-repeat="slave in _.values(slaves) | orderBy:tables['slaves'].selected_column:tables['slaves'].reverse">
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{slave.id}}" data-original-title="ID">
+ <a href="javascript:void(0)"
+ popover="{{slave.id}}"
+ popover-placement="bottom"
+ popover-title="ID">
{{slave.id | truncateMesosID}}
</a>
</td>
@@ -242,7 +248,10 @@
<td>{{slave.resources.mem * (1024 * 1024) | dataSize}}</td>
<td>{{slave.resources.disk * (1024 * 1024) | dataSize}}</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{slave.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{slave.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{slave.registered_time * 1000 | relativeDate}}
</a>
</td>
@@ -326,12 +335,18 @@
<td>{{framework.user}}</td>
<td><a href="{{'#/frameworks/' + framework.id}}">{{framework.name}}</a></td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.registered_time * 1000 | mesosDate}}" data-original-title="Registered">
+ <a href="javascript:void(0)"
+ popover="{{framework.registered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Registered">
{{framework.registered_time * 1000 | relativeDate}}
</a>
</td>
<td>
- <a href="" rel="popover" ng-click="popover($event, 'bottom')" data-content="{{framework.unregistered_time * 1000 | mesosDate}}" data-original-title="Unregistered">
+ <a href="javascript:void(0)"
+ popover="{{framework.unregistered_time * 1000 | mesosDate}}"
+ popover-placement="bottom"
+ popover-title="Unregistered">
{{framework.unregistered_time * 1000 | relativeDate}}
</a>
</td>
[3/7] Replaced bootstrap.js with angular-ui.js
Posted by bm...@apache.org.
http://git-wip-us.apache.org/repos/asf/mesos/blob/9929d2b8/src/webui/master/static/ui-bootstrap-tpls-0.4.0.min.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/ui-bootstrap-tpls-0.4.0.min.js b/src/webui/master/static/ui-bootstrap-tpls-0.4.0.min.js
new file mode 100644
index 0000000..009c43a
--- /dev/null
+++ b/src/webui/master/static/ui-bootstrap-tpls-0.4.0.min.js
@@ -0,0 +1,2 @@
+angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.datepicker","ui.bootstrap.dialog","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.position","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/dialog/message.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressb
ar/bar.html","template/progressbar/progress.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead.html"]),angular.module("ui.bootstrap.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(e,t,n){function a(e){for(var t in e)if(void 0!==i.style[t])return e[t]}var o=function(a,i,r){r=r||{};var l=e.defer(),s=o[r.animation?"animationEndEventName":"transitionEndEventName"],c=function(){n.$apply(function(){a.unbind(s,c),l.resolve(a)})};return s&&a.bind(s,c),t(function(){angular.isString(i)?a.addClass(i):angular.isFunction(i)?i(a):angular.isObject(i)&&a.css(i),s||l.resolve(a)}),l.promise.cancel=function(){s&&a.unbind(s,c),l.reject("Transition cancelled")},l.promise},i=document.createElement("trans"),r={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},l={WebkitTransition:"webkitAnimationEnd
",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return o.transitionEndEventName=a(r),o.animationEndEventName=a(l),o}]),angular.module("ui.bootstrap.collapse",["ui.bootstrap.transition"]).directive("collapse",["$transition",function(e){var t=function(e,t,n){t.removeClass("collapse"),t.css({height:n}),t[0].offsetWidth,t.addClass("collapse")};return{link:function(n,a,o){var i,r=!0;n.$watch(function(){return a[0].scrollHeight},function(){0!==a[0].scrollHeight&&(i||(r?t(n,a,a[0].scrollHeight+"px"):t(n,a,"auto")))}),n.$watch(o.collapse,function(e){e?u():c()});var l,s=function(t){return l&&l.cancel(),l=e(a,t),l.then(function(){l=void 0},function(){l=void 0}),l},c=function(){r?(r=!1,i||t(n,a,"auto")):s({height:a[0].scrollHeight+"px"}).then(function(){i||t(n,a,"auto")}),i=!1},u=function(){i=!0,r?(r=!1,t(n,a,0)):(t(n,a,a[0].scrollHeight+"px"),s({height:"0"}))}}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfi
g",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function(e,t,n){this.groups=[],this.closeOthers=function(a){var o=angular.isDefined(t.closeOthers)?e.$eval(t.closeOthers):n.closeOthers;o&&angular.forEach(this.groups,function(e){e!==a&&(e.isOpen=!1)})},this.addGroup=function(e){var t=this;this.groups.push(e),e.$on("$destroy",function(){t.removeGroup(e)})},this.removeGroup=function(e){var t=this.groups.indexOf(e);-1!==t&&this.groups.splice(this.groups.indexOf(e),1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",["$parse","$transition","$timeout",function(e){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@"},controller:["$scope",function(){this.setHeading=function(e){this.heading=e}}],link:function(t,n,a,o){var
i,r;o.addGroup(t),t.isOpen=!1,a.isOpen&&(i=e(a.isOpen),r=i.assign,t.$watch(function(){return i(t.$parent)},function(e){t.isOpen=e}),t.isOpen=i?i(t.$parent):!1),t.$watch("isOpen",function(e){e&&o.closeOthers(t),r&&r(t.$parent,e)})}}}]).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",compile:function(e,t,n){return function(e,t,a,o){o.setHeading(n(e,function(){}))}}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(e,t,n,a){e.$watch(function(){return a[n.accordionTransclude]},function(e){e&&(t.html(""),t.append(e))})}}}),angular.module("ui.bootstrap.alert",[]).directive("alert",function(){return{restrict:"EA",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"=",close:"&"},link:function(e,t,n){e.closeable="close"in n}}}),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).directive("bt
nRadio",["buttonConfig",function(e){var t=e.activeClass||"active",n=e.toggleEvent||"click";return{require:"ngModel",link:function(e,a,o,i){i.$render=function(){a.toggleClass(t,angular.equals(i.$modelValue,e.$eval(o.btnRadio)))},a.bind(n,function(){a.hasClass(t)||e.$apply(function(){i.$setViewValue(e.$eval(o.btnRadio)),i.$render()})})}}}]).directive("btnCheckbox",["buttonConfig",function(e){var t=e.activeClass||"active",n=e.toggleEvent||"click";return{require:"ngModel",link:function(e,a,o,i){var r=e.$eval(o.btnCheckboxTrue),l=e.$eval(o.btnCheckboxFalse);r=angular.isDefined(r)?r:!0,l=angular.isDefined(l)?l:!1,i.$render=function(){a.toggleClass(t,angular.equals(i.$modelValue,r))},a.bind(n,function(){e.$apply(function(){i.$setViewValue(a.hasClass(t)?l:r),i.$render()})})}}}]),angular.module("ui.bootstrap.carousel",["ui.bootstrap.transition"]).controller("CarouselController",["$scope","$timeout","$transition","$q",function(e,t,n){function a(){function n(){i?(e.next(),a()):e.pause()}o&&t.c
ancel(o);var r=+e.interval;!isNaN(r)&&r>=0&&(o=t(n,r))}var o,i,r=this,l=r.slides=[],s=-1;r.currentSlide=null,r.select=function(o,i){function c(){r.currentSlide&&angular.isString(i)&&!e.noTransition&&o.$element?(o.$element.addClass(i),o.$element[0].offsetWidth=o.$element[0].offsetWidth,angular.forEach(l,function(e){angular.extend(e,{direction:"",entering:!1,leaving:!1,active:!1})}),angular.extend(o,{direction:i,active:!0,entering:!0}),angular.extend(r.currentSlide||{},{direction:i,leaving:!0}),e.$currentTransition=n(o.$element,{}),function(t,n){e.$currentTransition.then(function(){u(t,n)},function(){u(t,n)})}(o,r.currentSlide)):u(o,r.currentSlide),r.currentSlide=o,s=p,a()}function u(t,n){angular.extend(t,{direction:"",active:!0,leaving:!1,entering:!1}),angular.extend(n||{},{direction:"",active:!1,leaving:!1,entering:!1}),e.$currentTransition=null}var p=l.indexOf(o);void 0===i&&(i=p>s?"next":"prev"),o&&o!==r.currentSlide&&(e.$currentTransition?(e.$currentTransition.cancel(),t(c)):c())
},r.indexOfSlide=function(e){return l.indexOf(e)},e.next=function(){var t=(s+1)%l.length;return e.$currentTransition?void 0:r.select(l[t],"next")},e.prev=function(){var t=0>s-1?l.length-1:s-1;return e.$currentTransition?void 0:r.select(l[t],"prev")},e.select=function(e){r.select(e)},e.isActive=function(e){return r.currentSlide===e},e.slides=function(){return l},e.$watch("interval",a),e.play=function(){i||(i=!0,a())},e.pause=function(){e.noPause||(i=!1,o&&t.cancel(o))},r.addSlide=function(t,n){t.$element=n,l.push(t),1===l.length||t.active?(r.select(l[l.length-1]),1==l.length&&e.play()):t.active=!1},r.removeSlide=function(e){var t=l.indexOf(e);l.splice(t,1),l.length>0&&e.active?t>=l.length?r.select(l[t-1]):r.select(l[t]):s>t&&s--}}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"="}}}]).directive("slide",["$pars
e",function(e){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{},link:function(t,n,a,o){if(a.active){var i=e(a.active),r=i.assign,l=t.active=i(t.$parent);t.$watch(function(){var e=i(t.$parent);return e!==t.active&&(e!==l?l=t.active=e:r(t.$parent,e=l=t.active)),e})}o.addSlide(t,n),t.$on("$destroy",function(){o.removeSlide(t)}),t.$watch("active",function(e){e&&o.select(t)})}}}]),angular.module("ui.bootstrap.datepicker",[]).constant("datepickerConfig",{dayFormat:"dd",monthFormat:"MMMM",yearFormat:"yyyy",dayHeaderFormat:"EEE",dayTitleFormat:"MMMM yyyy",monthTitleFormat:"yyyy",showWeeks:!0,startingDay:0,yearRange:20}).directive("datepicker",["dateFilter","$parse","datepickerConfig",function(e,t,n){return{restrict:"EA",replace:!0,scope:{model:"=ngModel",dateDisabled:"&"},templateUrl:"template/datepicker/datepicker.html",link:function(a,o,r){function l(e,t,n){a.rows=e,a.labels=t,a.title=n}function s(){a.showWeekNumbers="da
y"===a.mode&&p}function c(e,t){return"year"===a.mode?t.getFullYear()-e.getFullYear():"month"===a.mode?new Date(t.getFullYear(),t.getMonth())-new Date(e.getFullYear(),e.getMonth()):"day"===a.mode?new Date(t.getFullYear(),t.getMonth(),t.getDate())-new Date(e.getFullYear(),e.getMonth(),e.getDate()):void 0}function u(e){return d&&c(e,d)>0||m&&0>c(e,m)||a.dateDisabled&&a.dateDisabled({date:e,mode:a.mode})}a.mode="day";var p,d,m,g=new Date,f={};f.day=angular.isDefined(r.dayFormat)?a.$eval(r.dayFormat):n.dayFormat,f.month=angular.isDefined(r.monthFormat)?a.$eval(r.monthFormat):n.monthFormat,f.year=angular.isDefined(r.yearFormat)?a.$eval(r.yearFormat):n.yearFormat,f.dayHeader=angular.isDefined(r.dayHeaderFormat)?a.$eval(r.dayHeaderFormat):n.dayHeaderFormat,f.dayTitle=angular.isDefined(r.dayTitleFormat)?a.$eval(r.dayTitleFormat):n.dayTitleFormat,f.monthTitle=angular.isDefined(r.monthTitleFormat)?a.$eval(r.monthTitleFormat):n.monthTitleFormat;var h=angular.isDefined(r.startingDay)?a.$eval(r.s
tartingDay):n.startingDay,v=angular.isDefined(r.yearRange)?a.$eval(r.yearRange):n.yearRange;r.showWeeks?a.$parent.$watch(t(r.showWeeks),function(e){p=!!e,s()}):(p=n.showWeeks,s()),r.min&&a.$parent.$watch(t(r.min),function(e){d=new Date(e),w()}),r.max&&a.$parent.$watch(t(r.max),function(e){m=new Date(e),w()});var b=function(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n},$=function(e,t){return new Date(e,t+1,0).getDate()},y={day:function(){function t(t,a,i){for(var r=0;a>r;r++)n.push({date:new Date(t),isCurrent:i,isSelected:k(t),label:e(t,f.day),disabled:u(t)}),t.setDate(t.getDate()+1);o=t}var n=[],a=[],o=null,r=new Date(g);r.setDate(1);var s=h-r.getDay(),c=s>0?7-s:-s;for(c>0&&(r.setDate(-c+1),t(r,c,!1)),t(o||r,$(g.getFullYear(),g.getMonth()),!0),t(o,(7-n.length%7)%7,!1),i=0;7>i;i++)a.push(e(n[i].date,f.dayHeader));l(b(n,7),a,e(g,f.dayTitle))},month:function(){for(var t=[],n=0,a=g.getFullYear();12>n;){var o=new Date(a,n++,1);t.push({date:o,isCurrent:!0,isSelected:k(o),l
abel:e(o,f.month),disabled:u(o)})}l(b(t,3),[],e(g,f.monthTitle))},year:function(){for(var t=[],n=parseInt((g.getFullYear()-1)/v,10)*v+1,a=0;v>a;a++){var o=new Date(n+a,0,1);t.push({date:o,isCurrent:!0,isSelected:k(o),label:e(o,f.year),disabled:u(o)})}var i=t[0].label+" - "+t[t.length-1].label;l(b(t,5),[],i)}},w=function(){y[a.mode]()},k=function(e){if(a.model&&a.model.getFullYear()===e.getFullYear()){if("year"===a.mode)return!0;if(a.model.getMonth()===e.getMonth())return"month"===a.mode||"day"===a.mode&&a.model.getDate()===e.getDate()}return!1};a.$watch("model",function(e,t){angular.isDate(e)&&(g=angular.copy(e)),angular.equals(e,t)||w()}),a.$watch("mode",function(){s(),w()}),a.select=function(e){g=new Date(e),"year"===a.mode?(a.mode="month",g.setFullYear(e.getFullYear())):"month"===a.mode?(a.mode="day",g.setMonth(e.getMonth())):"day"===a.mode&&(a.model=new Date(g))},a.move=function(e){"day"===a.mode?g.setMonth(g.getMonth()+e):"month"===a.mode?g.setFullYear(g.getFullYear()+e):"year"
===a.mode&&g.setFullYear(g.getFullYear()+e*v),w()},a.toggleMode=function(){a.mode="day"===a.mode?"month":"month"===a.mode?"year":"day"},a.getWeekNumber=function(e){if("day"===a.mode&&a.showWeekNumbers&&7===e.length){var t=h>4?11-h:4-h,n=new Date(e[t].date);return n.setHours(0,0,0),Math.ceil(((n-new Date(n.getFullYear(),0,1))/864e5+1)/7)}}}}}]);var dialogModule=angular.module("ui.bootstrap.dialog",["ui.bootstrap.transition"]);dialogModule.controller("MessageBoxController",["$scope","dialog","model",function(e,t,n){e.title=n.title,e.message=n.message,e.buttons=n.buttons,e.close=function(e){t.close(e)}}]),dialogModule.provider("$dialog",function(){var e={backdrop:!0,dialogClass:"modal",backdropClass:"modal-backdrop",transitionClass:"fade",triggerClass:"in",resolve:{},backdropFade:!1,dialogFade:!1,keyboard:!0,backdropClick:!0},t={},n={value:0};this.options=function(e){t=e},this.$get=["$http","$document","$compile","$rootScope","$controller","$templateCache","$q","$transition","$injector
",function(a,o,i,r,l,s,c,u,p){function d(e){var t=angular.element("<div>");return t.addClass(e),t}function m(n){var a=this,o=this.options=angular.extend({},e,t,n);this._open=!1,this.backdropEl=d(o.backdropClass),o.backdropFade&&(this.backdropEl.addClass(o.transitionClass),this.backdropEl.removeClass(o.triggerClass)),this.modalEl=d(o.dialogClass),o.dialogFade&&(this.modalEl.addClass(o.transitionClass),this.modalEl.removeClass(o.triggerClass)),this.handledEscapeKey=function(e){27===e.which&&(a.close(),e.preventDefault(),a.$scope.$apply())},this.handleBackDropClick=function(e){a.close(),e.preventDefault(),a.$scope.$apply()},this.handleLocationChange=function(){a.close()}}var g=o.find("body");return m.prototype.isOpen=function(){return this._open},m.prototype.open=function(e,t){var n=this,a=this.options;if(e&&(a.templateUrl=e),t&&(a.controller=t),!a.template&&!a.templateUrl)throw Error("Dialog.open expected template or templateUrl, neither found. Use options or open method to specify th
em.");return this._loadResolves().then(function(e){var t=e.$scope=n.$scope=e.$scope?e.$scope:r.$new();if(n.modalEl.html(e.$template),n.options.controller){var a=l(n.options.controller,e);n.modalEl.children().data("ngControllerController",a)}i(n.modalEl)(t),n._addElementsToDom(),setTimeout(function(){n.options.dialogFade&&n.modalEl.addClass(n.options.triggerClass),n.options.backdropFade&&n.backdropEl.addClass(n.options.triggerClass)}),n._bindEvents()}),this.deferred=c.defer(),this.deferred.promise},m.prototype.close=function(e){function t(e){e.removeClass(a.options.triggerClass)}function n(){a._open&&a._onCloseComplete(e)}var a=this,o=this._getFadingElements();if(o.length>0)for(var i=o.length-1;i>=0;i--)u(o[i],t).then(n);else this._onCloseComplete(e)},m.prototype._getFadingElements=function(){var e=[];return this.options.dialogFade&&e.push(this.modalEl),this.options.backdropFade&&e.push(this.backdropEl),e},m.prototype._bindEvents=function(){this.options.keyboard&&g.bind("keydown",thi
s.handledEscapeKey),this.options.backdrop&&this.options.backdropClick&&this.backdropEl.bind("click",this.handleBackDropClick)},m.prototype._unbindEvents=function(){this.options.keyboard&&g.unbind("keydown",this.handledEscapeKey),this.options.backdrop&&this.options.backdropClick&&this.backdropEl.unbind("click",this.handleBackDropClick)},m.prototype._onCloseComplete=function(e){this._removeElementsFromDom(),this._unbindEvents(),this.deferred.resolve(e)},m.prototype._addElementsToDom=function(){g.append(this.modalEl),this.options.backdrop&&(0===n.value&&g.append(this.backdropEl),n.value++),this._open=!0},m.prototype._removeElementsFromDom=function(){this.modalEl.remove(),this.options.backdrop&&(n.value--,0===n.value&&this.backdropEl.remove()),this._open=!1},m.prototype._loadResolves=function(){var e,t=[],n=[],o=this;return this.options.template?e=c.when(this.options.template):this.options.templateUrl&&(e=a.get(this.options.templateUrl,{cache:s}).then(function(e){return e.data})),angula
r.forEach(this.options.resolve||[],function(e,a){n.push(a),t.push(angular.isString(e)?p.get(e):p.invoke(e))}),n.push("$template"),t.push(e),c.all(t).then(function(e){var t={};return angular.forEach(e,function(e,a){t[n[a]]=e}),t.dialog=o,t})},{dialog:function(e){return new m(e)},messageBox:function(e,t,n){return new m({templateUrl:"template/dialog/message.html",controller:"MessageBoxController",resolve:{model:function(){return{title:e,message:t,buttons:n}}}})}}}]}),angular.module("ui.bootstrap.dropdownToggle",[]).directive("dropdownToggle",["$document","$location",function(e){var t=null,n=angular.noop;return{restrict:"CA",link:function(a,o){a.$watch("$location.path",function(){n()}),o.parent().bind("click",function(){n()}),o.bind("click",function(a){var i=o===t;a.preventDefault(),a.stopPropagation(),t&&n(),i||(o.parent().addClass("open"),t=o,n=function(a){a&&(a.preventDefault(),a.stopPropagation()),e.unbind("click",n),o.parent().removeClass("open"),n=angular.noop,t=null},e.bind("clic
k",n))})}}}]),angular.module("ui.bootstrap.modal",["ui.bootstrap.dialog"]).directive("modal",["$parse","$dialog",function(e,t){return{restrict:"EA",terminal:!0,link:function(n,a,o){var i,r=angular.extend({},n.$eval(o.uiOptions||o.bsOptions||o.options)),l=o.modal||o.show;r=angular.extend(r,{template:a.html(),resolve:{$scope:function(){return n}}});var s=t.dialog(r);a.remove(),i=o.close?function(){e(o.close)(n)}:function(){angular.isFunction(e(l).assign)&&e(l).assign(n,!1)},n.$watch(l,function(e){e?s.open().then(function(){i()}):s.isOpen()&&s.close()})}}}]),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope",function(e){e.noPrevious=function(){return 1===e.currentPage},e.noNext=function(){return e.currentPage===e.numPages},e.isActive=function(t){return e.currentPage===t},e.selectPage=function(t){!e.isActive(t)&&t>0&&e.numPages>=t&&(e.currentPage=t,e.onSelectPage({page:t}))}}]).constant("paginationConfig",{boundaryLinks:!1,directionLinks:!0,firstTex
t:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["paginationConfig",function(e){return{restrict:"EA",scope:{numPages:"=",currentPage:"=",maxSize:"=",onSelectPage:"&"},controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(t,n,a){function o(e,t,n,a){return{number:e,text:t,active:n,disabled:a}}var i=angular.isDefined(a.boundaryLinks)?t.$eval(a.boundaryLinks):e.boundaryLinks,r=angular.isDefined(a.directionLinks)?t.$eval(a.directionLinks):e.directionLinks,l=angular.isDefined(a.firstText)?t.$parent.$eval(a.firstText):e.firstText,s=angular.isDefined(a.previousText)?t.$parent.$eval(a.previousText):e.previousText,c=angular.isDefined(a.nextText)?t.$parent.$eval(a.nextText):e.nextText,u=angular.isDefined(a.lastText)?t.$parent.$eval(a.lastText):e.lastText,p=angular.isDefined(a.rotate)?t.$eval(a.rotate):e.rotate;t.$watch("numPages + currentPage + maxSize",function(){t.pages=[];var e=1,n=t.
numPages,a=angular.isDefined(t.maxSize)&&t.maxSize<t.numPages;a&&(p?(e=Math.max(t.currentPage-Math.floor(t.maxSize/2),1),n=e+t.maxSize-1,n>t.numPages&&(n=t.numPages,e=n-t.maxSize+1)):(e=(Math.ceil(t.currentPage/t.maxSize)-1)*t.maxSize+1,n=Math.min(e+t.maxSize-1,t.numPages)));for(var d=e;n>=d;d++){var m=o(d,d,t.isActive(d),!1);t.pages.push(m)}if(a&&!p){if(e>1){var g=o(e-1,"...",!1,!1);t.pages.unshift(g)}if(t.numPages>n){var f=o(n+1,"...",!1,!1);t.pages.push(f)}}if(r){var h=o(t.currentPage-1,s,!1,t.noPrevious());t.pages.unshift(h);var v=o(t.currentPage+1,c,!1,t.noNext());t.pages.push(v)}if(i){var b=o(1,l,!1,t.noPrevious());t.pages.unshift(b);var $=o(t.numPages,u,!1,t.noNext());t.pages.push($)}t.currentPage>t.numPages&&t.selectPage(t.numPages)})}}}]).constant("pagerConfig",{previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(e){return{restrict:"EA",scope:{numPages:"=",currentPage:"=",onSelectPage:"&"},controller:"PaginationController",temp
lateUrl:"template/pagination/pager.html",replace:!0,link:function(t,n,a){function o(e,t,n,a,o){return{number:e,text:t,disabled:n,previous:l&&a,next:l&&o}}var i=angular.isDefined(a.previousText)?t.$parent.$eval(a.previousText):e.previousText,r=angular.isDefined(a.nextText)?t.$parent.$eval(a.nextText):e.nextText,l=angular.isDefined(a.align)?t.$parent.$eval(a.align):e.align;t.$watch("numPages + currentPage",function(){t.pages=[];var e=o(t.currentPage-1,i,t.noPrevious(),!0,!1);t.pages.unshift(e);var n=o(t.currentPage+1,r,t.noNext(),!1,!0);t.pages.push(n),t.currentPage>t.numPages&&t.selectPage(t.numPages)})}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(e,t){function n(e,n){return e.currentStyle?e.currentStyle[n]:t.getComputedStyle?t.getComputedStyle(e)[n]:e.style[n]}function a(e){return"static"===(n(e,"position")||"static")}var o,i;e.bind("mousemove",function(e){o=e.pageX,i=e.pageY});var r=function(t){for(var n=e[0],o=t.offsetParent||
n;o&&o!==n&&a(o);)o=o.offsetParent;return o||n};return{position:function(t){var n=this.offset(t),a={top:0,left:0},o=r(t[0]);return o!=e[0]&&(a=this.offset(angular.element(o)),a.top+=o.clientTop,a.left+=o.clientLeft),{width:t.prop("offsetWidth"),height:t.prop("offsetHeight"),top:n.top-a.top,left:n.left-a.left}},offset:function(n){var a=n[0].getBoundingClientRect();return{width:n.prop("offsetWidth"),height:n.prop("offsetHeight"),top:a.top+(t.pageYOffset||e[0].body.scrollTop),left:a.left+(t.pageXOffset||e[0].body.scrollLeft)}},mouse:function(){return{x:o,y:i}}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position"]).provider("$tooltip",function(){function e(e){var t=/[A-Z]/g,n="-";return e.replace(t,function(e,t){return(t?n:"")+e.toLowerCase()})}var t={placement:"top",animation:!0,popupDelay:0},n={mouseenter:"mouseleave",click:"click",focus:"blur"},a={};this.options=function(e){angular.extend(a,e)},this.setTriggers=function(e){angular.extend(n,e)},this.$get=["$window","$com
pile","$timeout","$parse","$document","$position","$interpolate",function(o,i,r,l,s,c,u){return function(o,p,d){function m(e){var t,a;return t=e||g.trigger||d,a=angular.isDefined(g.trigger)?n[g.trigger]||t:n[t]||t,{show:t,hide:a}}var g=angular.extend({},t,a),f=e(o),h=m(void 0),v=u.startSymbol(),b=u.endSymbol(),$="<"+f+"-popup "+'title="'+v+"tt_title"+b+'" '+'content="'+v+"tt_content"+b+'" '+'placement="'+v+"tt_placement"+b+'" '+'animation="tt_animation()" '+'is-open="tt_isOpen"'+">"+"</"+f+"-popup>";return{restrict:"EA",scope:!0,link:function(e,t,n){function a(){e.tt_isOpen?d():u()}function u(){e.tt_popupDelay?y=r(f,e.tt_popupDelay):e.$apply(f)}function d(){e.$apply(function(){v()})}function f(){var n,a,o,i;if(e.tt_content){switch(b&&r.cancel(b),k.css({top:0,left:0,display:"block"}),x?(w=w||s.find("body"),w.append(k)):t.after(k),n=g.appendToBody?c.offset(t):c.position(t),a=k.prop("offsetWidth"),o=k.prop("offsetHeight"),e.tt_placement){case"mouse":var l=c.mouse();i={top:l.y,left:l.x}
;break;case"right":i={top:n.top+n.height/2-o/2,left:n.left+n.width};break;case"bottom":i={top:n.top+n.height,left:n.left+n.width/2-a/2};break;case"left":i={top:n.top+n.height/2-o/2,left:n.left-a};break;default:i={top:n.top-o,left:n.left+n.width/2-a/2}}i.top+="px",i.left+="px",k.css(i),e.tt_isOpen=!0}}function v(){e.tt_isOpen=!1,r.cancel(y),angular.isDefined(e.tt_animation)&&e.tt_animation()?b=r(function(){k.remove()},500):k.remove()}var b,y,w,k=i($)(e),x=angular.isDefined(g.appendToBody)?g.appendToBody:!1;e.tt_isOpen=!1,n.$observe(o,function(t){e.tt_content=t}),n.$observe(p+"Title",function(t){e.tt_title=t}),n.$observe(p+"Placement",function(t){e.tt_placement=angular.isDefined(t)?t:g.placement}),n.$observe(p+"Animation",function(t){e.tt_animation=angular.isDefined(t)?l(t):function(){return g.animation}}),n.$observe(p+"PopupDelay",function(t){var n=parseInt(t,10);e.tt_popupDelay=isNaN(n)?g.popupDelay:n}),n.$observe(p+"Trigger",function(e){t.unbind(h.show),t.unbind(h.hide),h=m(e),h.sh
ow===h.hide?t.bind(h.show,a):(t.bind(h.show,u),t.bind(h.hide,d))}),n.$observe(p+"AppendToBody",function(t){x=angular.isDefined(t)?l(t)(e):x}),x&&e.$on("$locationChangeSuccess",function(){e.tt_isOpen&&v()}),e.$on("$destroy",function(){e.tt_isOpen?v():k.remove()})}}}}]}).directive("tooltipPopup",function(){return{restrict:"E",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(e){return e("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"E",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(e){return e("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("popoverPopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@
",content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html"}}).directive("popover",["$compile","$timeout","$parse","$window","$tooltip",function(e,t,n,a,o){return o("popover","popover","click")}]),angular.module("ui.bootstrap.progressbar",["ui.bootstrap.transition"]).constant("progressConfig",{animate:!0,autoType:!1,stackedTypes:["success","info","warning","danger"]}).controller("ProgressBarController",["$scope","$attrs","progressConfig",function(e,t,n){function a(e){return r[e]}var o=angular.isDefined(t.animate)?e.$eval(t.animate):n.animate,i=angular.isDefined(t.autoType)?e.$eval(t.autoType):n.autoType,r=angular.isDefined(t.stackedTypes)?e.$eval("["+t.stackedTypes+"]"):n.stackedTypes;this.makeBar=function(e,t,n){var r=angular.isObject(e)?e.value:e||0,l=angular.isObject(t)?t.value:t||0,s=angular.isObject(e)&&angular.isDefined(e.type)?e.type:i?a(n||0):null;return{from:l,to:r,type:s,animate:o}},this.addBar=function(t){e.bars.push(t),e.totalPercent
+=t.to},this.clearBars=function(){e.bars=[],e.totalPercent=0},this.clearBars()}]).directive("progress",function(){return{restrict:"EA",replace:!0,controller:"ProgressBarController",scope:{value:"=percent",onFull:"&",onEmpty:"&"},templateUrl:"template/progressbar/progress.html",link:function(e,t,n,a){e.$watch("value",function(e,t){if(a.clearBars(),angular.isArray(e))for(var n=0,o=e.length;o>n;n++)a.addBar(a.makeBar(e[n],t[n],n));else a.addBar(a.makeBar(e,t))},!0),e.$watch("totalPercent",function(t){t>=100?e.onFull():0>=t&&e.onEmpty()},!0)}}}).directive("progressbar",["$transition",function(e){return{restrict:"EA",replace:!0,scope:{width:"=",old:"=",type:"=",animate:"="},templateUrl:"template/progressbar/bar.html",link:function(t,n){t.$watch("width",function(a){t.animate?(n.css("width",t.old+"%"),e(n,{width:a+"%"})):n.css("width",a+"%")})}}}]),angular.module("ui.bootstrap.rating",[]).constant("ratingConfig",{max:5}).directive("rating",["ratingConfig","$parse",function(e,t){return{rest
rict:"EA",scope:{value:"="},templateUrl:"template/rating/rating.html",replace:!0,link:function(n,a,o){var i=angular.isDefined(o.max)?n.$eval(o.max):e.max;n.range=[];for(var r=1;i>=r;r++)n.range.push(r);n.rate=function(e){n.readonly||(n.value=e)},n.enter=function(e){n.readonly||(n.val=e)},n.reset=function(){n.val=angular.copy(n.value)},n.reset(),n.$watch("value",function(e){n.val=e}),n.readonly=!1,o.readonly&&n.$parent.$watch(t(o.readonly),function(e){n.readonly=!!e})}}}]),angular.module("ui.bootstrap.tabs",[]).directive("tabs",function(){return function(){throw Error("The `tabs` directive is deprecated, please migrate to `tabset`. Instructions can be found at http://github.com/angular-ui/bootstrap/tree/master/CHANGELOG.md")}}).controller("TabsetController",["$scope","$element",function(e){var t=this,n=t.tabs=e.tabs=[];t.select=function(e){angular.forEach(n,function(e){e.active=!1}),e.active=!0},t.addTab=function(e){n.push(e),1==n.length&&t.select(e)},t.removeTab=function(e){var a=n.
indexOf(e);if(e.active&&n.length>1){var o=a==n.length-1?a-1:a+1;t.select(n[o])}n.splice(a,1)}}]).directive("tabset",function(){return{restrict:"EA",transclude:!0,scope:{},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(e,t,n){e.vertical=angular.isDefined(n.vertical)?e.$eval(n.vertical):!1,e.type=angular.isDefined(n.type)?e.$parent.$eval(n.type):"tabs"}}}).directive("tab",["$parse","$http","$templateCache","$compile",function(e){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{heading:"@",onSelect:"&select"},controller:function(){},compile:function(t,n,a){return function(t,n,o,i){var r,l;t.active=!1,o.active?(r=e(o.active),l=r.assign,t.$parent.$watch(r,function(e){e&&t.disabled?l(t.$parent,!1):t.active=!!e})):l=r=angular.noop,t.$watch("active",function(e){l(t.$parent,e),e&&(i.select(t),t.onSelect())}),t.disabled=!1,o.disabled&&t.$parent.$watch(e(o.disabled),function(e){t.disabled=!!e}),t.se
lect=function(){t.disabled||(t.active=!0)},i.addTab(t),t.$on("$destroy",function(){i.removeTab(t)}),t.active&&l(t.$parent,!0),a(t.$parent,function(e){var n,a=[];angular.forEach(e,function(e){e.tagName&&(e.hasAttribute("tab-heading")||e.hasAttribute("data-tab-heading")||"tab-heading"==e.tagName.toLowerCase()||"data-tab-heading"==e.tagName.toLowerCase())?n=e:a.push(e)}),n&&(t.headingElement=angular.element(n)),t.contentElement=angular.element(a)})}}}}]).directive("tabHeadingTransclude",[function(){return{restrict:"A",require:"^tab",link:function(e,t){e.$watch("headingElement",function(e){e&&(t.html(""),t.append(e))})}}}]).directive("tabContentTransclude",["$parse",function(e){return{restrict:"A",require:"^tabset",link:function(t,n,a){t.$watch(e(a.tabContentTransclude),function(e){n.html(""),e&&n.append(e.contentElement)})}}}]),angular.module("ui.bootstrap.timepicker",[]).filter("pad",function(){return function(e){return angular.isDefined(e)&&2>(""+e).length&&(e="0"+e),e}}).constant("t
imepickerConfig",{hourStep:1,minuteStep:1,showMeridian:!0,meridians:["AM","PM"],readonlyInput:!1,mousewheel:!0}).directive("timepicker",["padFilter","$parse","timepickerConfig",function(e,t,n){return{restrict:"EA",require:"ngModel",replace:!0,templateUrl:"template/timepicker/timepicker.html",scope:{model:"=ngModel"},link:function(a,o,i){function r(){var e=parseInt(a.hours,10),t=a.showMeridian?e>0&&13>e:e>=0&&24>e;return t?(a.showMeridian&&(12===e&&(e=0),a.meridian===u[1]&&(e+=12)),e):void 0}function l(){var t=c.getHours();a.showMeridian&&(t=0===t||12===t?12:t%12),a.hours="h"===b?t:e(t),a.validHours=!0;var n=c.getMinutes();a.minutes="m"===b?n:e(n),a.validMinutes=!0,a.meridian=a.showMeridian?12>c.getHours()?u[0]:u[1]:"",b=!1}function s(e){var t=new Date(c.getTime()+6e4*e);t.getDate()!==c.getDate()&&t.setDate(t.getDate()-1),c.setTime(t.getTime()),a.model=new Date(c)}var c=new Date,u=n.meridians,p=n.hourStep;i.hourStep&&a.$parent.$watch(t(i.hourStep),function(e){p=parseInt(e,10)});var d
=n.minuteStep;i.minuteStep&&a.$parent.$watch(t(i.minuteStep),function(e){d=parseInt(e,10)}),a.showMeridian=n.showMeridian,i.showMeridian&&a.$parent.$watch(t(i.showMeridian),function(e){if(a.showMeridian=!!e,a.model)l();else{var t=new Date(c),n=r();angular.isDefined(n)&&t.setHours(n),a.model=new Date(t)}});var m=o.find("input"),g=m.eq(0),f=m.eq(1),h=angular.isDefined(i.mousewheel)?a.$eval(i.mousewheel):n.mousewheel;if(h){var v=function(e){return e.originalEvent&&(e=e.originalEvent),e.detail||e.wheelDelta>0};g.bind("mousewheel",function(e){a.$apply(v(e)?a.incrementHours():a.decrementHours()),e.preventDefault()}),f.bind("mousewheel",function(e){a.$apply(v(e)?a.incrementMinutes():a.decrementMinutes()),e.preventDefault()})}var b=!1;a.readonlyInput=angular.isDefined(i.readonlyInput)?a.$eval(i.readonlyInput):n.readonlyInput,a.readonlyInput?(a.updateHours=angular.noop,a.updateMinutes=angular.noop):(a.updateHours=function(){var e=r();angular.isDefined(e)?(b="h",null===a.model&&(a.model=new D
ate(c)),a.model.setHours(e)):(a.model=null,a.validHours=!1)},g.bind("blur",function(){a.validHours&&10>a.hours&&a.$apply(function(){a.hours=e(a.hours)
+})}),a.updateMinutes=function(){var e=parseInt(a.minutes,10);e>=0&&60>e?(b="m",null===a.model&&(a.model=new Date(c)),a.model.setMinutes(e)):(a.model=null,a.validMinutes=!1)},f.bind("blur",function(){a.validMinutes&&10>a.minutes&&a.$apply(function(){a.minutes=e(a.minutes)})})),a.$watch(function(){return+a.model},function(e){!isNaN(e)&&e>0&&(c=new Date(e),l())}),a.incrementHours=function(){s(60*p)},a.decrementHours=function(){s(60*-p)},a.incrementMinutes=function(){s(d)},a.decrementMinutes=function(){s(-d)},a.toggleMeridian=function(){s(720*(12>c.getHours()?1:-1))}}}}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position"]).factory("typeaheadParser",["$parse",function(e){var t=/^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;return{parse:function(n){var a=n.match(t);if(!a)throw Error("Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_' but got '"+n+"'.");return{itemName:a[3],source:e(a[4]),viewMapper:e
(a[2]||a[1]),modelMapper:e(a[1])}}}}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$position","typeaheadParser",function(e,t,n,a,o,i,r){var l=[9,13,27,38,40];return{require:"ngModel",link:function(s,c,u,p){var d,m=s.$eval(u.typeaheadMinLength)||1,g=s.$eval(u.typeaheadWaitMs)||0,f=r.parse(u.typeahead),h=s.$eval(u.typeaheadEditable)!==!1,v=t(u.typeaheadLoading).assign||angular.noop,b=t(u.typeaheadOnSelect),$=angular.element("<typeahead-popup></typeahead-popup>");$.attr({matches:"matches",active:"activeIdx",select:"select(activeIdx)",query:"query",position:"position"});var y=s.$new();s.$on("$destroy",function(){y.$destroy()});var w=function(){y.matches=[],y.activeIdx=-1},k=function(e){var t={$viewValue:e};v(s,!0),n.when(f.source(y,t)).then(function(n){if(e===p.$viewValue){if(n.length>0){y.activeIdx=0,y.matches.length=0;for(var a=0;n.length>a;a++)t[f.itemName]=n[a],y.matches.push({label:f.viewMapper(y,t),model:n[a]});y.query=e,y.position=i.position(c),y.posit
ion.top=y.position.top+c.prop("offsetHeight")}else w();v(s,!1)}},function(){w(),v(s,!1)})};w(),y.query=void 0,p.$parsers.push(function(e){var t;return w(),d?e:(e&&e.length>=m&&(g>0?(t&&a.cancel(t),t=a(function(){k(e)},g)):k(e)),h?e:void 0)}),p.$render=function(){var e={};e[f.itemName]=d||p.$viewValue,c.val(f.viewMapper(y,e)||p.$viewValue),d=void 0},y.select=function(e){var t,n,a={};a[f.itemName]=n=d=y.matches[e].model,t=f.modelMapper(y,a),p.$setViewValue(t),p.$render(),b(y,{$item:n,$model:t,$label:f.viewMapper(y,a)}),c[0].focus()},c.bind("keydown",function(e){0!==y.matches.length&&-1!==l.indexOf(e.which)&&(e.preventDefault(),40===e.which?(y.activeIdx=(y.activeIdx+1)%y.matches.length,y.$digest()):38===e.which?(y.activeIdx=(y.activeIdx?y.activeIdx:y.matches.length)-1,y.$digest()):13===e.which||9===e.which?y.$apply(function(){y.select(y.activeIdx)}):27===e.which&&(e.stopPropagation(),w(),y.$digest()))}),o.bind("click",function(){w(),y.$digest()}),c.after(e($)(y))}}}]).directive("typeah
eadPopup",function(){return{restrict:"E",scope:{matches:"=",query:"=",active:"=",position:"=",select:"&"},replace:!0,templateUrl:"template/typeahead/typeahead.html",link:function(e){e.isOpen=function(){return e.matches.length>0},e.isActive=function(t){return e.active==t},e.selectActive=function(t){e.active=t},e.selectMatch=function(t){e.select({activeIdx:t})}}}}).filter("typeaheadHighlight",function(){function e(e){return e.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}return function(t,n){return n?t.replace(RegExp(e(n),"gi"),"<strong>$&</strong>"):n}}),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(e){e.put("template/accordion/accordion-group.html",'<div class="accordion-group">\n <div class="accordion-heading" ><a class="accordion-toggle" ng-click="isOpen = !isOpen" accordion-transclude="heading">{{heading}}</a></div>\n <div class="accordion-body" collapse="!isOpen">\n <div class="accordion-inner" ng-transclude></div> </div>\n</div>')}
]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(e){e.put("template/accordion/accordion.html",'<div class="accordion" ng-transclude></div>')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(e){e.put("template/alert/alert.html","<div class='alert' ng-class='type && \"alert-\" + type'>\n <button ng-show='closeable' type='button' class='close' ng-click='close()'>×</button>\n <div ng-transclude></div>\n</div>\n")}]),angular.module("template/carousel/carousel.html",[]).run(["$templateCache",function(e){e.put("template/carousel/carousel.html",'<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel">\n <ol class="carousel-indicators" ng-show="slides().length > 1">\n <li ng-repeat="slide in slides()" ng-class="{active: isActive(slide)}" ng-click="select(slide)"></li>\n </ol>\n <div class="carousel-inner" ng-transclude></div>\n <a ng-click="prev()" class="carousel-control left"
ng-show="slides().length > 1">‹</a>\n <a ng-click="next()" class="carousel-control right" ng-show="slides().length > 1">›</a>\n</div>\n')}]),angular.module("template/carousel/slide.html",[]).run(["$templateCache",function(e){e.put("template/carousel/slide.html","<div ng-class=\"{\n 'active': leaving || (active && !entering),\n 'prev': (next || active) && direction=='prev',\n 'next': (next || active) && direction=='next',\n 'right': direction=='prev',\n 'left': direction=='next'\n }\" class=\"item\" ng-transclude></div>\n")}]),angular.module("template/datepicker/datepicker.html",[]).run(["$templateCache",function(e){e.put("template/datepicker/datepicker.html",'<table class="well well-large">\n <thead>\n <tr class="text-center">\n <th><button class="btn pull-left" ng-click="move(-1)"><i class="icon-chevron-left"></i></button></th>\n <th colspan="{{rows[0].length - 2 + showWeekNumbers}}"><button class="btn btn-block" ng-click="toggleMode(
)"><strong>{{title}}</strong></button></th>\n <th><button class="btn pull-right" ng-click="move(1)"><i class="icon-chevron-right"></i></button></th>\n </tr>\n <tr class="text-center" ng-show="labels.length > 0">\n <th ng-show="showWeekNumbers">#</th>\n <th ng-repeat="label in labels">{{label}}</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows">\n <td ng-show="showWeekNumbers" class="text-center"><em>{{ getWeekNumber(row) }}</em></td>\n <td ng-repeat="dt in row" class="text-center">\n <button style="width:100%;" class="btn" ng-class="{\'btn-info\': dt.isSelected}" ng-click="select(dt.date)" ng-disabled="dt.disabled"><span ng-class="{muted: ! dt.isCurrent}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/dialog/message.html",[]).run(["$templateCache",function(e){e.put("template/dialog/message.html",'<div class="modal-header">\n <h3>{{ title }}</h3>\n</div>\n<div class=
"modal-body">\n <p>{{ message }}</p>\n</div>\n<div class="modal-footer">\n <button ng-repeat="btn in buttons" ng-click="close(btn.result)" class="btn" ng-class="btn.cssClass">{{ btn.label }}</button>\n</div>\n')}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(e){e.put("template/modal/backdrop.html",'<div class="modal-backdrop"></div>')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(e){e.put("template/modal/window.html",'<div class="modal in" ng-transclude></div>')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(e){e.put("template/pagination/pager.html",'<div class="pager">\n <ul>\n <li ng-repeat="page in pages" ng-class="{disabled: page.disabled, previous: page.previous, next: page.next}"><a ng-click="selectPage(page.number)">{{page.text}}</a></li>\n </ul>\n</div>\n')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(e){e.put("tem
plate/pagination/pagination.html",'<div class="pagination"><ul>\n <li ng-repeat="page in pages" ng-class="{active: page.active, disabled: page.disabled}"><a ng-click="selectPage(page.number)">{{page.text}}</a></li>\n </ul>\n</div>\n')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(e){e.put("template/tooltip/tooltip-html-unsafe-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" ng-bind-html-unsafe="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(e){e.put("template/tooltip/tooltip-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" ng-bind="content"></div>\n</div>\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCac
he",function(e){e.put("template/popover/popover.html",'<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="arrow"></div>\n\n <div class="popover-inner">\n <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>\n <div class="popover-content" ng-bind="content"></div>\n </div>\n</div>\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(e){e.put("template/progressbar/bar.html",'<div class="bar" ng-class=\'type && "bar-" + type\'></div>')}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(e){e.put("template/progressbar/progress.html",'<div class="progress"><progressbar ng-repeat="bar in bars" width="bar.to" old="bar.from" animate="bar.animate" type="bar.type"></progressbar></div>')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(e){e.put("template/rating/rating.html",'<span ng-mouseleave="reset()">\n <i ng-repeat
="number in range" ng-mouseenter="enter(number)" ng-click="rate(number)" ng-class="{\'icon-star\': number <= val, \'icon-star-empty\': number > val}"></i>\n</span>\n')}]),angular.module("template/tabs/pane.html",[]).run(["$templateCache",function(e){e.put("template/tabs/pane.html",'<div class="tab-pane" ng-class="{active: selected}" ng-show="selected" ng-transclude></div>\n')}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(e){e.put("template/tabs/tab.html",'<li ng-class="{active: active, disabled: disabled}">\n <a ng-click="select()" tab-heading-transclude>{{heading}}</a>\n</li>\n')}]),angular.module("template/tabs/tabs.html",[]).run(["$templateCache",function(e){e.put("template/tabs/tabs.html",'<div class="tabbable">\n <ul class="nav nav-tabs">\n <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">\n <a ng-click="select(pane)">{{pane.heading}}</a>\n </li>\n </ul>\n <div class="tab-content" ng-transclude></div>\n</div>\n')}]),
angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(e){e.put("template/tabs/tabset.html",'\n<div class="tabbable">\n <ul class="nav {{type && \'nav-\' + type}}" ng-class="{\'nav-stacked\': vertical}" ng-transclude>\n </ul>\n <div class="tab-content">\n <div class="tab-pane" \n ng-repeat="tab in tabs" \n ng-class="{active: tab.active}"\n tab-content-transclude="tab" tt="tab">\n </div>\n </div>\n</div>\n')}]),angular.module("template/timepicker/timepicker.html",[]).run(["$templateCache",function(e){e.put("template/timepicker/timepicker.html",'<table class="form-inline">\n <tr class="text-center">\n <td><a ng-click="incrementHours()" class="btn btn-link"><i class="icon-chevron-up"></i></a></td>\n <td> </td>\n <td><a ng-click="incrementMinutes()" class="btn btn-link"><i class="icon-chevron-up"></i></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n <tr>\n <td class="control-group" ng-class="{\'error\': !validHours}
"><input type="text" ng-model="hours" ng-change="updateHours()" class="span1 text-center" ng-mousewheel="incrementHours()" ng-readonly="readonlyInput" maxlength="2" /></td>\n <td>:</td>\n <td class="control-group" ng-class="{\'error\': !validMinutes}"><input type="text" ng-model="minutes" ng-change="updateMinutes()" class="span1 text-center" ng-readonly="readonlyInput" maxlength="2"></td>\n <td ng-show="showMeridian"><button ng-click="toggleMeridian()" class="btn text-center">{{meridian}}</button></td>\n </tr>\n <tr class="text-center">\n <td><a ng-click="decrementHours()" class="btn btn-link"><i class="icon-chevron-down"></i></a></td>\n <td> </td>\n <td><a ng-click="decrementMinutes()" class="btn btn-link"><i class="icon-chevron-down"></i></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n</table>')}]),angular.module("template/typeahead/typeahead.html",[]).run(["$templateCache",function(e){e.put("template/typeahead/typeahead.html",'<ul class="typeahead dropdown-menu"
ng-style="{display: isOpen()&&\'block\' || \'none\', top: position.top+\'px\', left: position.left+\'px\'}">\n <li ng-repeat="match in matches" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)">\n <a tabindex="-1" ng-click="selectMatch($index)" ng-bind-html-unsafe="match.label | typeaheadHighlight:query"></a>\n </li>\n</ul>')}]);
\ No newline at end of file