azkaban-uncached
Changes
src/web/css/azkaban-svg.css 131(+131 -0)
src/web/js/azkaban.date.utils.js 3(+2 -1)
src/web/js/azkaban.schedule.panel.view.js 129(+68 -61)
src/web/js/bootstrap-datetimepicker.min.js 28(+28 -0)
Details
diff --git a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
index e0b5bf9..f5b0d4e 100644
--- a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
@@ -105,6 +105,8 @@
<div class="panel-footer">
#if (${exec})
<button type="button" class="btn btn-primary execute-flow" flowId="${flow.id}">Execute Flow</button>
+ <button type="button" class="btn btn-primary">Executions</button>
+ <button type="button" class="btn btn-primary">Summary</button>
#end
</div>
</div>
diff --git a/src/java/azkaban/webapp/servlet/velocity/schedulepanel.vm b/src/java/azkaban/webapp/servlet/velocity/schedulepanel.vm
index 1f54c5d..b3a72b4 100644
--- a/src/java/azkaban/webapp/servlet/velocity/schedulepanel.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/schedulepanel.vm
@@ -14,52 +14,72 @@
* the License.
*#
-<script type="text/javascript" src="${context}/js/azkaban.date.utils.js"></script>
-<script type="text/javascript" src="${context}/js/azkaban.schedule.panel.view.js"></script>
-
-<div id="scheduleModalBackground" class="modalBackground3">
- <div id="schedule-panel-top">
- <div id="schedule-panel" class="modal">
- <a href='#' title='Close' class='modal-close closeSchedule'>x</a>
- <h3>Schedule Flow Options</h3>
-
- <div id="scheduleInfo">
- <dl>
- <dt>Schedule Time</dt>
- <dd>
- <input id="hour" type="text" size="2" value="12"/>
- <input id="minutes" type="text" size="2" value="00"/>
- <select id="am_pm">
- <option>pm</option>
- <option>am</option>
- </select>
- <select id="timezone">
- <option>${timezone}</option>
- <option>UTC</option>
- </select>
- </dd>
- <dt>Schedule Date</dt><dd><input type="text" id="datepicker" /></dd>
- <dt>Recurrence</dt>
- <dd>
- <input id="is_recurring" type="checkbox" checked />
- <span>repeat every</span>
- <input id="period" type="text" size="2" value="1"/>
- <select id="period_units">
- <option value="d">Days</option>
- <option value="h">Hours</option>
- <option value="m">Minutes</option>
- <option value="M">Months</option>
- <option value="w">Weeks</option>
- </select>
- </dd>
- </dl>
- </div>
-
-
- <div class="actions">
- <a class="yes btn1" id="schedule-button" href="#">Schedule</a>
- <a class="no simplemodal-close btn3 closeSchedule" id="cancel-schedule-btn" href="#">Cancel</a>
+ <script type="text/javascript" src="${context}/js/azkaban.date.utils.js"></script>
+ <script type="text/javascript" src="${context}/js/azkaban.schedule.panel.view.js"></script>
+
+ <div class="modal fade" id="schedule-modal">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h4 class="modal-title">Schedule Flow Options</h4>
+ </div><!-- /modal-header -->
+ <div class="modal-body">
+ <fieldset>
+ <div class="form-group">
+ <label>Schedule Time</label>
+ <div class="form-inline">
+ <div class="form-group">
+ <input id="hour" type="text" size="2" value="12" class="form-control">
+ </div>
+ <div class="form-group">
+ <input id="minutes" type="text" size="2" value="00" class="form-control">
+ </div>
+ <div class="form-group">
+ <select id="am_pm" class="form-control">
+ <option>pm</option>
+ <option>am</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <select id="timezone" class="form-control">
+ <option>${timezone}</option>
+ <option>UTC</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="form-group">
+ <label>Schedule Date</label>
+ <input type="text" id="datepicker" class="form-control">
+ </div>
+ <div class="form-group">
+ <label>Recurrence</label>
+ <div class="form-inline">
+ <div class="checkbox">
+ <input id="is_recurring" type="checkbox" checked="checked">
+ <label>repeat every</label>
+ </div>
+ <div class="form-group">
+ <input id="period" type="text" size="2" value="1" class="form-control">
+ </div>
+ <div class="form-group">
+ <select id="period_units" class="form-control">
+ <option value="d">Days</option>
+ <option value="h">Hours</option>
+ <option value="m">Minutes</option>
+ <option value="M">Months</option>
+ <option value="w">Weeks</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+ <button type="button" class="btn btn-primary" id="schedule-button">Schedule</button>
+ </div>
+ </div>
+ </div>
</div>
- </div>
- </div>
-</div>
src/web/css/azkaban-svg.css 131(+131 -0)
diff --git a/src/web/css/azkaban-svg.css b/src/web/css/azkaban-svg.css
new file mode 100644
index 0000000..78a4625
--- /dev/null
+++ b/src/web/css/azkaban-svg.css
@@ -0,0 +1,131 @@
+svg .edge {
+ stroke: #777;
+ stroke-width: 2;
+}
+
+svg .edge:hover {
+ stroke: #009FC9;
+ stroke-width: 4;
+}
+
+svg .node.disabled {
+ opacity: 0.3;
+}
+
+svg .node .backboard {
+ fill: #FFF;
+ opacity: 0.05;
+}
+
+svg .node:hover {
+ cursor: pointer;
+}
+
+svg .node:hover .backboard {
+ opacity: 0.7;
+}
+
+svg .selected .backboard {
+ opacity: 0.4;
+}
+
+svg .node circle {
+ fill: #888;
+ stroke: #777;
+ stroke-width: 2;
+}
+
+svg .node:hover circle {
+ stroke: #009FC9;
+}
+
+svg .node:hover text {
+ fill: #009FC9;
+}
+
+svg .selected text {
+ fill: #338AB0;
+}
+
+svg .selected circle {
+ stroke: #009FC9;
+ stroke-width: 4;
+}
+
+svg .READY circle {
+ fill: #CCC;
+}
+
+svg .RUNNING circle {
+ fill: #009FC9;
+}
+
+svg .QUEUED circle {
+ opacity: 0.5;
+ fill: #009FC9;
+}
+
+svg .FAILED circle {
+ fill: #CC0000;
+}
+
+svg .KILLED circle {
+ fill: #CC0000;
+}
+
+svg .SUCCEEDED circle {
+ fill: #00CC33;
+}
+
+svg .DISABLED circle {
+ opacity: 0.3;
+}
+
+svg .SKIPPED circle {
+ opacity: 0.3;
+}
+
+#Used for charts
+svg circle.READY {
+ stroke: #CCC;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.RUNNING {
+ stroke: #009FC9;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.FAILED {
+ stroke: #CC0000;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.KILLED {
+ stroke: #CC0000;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.SUCCEEDED {
+ stroke: #00CC33;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.DISABLED {
+ stroke: #CCC;
+ opacity: 0.3;
+ stroke-width: 2px;
+ fill: #FFF;
+}
+
+svg circle.SKIPPED {
+ stroke: #CCC;
+ opacity: 0.3;
+ stroke-width: 2px;
+ fill: #FFF;
+}
diff --git a/src/web/css/bootstrap-datetimepicker.min.css b/src/web/css/bootstrap-datetimepicker.min.css
new file mode 100644
index 0000000..ed45378
--- /dev/null
+++ b/src/web/css/bootstrap-datetimepicker.min.css
@@ -0,0 +1,9 @@
+/*!
+ * Datepicker for Bootstrap v3
+ *
+ * Copyright 2012 Stefan Petre
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+ .bootstrap-datetimepicker-widget{top:0;left:0;z-index:9999;width:250px;padding:4px;margin-top:1px;border-radius:4px}.bootstrap-datetimepicker-widget .btn{padding:6px}.bootstrap-datetimepicker-widget:before{position:absolute;top:-7px;left:6px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.bootstrap-datetimepicker-widget:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid white;border-left:6px solid transparent;content:''}.bootstrap-datetimepicker-widget.pull-right:before{right:6px;left:auto}.bootstrap-datetimepicker-widget.pull-right:after{right:7px;left:auto}.bootstrap-datetimepicker-widget>ul{margin:0;list-style-type:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:100%;font-size:1.2em;font-weight:bold}.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator{width:4px;padding:0;margin:0}.bootstrap-datetimepicker-widget .datepicker>div{display:none}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget td,.bootstrap-datetimepicker-widget th{width:20px;height:20px;text-align:center;border-radius:4px}.bootstrap-datetimepicker-widget td.day:hover,.bootstrap-datetimepicker-widget td.hour:hover,.bootstrap-datetimepicker-widget td.minute:hover,.bootstrap-datetimepicker-widget td.second:hover{cursor:pointer;background:#eee}.bootstrap-datetimepicker-widget td.old,.bootstrap-datetimepicker-widget td.new{color:#999}.bootstrap-datetimepicker-widget td.active,.bootstrap-datetimepicker-widget td.active:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#428bca}.bootstrap-datetimepicker-widget td.disabled,.bootstrap-datetimepicker-widget td.disabled:hover{color:#999;cursor:not-allowed;background:0}.bootstrap-datetimepicker-widget td span{display:block;float:left;width:47px;height:54px;margin:2px;line-height:54px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget td span:hover{background:#eee}.bootstrap-datetimepicker-widget td span.active{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#428bca}.bootstrap-datetimepicker-widget td span.old{color:#999}.bootstrap-datetimepicker-widget td span.disabled,.bootstrap-datetimepicker-widget td span.disabled:hover{color:#999;cursor:not-allowed;background:0}.bootstrap-datetimepicker-widget th.switch{width:145px}.bootstrap-datetimepicker-widget th.next,.bootstrap-datetimepicker-widget th.prev{font-size:21px}.bootstrap-datetimepicker-widget th.disabled,.bootstrap-datetimepicker-widget th.disabled:hover{color:#999;cursor:not-allowed;background:0}.bootstrap-datetimepicker-widget thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget thead tr:first-child th:hover{background:#eee}.input-group.date .input-group-addon span{display:block;width:16px;height:16px;cursor:pointer}.bootstrap-datetimepicker-widget.left-oriented:before{right:6px;left:auto}.bootstrap-datetimepicker-widget.left-oriented:after{right:7px;left:auto}.bootstrap-datetimepicker-widget ul.list-unstyled li.in div.timepicker div.timepicker-picker table.table-condensed tbody>tr>td{padding:0!important}
\ No newline at end of file
src/web/js/azkaban.date.utils.js 3(+2 -1)
diff --git a/src/web/js/azkaban.date.utils.js b/src/web/js/azkaban.date.utils.js
index ce90f7b..a65ec50 100644
--- a/src/web/js/azkaban.date.utils.js
+++ b/src/web/js/azkaban.date.utils.js
@@ -67,7 +67,8 @@ var getDateFormat = function(date) {
var minutes = getTwoDigitStr(date.getMinutes());
var second = getTwoDigitStr(date.getSeconds());
- var datestring = year + "-" + month + "-" + day + " " + hours + ":" + minutes + " " + second + "s";
+ var datestring = year + "-" + month + "-" + day + " " + hours + ":" +
+ minutes + " " + second + "s";
return datestring;
}
diff --git a/src/web/js/azkaban.flow.execute.view.js b/src/web/js/azkaban.flow.execute.view.js
index 3fe3104..a74f473 100644
--- a/src/web/js/azkaban.flow.execute.view.js
+++ b/src/web/js/azkaban.flow.execute.view.js
@@ -279,6 +279,8 @@ azkaban.FlowExecuteDialogView = Backbone.View.extend({
},
scheduleClick: function() {
+ console.log("click schedule button.");
+ this.hideExecutionOptionPanel();
schedulePanelView.showSchedulePanel();
},
@@ -293,6 +295,7 @@ azkaban.FlowExecuteDialogView = Backbone.View.extend({
},
handleExecuteFlow: function(evt) {
+ console.log("click schedule button.");
var executeURL = contextURL + "/executor";
var executingData = this.getExecutionOptionData();
executeFlow(executingData);
src/web/js/azkaban.schedule.panel.view.js 129(+68 -61)
diff --git a/src/web/js/azkaban.schedule.panel.view.js b/src/web/js/azkaban.schedule.panel.view.js
index 1d85736..2e26845 100644
--- a/src/web/js/azkaban.schedule.panel.view.js
+++ b/src/web/js/azkaban.schedule.panel.view.js
@@ -17,73 +17,80 @@
$.namespace('azkaban');
var schedulePanelView;
-azkaban.SchedulePanelView= Backbone.View.extend({
- events : {
- "click .closeSchedule": "hideSchedulePanel",
- "click #schedule-button": "scheduleFlow"
- },
- initialize : function(settings) {
- $("#datepicker").css("backgroundColor", "transparent");
- $( "#datepicker" ).datepicker();
- $( "#datepicker" ).datepicker('setDate', new Date());
- $( "#datepicker" ).datepicker("hide");
- },
- render: function() {
- },
- showSchedulePanel: function() {
- $('#scheduleModalBackground').show();
- $('#schedule-panel').show();
- },
- hideSchedulePanel: function() {
- $('#scheduleModalBackground').hide();
- $('#schedule-panel').hide();
- },
- scheduleFlow: function() {
- var hourVal = $('#hour').val();
- var minutesVal = $('#minutes').val();
- var ampmVal = $('#am_pm').val();
- var timezoneVal = $('#timezone').val();
- var dateVal = $('#datepicker').val();
- var is_recurringVal = $('#is_recurring').val();
- var periodVal = $('#period').val();
- var periodUnits = $('#period_units').val();
-
- var scheduleURL = contextURL + "/schedule"
-
- var scheduleData = flowExecuteDialogView.getExecutionOptionData();
- console.log("Creating schedule for "+projectName+"."+scheduleData.flow);
- var scheduleTime = $('#hour').val() + "," + $('#minutes').val() + "," + $('#am_pm').val() + "," + $('#timezone').val();
- var scheduleDate = $('#datepicker').val();
- var is_recurring = document.getElementById('is_recurring').checked ? 'on' : 'off';
- var period = $('#period').val() + $('#period_units').val();
+azkaban.SchedulePanelView = Backbone.View.extend({
+ events: {
+ "click #schedule-button": "scheduleFlow"
+ },
+
+ initialize: function(settings) {
+ $("#datepicker").css("backgroundColor", "transparent");
+ $("#datepicker").datepicker();
+ $("#datepicker").datepicker('setDate', new Date());
+ $("#datepicker").datepicker("hide");
+ },
+
+ render: function() {
+ },
+
+ showSchedulePanel: function() {
+ $('#schedule-modal').modal();
+ },
- scheduleData.ajax = "scheduleFlow";
- scheduleData.projectName = projectName;
- scheduleData.scheduleTime = scheduleTime;
- scheduleData.scheduleDate = scheduleDate;
- scheduleData.is_recurring = is_recurring;
- scheduleData.period = period;
+ hideSchedulePanel: function() {
+ $('#schedule-modal').modal("hide");
+ },
+
+ scheduleFlow: function() {
+ var hourVal = $('#hour').val();
+ var minutesVal = $('#minutes').val();
+ var ampmVal = $('#am_pm').val();
+ var timezoneVal = $('#timezone').val();
+ var dateVal = $('#datepicker').val();
+ var is_recurringVal = $('#is_recurring').val();
+ var periodVal = $('#period').val();
+ var periodUnits = $('#period_units').val();
+
+ var scheduleURL = contextURL + "/schedule"
+ var scheduleData = flowExecuteDialogView.getExecutionOptionData();
- $.post(
- scheduleURL,
- scheduleData,
- function(data) {
- if (data.error) {
- messageDialogView.show("Error Scheduling Flow", data.message);
- }
- else {
- messageDialogView.show("Flow Scheduled", data.message,
+ console.log("Creating schedule for " + projectName + "." +
+ scheduleData.flow);
+
+ var scheduleTime = $('#hour').val() + "," + $('#minutes').val() + "," +
+ $('#am_pm').val() + "," + $('#timezone').val();
+ var scheduleDate = $('#datepicker').val();
+ var is_recurring = document.getElementById('is_recurring').checked
+ ? 'on' : 'off';
+ var period = $('#period').val() + $('#period_units').val();
+
+ scheduleData.ajax = "scheduleFlow";
+ scheduleData.projectName = projectName;
+ scheduleData.scheduleTime = scheduleTime;
+ scheduleData.scheduleDate = scheduleDate;
+ scheduleData.is_recurring = is_recurring;
+ scheduleData.period = period;
+
+ var successHandler = function(data) {
+ if (data.error) {
+ schedulePanelView.hideSchedulePanel();
+ messageDialogView.show("Error Scheduling Flow", data.message);
+ }
+ else {
+ schedulePanelView.hideSchedulePanel();
+ messageDialogView.show("Flow Scheduled", data.message,
function() {
window.location.href = scheduleURL;
}
- );
- }
- },
- "json"
- );
- }
+ );
+ }
+ };
+
+ $.post(scheduleURL, scheduleData, successHandler, "json");
+ }
});
$(function() {
- schedulePanelView = new azkaban.SchedulePanelView({el:$('#scheduleModalBackground')});
+ schedulePanelView = new azkaban.SchedulePanelView({
+ el: $('#schedule-modal')
+ });
});
src/web/js/bootstrap-datetimepicker.min.js 28(+28 -0)
diff --git a/src/web/js/bootstrap-datetimepicker.min.js b/src/web/js/bootstrap-datetimepicker.min.js
new file mode 100644
index 0000000..12d186f
--- /dev/null
+++ b/src/web/js/bootstrap-datetimepicker.min.js
@@ -0,0 +1,28 @@
+/**
+ * version 2.1.11
+ * @license
+ * =========================================================
+ * bootstrap-datetimepicker.js
+ * http://www.eyecon.ro/bootstrap-datepicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Contributions:
+ * - updated for Bootstrap v3 by Jonathan Peterson (@Eonasdan) and (almost)
+ * completely rewritten to use Momentjs
+ * - based on tarruda's bootstrap-datepicker
+ *
+ * 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(d){if(typeof moment==="undefined"){alert("momentjs is requried");throw new Error("momentjs is requried")}var c=0,a=moment,b=function(g,i){var s={pickDate:true,pickTime:true,startDate:new a({y:1970}),endDate:new a().add(50,"y"),collapse:true,language:"en",defaultDate:"",disabledDates:[],icons:{},useStrict:false},K={time:"glyphicon glyphicon-time",date:"glyphicon glyphicon-calendar",up:"glyphicon glyphicon-chevron-up",down:"glyphicon glyphicon-chevron-down"},q=this,E=function(){var O=false,N,P,M;q.options=d.extend({},s,i);q.options.icons=d.extend({},K,q.options.icons);if(!(q.options.pickTime||q.options.pickDate)){throw new Error("Must choose at least one picker")}q.id=c++;a.lang(q.options.language);q.date=a();q.element=d(g);q.unset=false;q.isInput=q.element.is("input");q.component=false;if(q.element.hasClass("input-group")){if(q.element.find(".datepickerbutton").size()==0){q.component=q.element.find(".input-group-addon")}else{q.component=q.element.find(".datepickerbutton")}}q.format=q.options.format;M=a()._lang._longDateFormat;if(!q.format){if(q.isInput){q.format=q.element.data("format")}else{q.format=q.element.find("input").data("format")}if(!q.format){q.format=(q.options.pickDate?M.L:"");if(q.options.pickDate&&q.options.pickTime){q.format+=" "}q.format+=(q.options.pickTime?M.LT:"")}}q.use24hours=q.format.toLowerCase().indexOf("a")<1;if(q.component){O=q.component.find("span")}if(q.options.pickTime){if(O){O.addClass(q.options.icons.time)}}if(q.options.pickDate){if(O){O.removeClass(q.options.icons.time);O.addClass(q.options.icons.date)}}q.widget=d(I(q.options.pickDate,q.options.pickTime,q.options.collapse)).appendTo("body");q.minViewMode=q.options.minViewMode||q.element.data("date-minviewmode")||0;if(typeof q.minViewMode==="string"){switch(q.minViewMode){case"months":q.minViewMode=1;break;case"years":q.minViewMode=2;break;default:q.minViewMode=0;break}}q.viewMode=q.options.viewMode||q.element.data("date-viewmode")||0;if(typeof q.viewMode==="string"){switch(q.viewMode){case"months":q.viewMode=1;break;case"years":q.viewMode=2;break;default:q.viewMode=0;break}}for(N=0;N<q.options.disabledDates.length;N++){P=q.options.disabledDates[N];P=a(P);if(!P.isValid()){P=a(q.options.startDate).subtract(1,"day")}q.options.disabledDates[N]=P.format("L")}q.startViewMode=q.viewMode;q.setStartDate(q.options.startDate||q.element.data("date-startdate"));q.setEndDate(q.options.endDate||q.element.data("date-enddate"));H();L();l();C();n();f();J();if(q.options.defaultDate!==""){q.setValue(q.options.defaultDate)}},o=function(){var M="absolute",O=q.component?q.component.offset():q.element.offset(),N=d(window);q.width=q.component?q.component.outerWidth():q.element.outerWidth();O.top=O.top+q.element.outerHeight();if(q.options.width!==undefined){q.widget.width(q.options.width)}if(q.options.orientation==="left"){q.widget.addClass("left-oriented");O.left=O.left-q.widget.width()+20}if(A()){M="fixed";O.top-=N.scrollTop();O.left-=N.scrollLeft()}if(N.width()<O.left+q.widget.outerWidth()){O.right=N.width()-O.left-q.width;O.left="auto";q.widget.addClass("pull-right")}else{O.right="auto";q.widget.removeClass("pull-right")}q.widget.css({position:M,top:O.top,left:O.left,right:O.right})},z=function(M){q.element.trigger({type:"change.dp",date:q.getDate(),oldDate:M})},w=function(M){q.element.trigger({type:"error.dp",date:M})},n=function(M){a.lang(q.options.language);var N=M;if(!N){if(q.isInput){N=q.element.val()}else{N=q.element.find("input").val()}if(N){q.date=a(N,q.format,q.options.useStrict)}if(!q.date){q.date=a()}}q.viewDate=a(q.date).startOf("month");h();y()},H=function(){a.lang(q.options.language);var O=d("<tr>"),M=a.weekdaysMin(),N;if(a()._lang._week.dow==0){for(N=0;N<7;N++){O.append('<th class="dow">'+M[N]+"</th>")}}else{for(N=1;N<8;N++){if(N==7){O.append('<th class="dow">'+M[0]+"</th>")}else{O.append('<th class="dow">'+M[N]+"</th>")}}}q.widget.find(".datepicker-days thead").append(O)},L=function(){a.lang(q.options.language);var N="",M=0,O=a.monthsShort();while(M<12){N+='<span class="month">'+O[M++]+"</span>"}q.widget.find(".datepicker-months td").append(N)},h=function(){a.lang(q.options.language);var X=q.viewDate.year(),V=q.viewDate.month(),W=q.options.startDate.year(),Z=q.options.startDate.month(),aa=q.options.endDate.year(),T=q.options.endDate.month(),P,S,R=[],ab,O,Q,Y,N,U,M=a.months();q.widget.find(".datepicker-days").find(".disabled").removeClass("disabled");q.widget.find(".datepicker-months").find(".disabled").removeClass("disabled");q.widget.find(".datepicker-years").find(".disabled").removeClass("disabled");q.widget.find(".datepicker-days th:eq(1)").text(M[V]+" "+X);P=a(q.viewDate).subtract("months",1);Y=P.daysInMonth();P.date(Y).startOf("week");if((X==W&&V<=Z)||X<W){q.widget.find(".datepicker-days th:eq(0)").addClass("disabled")}if((X==aa&&V>=T)||X>aa){q.widget.find(".datepicker-days th:eq(2)").addClass("disabled")}S=a(P).add(42,"d");while(P.isBefore(S)){if(P.weekday()===a().startOf("week").weekday()){ab=d("<tr>");R.push(ab)}O="";if(P.year()<X||(P.year()==X&&P.month()<V)){O+=" old"}else{if(P.year()>X||(P.year()==X&&P.month()>V)){O+=" new"}}if(P.isSame(a({y:q.date.year(),M:q.date.month(),d:q.date.date()}))){O+=" active"}if((a(P).add(1,"d")<=q.options.startDate)||(P>q.options.endDate)||e(P)){O+=" disabled"}ab.append('<td class="day'+O+'">'+P.date()+"</td>");P.add(1,"d")}q.widget.find(".datepicker-days tbody").empty().append(R);U=a().year(),M=q.widget.find(".datepicker-months").find("th:eq(1)").text(X).end().find("span").removeClass("active");if(U===X){M.eq(a().month()).addClass("active")}if(U-1<W){q.widget.find(".datepicker-months th:eq(0)").addClass("disabled")}if(U+1>aa){q.widget.find(".datepicker-months th:eq(2)").addClass("disabled")}for(Q=0;Q<12;Q++){if((X==W&&Z>Q)||(X<W)){d(M[Q]).addClass("disabled")}else{if((X==aa&&T<Q)||(X>aa)){d(M[Q]).addClass("disabled")}}}R="";X=parseInt(X/10,10)*10;N=q.widget.find(".datepicker-years").find("th:eq(1)").text(X+"-"+(X+9)).end().find("td");q.widget.find(".datepicker-years").find("th").removeClass("disabled");if(W>X){q.widget.find(".datepicker-years").find("th:eq(0)").addClass("disabled")}if(aa<X+9){q.widget.find(".datepicker-years").find("th:eq(2)").addClass("disabled")}X-=1;for(Q=-1;Q<11;Q++){R+='<span class="year'+(Q===-1||Q===10?" old":"")+(U===X?" active":"")+((X<W||X>aa)?" disabled":"")+'">'+X+"</span>";X+=1}N.html(R)},l=function(){a.lang(q.options.language);var P=q.widget.find(".timepicker .timepicker-hours table"),O="",Q,N,M;P.parent().hide();if(q.use24hours){Q=0;for(N=0;N<6;N+=1){O+="<tr>";for(M=0;M<4;M+=1){O+='<td class="hour">'+D(Q.toString())+"</td>";Q++}O+="</tr>"}}else{Q=1;for(N=0;N<3;N+=1){O+="<tr>";for(M=0;M<4;M+=1){O+='<td class="hour">'+D(Q.toString())+"</td>";Q++}O+="</tr>"}}P.html(O)},C=function(){var P=q.widget.find(".timepicker .timepicker-minutes table"),O="",Q=0,N,M;P.parent().hide();for(N=0;N<5;N++){O+="<tr>";for(M=0;M<4;M+=1){O+='<td class="minute">'+D(Q.toString())+"</td>";Q+=3}O+="</tr>"}P.html(O)},y=function(){if(!q.date){return}var O=q.widget.find(".timepicker span[data-time-component]"),M=q.date.hours(),N="AM";if(!q.use24hours){if(M>=12){N="PM"}if(M===0){M=12}else{if(M!=12){M=M%12}}q.widget.find(".timepicker [data-action=togglePeriod]").text(N)}O.filter("[data-time-component=hours]").text(D(M));O.filter("[data-time-component=minutes]").text(D(q.date.minutes()))},B=function(S){S.stopPropagation();S.preventDefault();q.unset=false;var R=d(S.target).closest("span, td, th"),Q,O,P,M,N=q.date;if(R.length===1){if(!R.is(".disabled")){switch(R[0].nodeName.toLowerCase()){case"th":switch(R[0].className){case"switch":f(1);break;case"prev":case"next":P=G.modes[q.viewMode].navStep;if(R[0].className==="prev"){P=P*-1}q.viewDate.add(P,G.modes[q.viewMode].navFnc);h();break}break;case"span":if(R.is(".month")){Q=R.parent().find("span").index(R);q.viewDate.month(Q)}else{O=parseInt(R.text(),10)||0;q.viewDate.year(O)}if(q.viewMode!==0){q.date=a({y:q.viewDate.year(),M:q.viewDate.month(),d:q.viewDate.date(),h:q.date.hours(),m:q.date.minutes()});z(N)}f(-1);h();break;case"td":if(R.is(".day")){M=parseInt(R.text(),10)||1;Q=q.viewDate.month();O=q.viewDate.year();if(R.is(".old")){if(Q===0){Q=11;O-=1}else{Q-=1}}else{if(R.is(".new")){if(Q==11){Q=0;O+=1}else{Q+=1}}}q.date=a({y:O,M:Q,d:M,h:q.date.hours(),m:q.date.minutes()});q.viewDate=a({y:O,M:Q,d:Math.min(28,M)});h();x();z(N)}break}}}},r={incrementHours:function(){j("add","hours")},incrementMinutes:function(){j("add","minutes")},decrementHours:function(){j("subtract","hours")},decrementMinutes:function(){j("subtract","minutes")},togglePeriod:function(){var M=q.date.hours();if(M>=12){M-=12}else{M+=12}q.date.hours(M)},showPicker:function(){q.widget.find(".timepicker > div:not(.timepicker-picker)").hide();q.widget.find(".timepicker .timepicker-picker").show()},showHours:function(){q.widget.find(".timepicker .timepicker-picker").hide();q.widget.find(".timepicker .timepicker-hours").show()},showMinutes:function(){q.widget.find(".timepicker .timepicker-picker").hide();q.widget.find(".timepicker .timepicker-minutes").show()},selectHour:function(M){q.date.hours(parseInt(d(M.target).text(),10));r.showPicker.call(q)},selectMinute:function(M){q.date.minutes(parseInt(d(M.target).text(),10));r.showPicker.call(q)}},v=function(O){var N=d(O.currentTarget).data("action"),P=r[N].apply(q,arguments),M=q.date;F(O);if(!q.date){q.date=a({y:1970})}x();y();z(M);return P},F=function(M){M.stopPropagation();M.preventDefault()},u=function(O){a.lang(q.options.language);var M=d(O.target),N=q.date,P=a(M.val(),q.format,q.options.useStrict);if(P.isValid()){n();q.setValue(P);z(N);x()}else{q.viewDate=N;z(N);w(P);q.unset=true;M.val("")}},f=function(M){if(M){q.viewMode=Math.max(q.minViewMode,Math.min(2,q.viewMode+M))}q.widget.find(".datepicker > div").hide().filter(".datepicker-"+G.modes[q.viewMode].clsName).show()},J=function(){var Q,P,N,M,O;q.widget.on("click",".datepicker *",d.proxy(B,this));q.widget.on("click","[data-action]",d.proxy(v,this));q.widget.on("mousedown",d.proxy(F,this));if(q.options.pickDate&&q.options.pickTime){q.widget.on("click.togglePicker",".accordion-toggle",function(R){R.stopPropagation();Q=d(this);P=Q.closest("ul");N=P.find(".in");M=P.find(".collapse:not(.in)");if(N&&N.length){O=N.data("collapse");if(O&&O.transitioning){return}N.collapse("hide");M.collapse("show");Q.find("span").toggleClass(q.options.icons.time+" "+q.options.icons.date);q.element.find(".input-group-addon span").toggleClass(q.options.icons.time+" "+q.options.icons.date)}})}if(q.isInput){q.element.on({focus:d.proxy(q.show,this),change:d.proxy(u,this),blur:d.proxy(q.hide,this)})}else{q.element.on({change:d.proxy(u,this)},"input");if(q.component){q.component.on("click",d.proxy(q.show,this))}else{q.element.on("click",d.proxy(q.show,this))}}},p=function(){d(window).on("resize.datetimepicker"+q.id,d.proxy(o,this));if(!q.isInput){d(document).on("mousedown.datetimepicker"+q.id,d.proxy(q.hide,this))}},t=function(){q.widget.off("click",".datepicker *",q.click);q.widget.off("click","[data-action]");q.widget.off("mousedown",q.stopEvent);if(q.options.pickDate&&q.options.pickTime){q.widget.off("click.togglePicker")}if(q.isInput){q.element.off({focus:q.show,change:q.change})}else{q.element.off({change:q.change},"input");if(q.component){q.component.off("click",q.show)}else{q.element.off("click",q.show)}}},k=function(){d(window).off("resize.datetimepicker"+q.id);if(!q.isInput){d(document).off("mousedown.datetimepicker"+q.id)}},A=function(){if(q.element){var N=q.element.parents(),M=false,O;for(O=0;O<N.length;O++){if(d(N[O]).css("position")=="fixed"){M=true;break}}return M}else{return false}},x=function(){a.lang(q.options.language);var N="",M;if(!q.unset){N=a(q.date).format(q.format)}if(!q.isInput){if(q.component){M=q.element.find("input");M.val(N)}q.element.data("date",N)}else{q.element.val(N)}if(!q.options.pickTime){q.hide()}},j=function(O,N){a.lang(q.options.language);var M;if(O=="add"){M=a(q.date);if(M.hours()==23){M.add(1,N)}M.add(1,N)}else{M=a(q.date).subtract(1,N)}if(M.isAfter(q.options.endDate)||M.subtract(1,N).isBefore(q.options.startDate)||e(M)){w(M.format(q.format));return}if(O=="add"){q.date.add(1,N)}else{q.date.subtract(1,N)}},e=function(M){a.lang(q.options.language);var O=q.options.disabledDates,N;for(N in O){if(O[N]==a(M).format("L")){return true}}return false},D=function(M){M=M.toString();if(M.length>=2){return M}else{return"0"+M}},I=function(N,M,O){if(N&&M){return('<div class="bootstrap-datetimepicker-widget dropdown-menu" style="z-index:9999 !important;"><ul class="list-unstyled"><li'+(O?' class="collapse in"':"")+'><div class="datepicker">'+G.template+'</div></li><li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="'+q.options.icons.time+'"></span></a></li><li'+(O?' class="collapse"':"")+'><div class="timepicker">'+m.getTemplate()+"</div></li></ul></div>")}else{if(M){return('<div class="bootstrap-datetimepicker-widget dropdown-menu"><div class="timepicker">'+m.getTemplate()+"</div></div>")}else{return('<div class="bootstrap-datetimepicker-widget dropdown-menu"><div class="datepicker">'+G.template+"</div></div>")}}},G={modes:[{clsName:"days",navFnc:"month",navStep:1},{clsName:"months",navFnc:"year",navStep:1},{clsName:"years",navFnc:"year",navStep:10}],headTemplate:'<thead><tr><th class="prev">‹</th><th colspan="5" class="switch"></th><th class="next">›</th></tr></thead>',contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>'},m={hourTemplate:'<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',minuteTemplate:'<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>'};G.template='<div class="datepicker-days"><table class="table-condensed">'+G.headTemplate+'<tbody></tbody></table></div><div class="datepicker-months"><table class="table-condensed">'+G.headTemplate+G.contTemplate+'</table></div><div class="datepicker-years"><table class="table-condensed">'+G.headTemplate+G.contTemplate+"</table></div>";m.getTemplate=function(){return('<div class="timepicker-picker"><table class="table-condensed"><tr><td><a href="#" class="btn" data-action="incrementHours"><span class="'+q.options.icons.up+'"></span></a></td><td class="separator"></td><td><a href="#" class="btn" data-action="incrementMinutes"><span class="'+q.options.icons.up+'"></span></a></td>'+(!q.use24hours?'<td class="separator"></td>':"")+"</tr><tr><td>"+m.hourTemplate+'</td> <td class="separator">:</td><td>'+m.minuteTemplate+"</td> "+(!q.use24hours?'<td class="separator"></td><td><button type="button" class="btn btn-primary" data-action="togglePeriod"></button></td>':"")+'</tr><tr><td><a href="#" class="btn" data-action="decrementHours"><span class="'+q.options.icons.down+'"></span></a></td><td class="separator"></td><td><a href="#" class="btn" data-action="decrementMinutes"><span class="'+q.options.icons.down+'"></span></a></td>'+(!q.use24hours?'<td class="separator"></td>':"")+'</tr></table></div><div class="timepicker-hours" data-action="selectHour"><table class="table-condensed"></table></div><div class="timepicker-minutes" data-action="selectMinute"><table class="table-condensed"></table></div>')};q.destroy=function(){t();k();q.widget.remove();q.element.removeData("DateTimePicker");q.component.removeData("DateTimePicker")};q.show=function(M){q.widget.show();q.height=q.component?q.component.outerHeight():q.element.outerHeight();o();q.element.trigger({type:"show.dp",date:q.date});p();if(M){F(M)}},q.disable=function(){q.element.find("input").prop("disabled",true);t()},q.enable=function(){q.element.find("input").prop("disabled",false);J()},q.hide=function(){var O=q.widget.find(".collapse"),M,N;for(M=0;M<O.length;M++){N=O.eq(M).data("collapse");if(N&&N.transitioning){return}}q.widget.hide();q.viewMode=q.startViewMode;f();q.element.trigger({type:"hide.dp",date:q.date});k()},q.setValue=function(M){a.lang(q.options.language);if(!M){q.unset=true}else{q.unset=false}if(!a.isMoment(M)){M=a(M)}if(M.isValid()){q.date=M;x();q.viewDate=a({y:q.date.year(),M:q.date.month()});h();y()}else{w(M)}},q.getDate=function(){if(q.unset){return null}return q.date},q.setDate=function(M){if(!M){q.setValue(null)}else{q.setValue(M)}},q.setEndDate=function(M){q.options.endDate=a(M);if(!q.options.endDate.isValid()){q.options.endDate=a().add(50,"y")}if(q.viewDate){n()}},q.setStartDate=function(M){q.options.startDate=a(M);if(!q.options.startDate.isValid()){q.options.startDate=a({y:1970})}if(q.viewDate){n()}};E()};d.fn.datetimepicker=function(e){return this.each(function(){var g=d(this),f=g.data("DateTimePicker");if(!f){g.data("DateTimePicker",new b(this,e))}})}})(jQuery);
\ No newline at end of file