diff options
-rw-r--r-- | appinfo/routes.php | 20 | ||||
-rw-r--r-- | css/style.css | 106 | ||||
-rw-r--r-- | css/style.less | 103 | ||||
-rw-r--r-- | js/app/app.coffee | 17 | ||||
-rw-r--r-- | js/app/controllers/detailscontroller.coffee | 37 | ||||
-rw-r--r-- | js/app/directives/avatar.coffee | 29 | ||||
-rw-r--r-- | js/app/filters/dateFromNow.coffee | 27 | ||||
-rw-r--r-- | js/app/services/businesslayer/tasksbusinesslayer.coffee | 20 | ||||
-rw-r--r-- | js/app/services/models/tasksmodel.coffee | 25 | ||||
-rw-r--r-- | js/app/services/persistence.coffee | 22 | ||||
-rw-r--r-- | js/public/app.js | 190 | ||||
-rw-r--r-- | js/vendor/momentjs/moment.js | 247 | ||||
-rw-r--r-- | js/vendor/momentjs/moment.min.js | 4 | ||||
-rw-r--r-- | l10n/de.php | 16 | ||||
-rw-r--r-- | lib/controller/settingscontroller.php | 4 | ||||
-rw-r--r-- | lib/controller/taskscontroller.php | 98 | ||||
-rw-r--r-- | lib/helper.php | 17 | ||||
-rw-r--r-- | templates/part.details.php | 45 |
18 files changed, 928 insertions, 99 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 5d65f23d..9af9e280 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -243,6 +243,26 @@ $this->create('task_reminder', '/tasks/{taskID}/reminder') } ); +$this->create('task_comment', '/tasks/{taskID}/comment') + ->post() + ->action( + function($params){ + session_write_close(); + $dispatcher = new Dispatcher($params); + $dispatcher->dispatch('TasksController', 'addComment'); + } + ); + +$this->create('task_deletecomment', '/tasks/{taskID}/comment/{commentID}/delete') + ->post() + ->action( + function($params){ + session_write_close(); + $dispatcher = new Dispatcher($params); + $dispatcher->dispatch('TasksController', 'deleteComment'); + } + ); + /* * Settings */ diff --git a/css/style.css b/css/style.css index 0ab32ac0..24c72a53 100644 --- a/css/style.css +++ b/css/style.css @@ -187,6 +187,9 @@ text-decoration: line-through; text-shadow: none; } +#content li.task-item:last-child { + height: 39px; +} #content li.task-item:last-child .task-body { border-width: 1px; } @@ -636,7 +639,7 @@ border-top: 1px solid #D3D3D3; bottom: 0; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5) inset; - height: 35px; + height: 65px; left: 0; position: absolute; right: 0; @@ -647,9 +650,46 @@ } #task-details div.footer .icon { position: absolute; - top: 8px; + bottom: 7px; left: 8px; } +#task-details div.footer .detail-addcomment { + padding: 4px 10px 0; +} +#task-details div.footer .detail-addcomment input { + background: none repeat scroll 0 0 white; + border: 1px solid #bdbcbb; + border-radius: 0; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset; + box-sizing: border-box; + color: #423e3e; + font-family: "Helvetica Neue", "Helvetica", "Arial", Sans-Serif; + font-size: 13px; + font-weight: 500; + margin-top: 2px; + outline: medium none; + padding: 4px; + transition: all 0.2s ease-in-out 0s; +} +#task-details div.footer .detail-addcomment input[type="text"] { + width: 230px; +} +#task-details div.footer .detail-addcomment input[type="button"] { + float: right; + margin-right: 0; + color: #BBB; + cursor: default; +} +#task-details div.footer .detail-addcomment input[type="button"].active { + color: #fff; + background: -webkit-linear-gradient(top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -moz-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -ms-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -o-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: linear-gradient(top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + transition: none; + cursor: pointer; +} #task-details.completed .body .section .section-title { color: #9FA2A6 !important; } @@ -723,7 +763,7 @@ position: relative; } #task-details .body { - bottom: 36px; + bottom: 65px; left: 0; overflow: auto; position: absolute; @@ -742,7 +782,7 @@ border-color: #CFCFCF; font-size: 13px; line-height: 26px; - margin: 20px; + margin: 0 20px; padding: 5px 15px; cursor: text; } @@ -956,6 +996,53 @@ #task-details .body .section.detail-reminder.date .section-description { display: block; } +#task-details .body .section.detail-note { + padding: 20px 0; + height: auto; +} +#task-details .body .section.detail-comments { + background: none; + padding: 10px 0; + height: auto; +} +#task-details .body .section.detail-comments .comment-item { + padding: 5px 55px 0; + position: relative; +} +#task-details .body .section.detail-comments .comment-item .icon.detail-delete { + top: 5px; +} +#task-details .body .section.detail-comments .comment-item:hover .icon.detail-delete { + display: block; +} +#task-details .body .section.detail-comments .comment-item .avatar { + width: 32px; + height: 32px; + position: absolute; + left: 10px; + top: 10px; + border-radius: 2px; + overflow: hidden; +} +#task-details .body .section.detail-comments .comment-item .avatar img { + height: 100%; + width: 100%; +} +#task-details .body .section.detail-comments .comment-item .username { + display: inline-block; + font-weight: bold; +} +#task-details .body .section.detail-comments .comment-item .time { + color: #9fa2a6; + font-size: 11px; +} +#task-details .body .section.detail-addcomment { + background: url("../img/divider.svg") repeat-x scroll center top transparent; + bottom: 0; + left: 0; + position: absolute; + right: 0; +} #modal-wrapper { position: absolute; width: 100%; @@ -986,7 +1073,11 @@ min-height: 100px; } .button { - background-image: -moz-linear-gradient(center top, #5cb6e7 0px, #317cd7 100%); + background: -webkit-linear-gradient(top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -moz-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -ms-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: -o-linear-gradient(center top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; + background: linear-gradient(top, #5cb6e7 0%, #317cd7 100%) repeat scroll 0 0 transparent; border-color: #0c67a5; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset; color: #fff; @@ -1057,6 +1148,11 @@ td.ui-timepicker-hours table { } .ui-timepicker table td a.ui-state-active { background: -moz-linear-gradient(center top, #33a3ef, #168ad4) repeat scroll 0 0 transparent !important; + background: -webkit-linear-gradient(top, #33a3ef 0%, #168ad4 100%) repeat scroll 0 0 transparent; + background: -moz-linear-gradient(center top, #33a3ef 0%, #168ad4 100%) repeat scroll 0 0 transparent; + background: -ms-linear-gradient(center top, #33a3ef 0%, #168ad4 100%) repeat scroll 0 0 transparent; + background: -o-linear-gradient(center top, #33a3ef 0%, #168ad4 100%) repeat scroll 0 0 transparent; + background: linear-gradient(top, #33a3ef 0%, #168ad4 100%) repeat scroll 0 0 transparent; border-radius: 3px 3px 3px 3px; color: white; opacity: 1; diff --git a/css/style.less b/css/style.less index 0761850f..9cc2a40d 100644 --- a/css/style.less +++ b/css/style.less @@ -209,8 +209,11 @@ text-shadow: none; } } - &:last-child .task-body{ - border-width: 1px; + &:last-child{ + height: 39px; + .task-body{ + border-width: 1px; + } } .task-body{ -moz-box-sizing: border-box; @@ -674,12 +677,11 @@ position: relative; } div.footer{ - // background: none repeat scroll 0 0 #f1f1f1; background: url("../img/bgTask.png") repeat scroll 0 0 #FFFFFF; border-top: 1px solid #D3D3D3; bottom: 0; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5) inset; - height: 35px; + height: 65px; left: 0; position: absolute; right: 0; @@ -689,9 +691,42 @@ } .icon{ position:absolute; - top:8px; + bottom:7px; left:8px; } + .detail-addcomment{ + padding: 4px 10px 0; + input{ + background: none repeat scroll 0 0 white; + border: 1px solid #bdbcbb; + border-radius: 0; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset; + box-sizing: border-box; + color: #423e3e; + font-family: "Helvetica Neue","Helvetica","Arial",Sans-Serif; + font-size: 13px; + font-weight: 500; + margin-top: 2px; + outline: medium none; + padding: 4px; + transition: all 0.2s ease-in-out 0s; + &[type="text"]{ + width: 230px; + } + &[type="button"]{ + float: right; + margin-right: 0; + color: #BBB; + cursor: default; + &.active{ + color: #fff; + .background-gradient(#5cb6e7,#317cd7); + transition: none; + cursor: pointer; + } + } + } + } } &.completed{ .body{ @@ -772,7 +807,7 @@ } } .body{ - bottom: 36px; + bottom: 65px; left: 0; overflow: auto; position: absolute; @@ -786,7 +821,7 @@ // box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 1px 0 #F8F5DB inset; font-size: 13px; line-height: 26px; - margin: 20px; + margin: 0 20px; padding: 5px 15px; cursor:text; .expandingArea{ @@ -1002,6 +1037,56 @@ } } } + &.detail-note{ + padding: 20px 0; + height:auto; + } + &.detail-comments{ + background: none; + padding: 10px 0; + height: auto; + .comment-item{ + padding: 5px 55px 0; + position: relative; + .icon.detail-delete{ + top: 5px; + } + &:hover{ + .icon.detail-delete{ + display: block; + } + } + .avatar{ + width: 32px; + height: 32px; + position: absolute; + left: 10px; + top: 10px; + border-radius: 2px; + overflow: hidden; + img{ + height: 100%; + width: 100%; + } + } + .username{ + display: inline-block; + font-weight: bold; + } + .comment{} + .time{ + color: #9fa2a6; + font-size: 11px; + } + } + } + &.detail-addcomment{ + background: url("../img/divider.svg") repeat-x scroll center top transparent; + bottom: 0; + left: 0; + position: absolute; + right: 0; + } } } } @@ -1039,7 +1124,8 @@ } } .button{ - background-image: -moz-linear-gradient(center top , #5cb6e7 0px, #317cd7 100%); + // background-image: linear-gradient(center top , #5cb6e7 0px, #317cd7 100%); + .background-gradient(#5cb6e7, #317cd7); border-color: #0c67a5; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset; color: #fff; @@ -1115,6 +1201,7 @@ td.ui-timepicker-hours table{ .ui-timepicker{ table td a.ui-state-active{ background: -moz-linear-gradient(center top , #33A3EF, #168AD4) repeat scroll 0 0 transparent !important; + .background-gradient( #33A3EF, #168AD4); border-radius: 3px 3px 3px 3px; color: white; opacity: 1; diff --git a/js/app/app.coffee b/js/app/app.coffee index b76e4e36..1510deae 100644 --- a/js/app/app.coffee +++ b/js/app/app.coffee @@ -142,4 +142,21 @@ angular.module('Tasks').run ['Config', '$timeout', sameElse : 'ddd, MMM. DD' } }) + moment.lang('en', { + relativeTime: { + future: t('tasks_enhanced', "in %s") + past: t('tasks_enhanced', "%s ago") + s: t('tasks_enhanced', "seconds") + m: t('tasks_enhanced', "a minute") + mm: t('tasks_enhanced', "%d minutes") + h: t('tasks_enhanced', "an hour") + hh: t('tasks_enhanced', "%d hours") + d: t('tasks_enhanced', "a day") + dd: t('tasks_enhanced', "%d days") + M: t('tasks_enhanced', "a month") + MM: t('tasks_enhanced', "%d months") + y: t('tasks_enhanced', "a year") + yy: t('tasks_enhanced', "%d years") + } + }) ]
\ No newline at end of file diff --git a/js/app/controllers/detailscontroller.coffee b/js/app/controllers/detailscontroller.coffee index 82c336a3..257767bd 100644 --- a/js/app/controllers/detailscontroller.coffee +++ b/js/app/controllers/detailscontroller.coffee @@ -40,6 +40,8 @@ $timeout, $routeParams, SettingsModel) -> @_$scope.settingsmodel = @_$settingsmodel + @_$scope.isAddingComment = false + @_$scope.durations = [ { name: t('tasks_enhanced','week'), @@ -288,6 +290,41 @@ $timeout, $routeParams, SettingsModel) -> @_$scope.setReminderDuration = (taskID) -> _tasksbusinesslayer.setReminder(_$scope.route.taskID) + @_$scope.addComment = () -> + if _$scope.CommentContent + _$scope.isAddingComment = true + + comment = { + tmpID: 'newComment' + Date.now() + comment: _$scope.CommentContent + taskID: _$scope.route.taskID + time: moment().format('YYYYMMDDTHHmmss') + name: $('#expandDisplayName').text() + } + + _tasksbusinesslayer.addComment comment + , (data) => + _$tasksmodel.updateComment(data.comment) + _$scope.isAddingComment = false + , => + _$scope.isAddingComment = false + + _$scope.CommentContent = '' + + @_$scope.sendComment = (event) -> + if (event.keyCode == 13) + _$scope.addComment() + + @_$scope.deleteComment = (commentID) -> + _tasksbusinesslayer.deleteComment(_$scope.route.taskID, commentID) + + @_$scope.commentStrings = () -> + { + button: t('tasks_enhanced','Comment'), + input: t('tasks_enhanced','Add a comment') + } + + return new DetailsController($scope, $window, TasksModel, TasksBusinessLayer, $route, $location, $timeout, $routeParams, SettingsModel) diff --git a/js/app/directives/avatar.coffee b/js/app/directives/avatar.coffee new file mode 100644 index 00000000..494bcd03 --- /dev/null +++ b/js/app/directives/avatar.coffee @@ -0,0 +1,29 @@ +### + +ownCloud - Tasks + +@author Raimund Schlüßler +@copyright 2013 + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see <http://www.gnu.org/licenses/>. + +### +angular.module('Tasks').directive 'avatar', -> + restrict: 'A' + scope: false + link: (scope, elm, attr) -> + attr.$observe('userID', () -> + if(attr.userid) + elm.avatar(attr.userid,attr.size) + )
\ No newline at end of file diff --git a/js/app/filters/dateFromNow.coffee b/js/app/filters/dateFromNow.coffee new file mode 100644 index 00000000..afaace6e --- /dev/null +++ b/js/app/filters/dateFromNow.coffee @@ -0,0 +1,27 @@ +### + +ownCloud - Tasks + +@author Raimund Schlüßler +@copyright 2013 + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see <http://www.gnu.org/licenses/>. + +### +angular.module('Tasks').filter 'dateFromNow', () -> + (due) -> + if moment(due, "YYYYMMDDTHHmmss").isValid() + return moment(due, "YYYYMMDDTHHmmss").fromNow() + else + return ''
\ No newline at end of file diff --git a/js/app/services/businesslayer/tasksbusinesslayer.coffee b/js/app/services/businesslayer/tasksbusinesslayer.coffee index 70fa748f..1d74c127 100644 --- a/js/app/services/businesslayer/tasksbusinesslayer.coffee +++ b/js/app/services/businesslayer/tasksbusinesslayer.coffee @@ -332,6 +332,26 @@ angular.module('Tasks').factory 'TasksBusinessLayer', setShowHidden: (showHidden) -> @_persistence.setShowHidden(showHidden) + # addComment: (taskID, comment) -> + # @_persistence.addComment(taskID, comment) + + addComment: (comment, onSuccess=null, onFailure=null) -> + onSuccess or= -> + onFailure or= -> + + @_$tasksmodel.addComment(comment) + + success = (response) => + if response.status == 'error' + onFailure() + else + onSuccess(response.data) + @_persistence.addComment(comment, success) + + deleteComment: (taskID, commentID) -> + @_$tasksmodel.deleteComment(taskID, commentID) + @_persistence.deleteComment(taskID, commentID) + return new TasksBusinessLayer(TasksModel, Persistence) diff --git a/js/app/services/models/tasksmodel.coffee b/js/app/services/models/tasksmodel.coffee index 299661e7..7108f536 100644 --- a/js/app/services/models/tasksmodel.coffee +++ b/js/app/services/models/tasksmodel.coffee @@ -165,5 +165,30 @@ angular.module('Tasks').factory 'TasksModel', setNote: (taskID, note) -> @update({id:taskID,note:note}) + addComment: (comment) -> + task = @getById(comment.taskID) + if task.comments + task.comments.push(comment) + else + task.comments = [comment] + + updateComment: (comment) -> + task = @getById(comment.taskID) + i = 0 + for com in task.comments + if com.tmpID == comment.tmpID + task.comments[i] = comment + break + i++ + + deleteComment: (taskID, commentID) -> + task = @getById(taskID) + i = 0 + for comment in task.comments + if comment.id == commentID + task.comments.splice(i,1) + break + i++ + return new TasksModel(Utils) ]
\ No newline at end of file diff --git a/js/app/services/persistence.coffee b/js/app/services/persistence.coffee index 44e14484..dab98b69 100644 --- a/js/app/services/persistence.coffee +++ b/js/app/services/persistence.coffee @@ -326,6 +326,28 @@ angular.module('Tasks').factory 'Persistence', @_request.post '/apps/tasks_enhanced/settings/showhidden/{showHidden}', params + addComment: (comment, onSuccess=null, onFailure=null) -> + params = + routeParams: + taskID: comment.taskID + data: + comment: comment.comment + tmpID: comment.tmpID + onSuccess: onSuccess + onFailure: onFailure + + @_request.post '/apps/tasks_enhanced/tasks/{taskID}/comment', + params + + deleteComment: (taskID, commentID) -> + params = + routeParams: + taskID: taskID + commentID: commentID + + @_request.post '/apps/tasks_enhanced/tasks/{taskID}/comment/ + {commentID}/delete', params + return new Persistence(Request, Loading, $rootScope) ]
\ No newline at end of file diff --git a/js/public/app.js b/js/public/app.js index 43895393..d3c8a949 100644 --- a/js/public/app.js +++ b/js/public/app.js @@ -128,7 +128,7 @@ sameElse: 'MMM DD, YYYY' } }); - return moment.lang('list_week', { + moment.lang('list_week', { calendar: { lastDay: '[' + t('tasks_enhanced', 'Yesterday') + ']', sameDay: '[' + t('tasks_enhanced', 'Today') + '], MMM. DD', @@ -138,12 +138,46 @@ sameElse: 'ddd, MMM. DD' } }); + return moment.lang('en', { + relativeTime: { + future: t('tasks_enhanced', "in %s"), + past: t('tasks_enhanced', "%s ago"), + s: t('tasks_enhanced', "seconds"), + m: t('tasks_enhanced', "a minute"), + mm: t('tasks_enhanced', "%d minutes"), + h: t('tasks_enhanced', "an hour"), + hh: t('tasks_enhanced', "%d hours"), + d: t('tasks_enhanced', "a day"), + dd: t('tasks_enhanced', "%d days"), + M: t('tasks_enhanced', "a month"), + MM: t('tasks_enhanced', "%d months"), + y: t('tasks_enhanced', "a year"), + yy: t('tasks_enhanced', "%d years") + } + }); } ]); }).call(this); (function() { + angular.module('Tasks').directive('avatar', function() { + return { + restrict: 'A', + scope: false, + link: function(scope, elm, attr) { + return attr.$observe('userID', function() { + if (attr.userid) { + return elm.avatar(attr.userid, attr.size); + } + }); + } + }; + }); + +}).call(this); + +(function() { angular.module('Tasks').directive('datepicker', function() { return { restrict: 'A', @@ -410,6 +444,7 @@ return _$scope.task = _$tasksmodel.getById(_$scope.route.taskID); }); this._$scope.settingsmodel = this._$settingsmodel; + this._$scope.isAddingComment = false; this._$scope.durations = [ { name: t('tasks_enhanced', 'week'), @@ -663,6 +698,41 @@ this._$scope.setReminderDuration = function(taskID) { return _tasksbusinesslayer.setReminder(_$scope.route.taskID); }; + this._$scope.addComment = function() { + var comment, + _this = this; + if (_$scope.CommentContent) { + _$scope.isAddingComment = true; + comment = { + tmpID: 'newComment' + Date.now(), + comment: _$scope.CommentContent, + taskID: _$scope.route.taskID, + time: moment().format('YYYYMMDDTHHmmss'), + name: $('#expandDisplayName').text() + }; + _tasksbusinesslayer.addComment(comment, function(data) { + _$tasksmodel.updateComment(data.comment); + return _$scope.isAddingComment = false; + }, function() { + return _$scope.isAddingComment = false; + }); + return _$scope.CommentContent = ''; + } + }; + this._$scope.sendComment = function(event) { + if (event.keyCode === 13) { + return _$scope.addComment(); + } + }; + this._$scope.deleteComment = function(commentID) { + return _tasksbusinesslayer.deleteComment(_$scope.route.taskID, commentID); + }; + this._$scope.commentStrings = function() { + return { + button: t('tasks_enhanced', 'Comment'), + input: t('tasks_enhanced', 'Add a comment') + }; + }; } return DetailsController; @@ -1627,6 +1697,33 @@ return this._persistence.setShowHidden(showHidden); }; + TasksBusinessLayer.prototype.addComment = function(comment, onSuccess, onFailure) { + var success, + _this = this; + if (onSuccess == null) { + onSuccess = null; + } + if (onFailure == null) { + onFailure = null; + } + onSuccess || (onSuccess = function() {}); + onFailure || (onFailure = function() {}); + this._$tasksmodel.addComment(comment); + success = function(response) { + if (response.status === 'error') { + return onFailure(); + } else { + return onSuccess(response.data); + } + }; + return this._persistence.addComment(comment, success); + }; + + TasksBusinessLayer.prototype.deleteComment = function(taskID, commentID) { + this._$tasksmodel.deleteComment(taskID, commentID); + return this._persistence.deleteComment(taskID, commentID); + }; + return TasksBusinessLayer; })(); @@ -2149,6 +2246,50 @@ }); }; + TasksModel.prototype.addComment = function(comment) { + var task; + task = this.getById(comment.taskID); + if (task.comments) { + return task.comments.push(comment); + } else { + return task.comments = [comment]; + } + }; + + TasksModel.prototype.updateComment = function(comment) { + var com, i, task, _i, _len, _ref, _results; + task = this.getById(comment.taskID); + i = 0; + _ref = task.comments; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + com = _ref[_i]; + if (com.tmpID === comment.tmpID) { + task.comments[i] = comment; + break; + } + _results.push(i++); + } + return _results; + }; + + TasksModel.prototype.deleteComment = function(taskID, commentID) { + var comment, i, task, _i, _len, _ref, _results; + task = this.getById(taskID); + i = 0; + _ref = task.comments; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + comment = _ref[_i]; + if (comment.id === commentID) { + task.comments.splice(i, 1); + break; + } + _results.push(i++); + } + return _results; + }; + return TasksModel; })(_Model); @@ -2582,6 +2723,40 @@ return this._request.post('/apps/tasks_enhanced/settings/showhidden/{showHidden}', params); }; + Persistence.prototype.addComment = function(comment, onSuccess, onFailure) { + var params; + if (onSuccess == null) { + onSuccess = null; + } + if (onFailure == null) { + onFailure = null; + } + params = { + routeParams: { + taskID: comment.taskID + }, + data: { + comment: comment.comment, + tmpID: comment.tmpID + }, + onSuccess: onSuccess, + onFailure: onFailure + }; + return this._request.post('/apps/tasks_enhanced/tasks/{taskID}/comment', params); + }; + + Persistence.prototype.deleteComment = function(taskID, commentID) { + var params; + params = { + routeParams: { + taskID: taskID, + commentID: commentID + } + }; + return this._request.post('/apps/tasks_enhanced/tasks/{taskID}/comment/\ + {commentID}/delete', params); + }; + return Persistence; })(); @@ -2671,6 +2846,19 @@ }).call(this); (function() { + angular.module('Tasks').filter('dateFromNow', function() { + return function(due) { + if (moment(due, "YYYYMMDDTHHmmss").isValid()) { + return moment(due, "YYYYMMDDTHHmmss").fromNow(); + } else { + return ''; + } + }; + }); + +}).call(this); + +(function() { angular.module('Tasks').filter('dateTaskList', function() { return function(due) { if (moment(due, "YYYYMMDDTHHmmss").isValid()) { diff --git a/js/vendor/momentjs/moment.js b/js/vendor/momentjs/moment.js index 257ee7ec..83282c6f 100644 --- a/js/vendor/momentjs/moment.js +++ b/js/vendor/momentjs/moment.js @@ -1,5 +1,5 @@ //! moment.js -//! version : 2.6.0 +//! version : 2.7.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com @@ -11,7 +11,7 @@ ************************************/ var moment, - VERSION = "2.6.0", + VERSION = "2.7.0", // the global-scope this is NOT the global object in Node.js globalScope = typeof global !== 'undefined' ? global : this, oldGlobalMoment, @@ -36,6 +36,7 @@ _f : null, _l : null, _strict : null, + _tzm : null, _isUTC : null, _offset : null, // optional. Combine with _isUTC _pf : null, @@ -144,6 +145,16 @@ // format function strings formatFunctions = {}, + // default relative time thresholds + relativeTimeThresholds = { + s: 45, //seconds to minutes + m: 45, //minutes to hours + h: 22, //hours to days + dd: 25, //days to month (month == 1) + dm: 45, //days to months (months > 1) + dy: 345 //days to year + }, + // tokens to ordinalize and pad ordinalizeTokens = 'DDD w W M D d'.split(' '), paddedTokens = 'M D H h m s w W'.split(' '), @@ -283,6 +294,16 @@ lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; + // Pick the first defined of two or three arguments. dfl comes from + // default. + function dfl(a, b, c) { + switch (arguments.length) { + case 2: return a != null ? a : b; + case 3: return a != null ? a : b != null ? b : c; + default: throw new Error("Implement me"); + } + } + function defaultParsingFlags() { // We need to deep clone this object, and es5 standard is not very // helpful. @@ -1151,39 +1172,94 @@ config._useUTC = true; config._tzm = timezoneMinutesFromString(input); break; + // WEEKDAY - human + case 'dd': + case 'ddd': + case 'dddd': + a = getLangDefinition(config._l).weekdaysParse(input); + // if we didn't get a weekday name, mark the date as invalid + if (a != null) { + config._w = config._w || {}; + config._w['d'] = a; + } else { + config._pf.invalidWeekday = input; + } + break; + // WEEK, WEEK DAY - numeric case 'w': case 'ww': case 'W': case 'WW': case 'd': - case 'dd': - case 'ddd': - case 'dddd': case 'e': case 'E': token = token.substr(0, 1); /* falls through */ - case 'gg': case 'gggg': - case 'GG': case 'GGGG': case 'GGGGG': token = token.substr(0, 2); if (input) { config._w = config._w || {}; - config._w[token] = input; + config._w[token] = toInt(input); } break; + case 'gg': + case 'GG': + config._w = config._w || {}; + config._w[token] = moment.parseTwoDigitYear(input); } } + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, lang; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); + week = dfl(w.W, 1); + weekday = dfl(w.E, 1); + } else { + lang = getLangDefinition(config._l); + dow = lang._week.dow; + doy = lang._week.doy; + + weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); + week = dfl(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < dow) { + ++week; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + } else { + // default to begining of week + weekday = dow; + } + } + temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); + + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + // convert an array to a date. // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] function dateFromConfig(config) { - var i, date, input = [], currentDate, - yearToUse, fixYear, w, temp, lang, weekday, week; + var i, date, input = [], currentDate, yearToUse; if (config._d) { return; @@ -1193,39 +1269,12 @@ //compute day of the year from weeks and weekdays if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - fixYear = function (val) { - var intVal = parseInt(val, 10); - return val ? - (val.length < 3 ? (intVal > 68 ? 1900 + intVal : 2000 + intVal) : intVal) : - (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); - }; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); - } - else { - lang = getLangDefinition(config._l); - weekday = w.d != null ? parseWeekday(w.d, lang) : - (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); - - week = parseInt(w.w, 10) || 1; - - //if we're parsing 'd', then the low day numbers may be next week - if (w.d != null && weekday < lang._week.dow) { - week++; - } - - temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); - } - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; + dayOfYearFromWeekInfo(config); } //if the day of the year is set, figure out what it is if (config._dayOfYear) { - yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; + yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse)) { config._pf._overflowDayOfYear = true; @@ -1250,11 +1299,12 @@ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - // add the offsets to the time to be parsed so that we can have a clean array for checking isValid - input[HOUR] += toInt((config._tzm || 0) / 60); - input[MINUTE] += toInt((config._tzm || 0) % 60); - config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); + // Apply timezone offset from input. The actual zone can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + } } function dateFromObject(config) { @@ -1294,6 +1344,11 @@ // date from string and format string function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { + parseISO(config); + return; + } + config._a = []; config._pf.empty = true; @@ -1406,7 +1461,7 @@ } // date from iso format - function makeDateFromString(config) { + function parseISO(config) { var i, l, string = config._i, match = isoRegex.exec(string); @@ -1430,8 +1485,16 @@ config._f += "Z"; } makeDateFromStringAndFormat(config); + } else { + config._isValid = false; } - else { + } + + // date from iso format or fallback + function makeDateFromString(config) { + parseISO(config); + if (config._isValid === false) { + delete config._isValid; moment.createFromInputFallback(config); } } @@ -1512,15 +1575,15 @@ hours = round(minutes / 60), days = round(hours / 24), years = round(days / 365), - args = seconds < 45 && ['s', seconds] || + args = seconds < relativeTimeThresholds.s && ['s', seconds] || minutes === 1 && ['m'] || - minutes < 45 && ['mm', minutes] || + minutes < relativeTimeThresholds.m && ['mm', minutes] || hours === 1 && ['h'] || - hours < 22 && ['hh', hours] || + hours < relativeTimeThresholds.h && ['hh', hours] || days === 1 && ['d'] || - days <= 25 && ['dd', days] || - days <= 45 && ['M'] || - days < 345 && ['MM', round(days / 30)] || + days <= relativeTimeThresholds.dd && ['dd', days] || + days <= relativeTimeThresholds.dm && ['M'] || + days < relativeTimeThresholds.dy && ['MM', round(days / 30)] || years === 1 && ['y'] || ['yy', years]; args[2] = withoutSuffix; args[3] = milliseconds > 0; @@ -1566,6 +1629,7 @@ function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + d = d === 0 ? 7 : d; weekday = weekday != null ? weekday : firstDayOfWeek; daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; @@ -1641,6 +1705,40 @@ config._d = new Date(config._i); }); + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return moment(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + moment.min = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + }; + + moment.max = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + }; + // creating with utc moment.utc = function (input, format, lang, strict) { var c; @@ -1737,6 +1835,9 @@ // default format moment.defaultFormat = isoFormat; + // constant that refers to the ISO standard + moment.ISO_8601 = function () {}; + // Plugins that add properties should also add the key here (null value), // so we can properly clone ourselves. moment.momentProperties = momentProperties; @@ -1745,6 +1846,15 @@ // It is intended to keep the offset in sync with the timezone. moment.updateOffset = function () {}; + // This function allows you to set a threshold for relative time strings + moment.relativeTimeThreshold = function(threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + relativeTimeThresholds[threshold] = limit; + return true; + }; + // This function will load languages and then set the global language. If // no arguments are passed in, it will simply return the current global // language key. @@ -1900,7 +2010,9 @@ add : function (input, val) { var dur; // switch args to support add('s', 1) and add(1, 's') - if (typeof input === 'string') { + if (typeof input === 'string' && typeof val === 'string') { + dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input); + } else if (typeof input === 'string') { dur = moment.duration(+val, input); } else { dur = moment.duration(input, val); @@ -1912,7 +2024,9 @@ subtract : function (input, val) { var dur; // switch args to support subtract('s', 1) and subtract(1, 's') - if (typeof input === 'string') { + if (typeof input === 'string' && typeof val === 'string') { + dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input); + } else if (typeof input === 'string') { dur = moment.duration(+val, input); } else { dur = moment.duration(input, val); @@ -1963,10 +2077,11 @@ return this.from(moment(), withoutSuffix); }, - calendar : function () { + calendar : function (time) { // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're zone'd or not. - var sod = makeAs(moment(), this).startOf('day'), + var now = time || moment(), + sod = makeAs(now, this).startOf('day'), diff = this.diff(sod, 'days', true), format = diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : @@ -2061,15 +2176,21 @@ return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); }, - min: function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - }, + min: deprecate( + "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548", + function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + } + ), - max: function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; - }, + max: deprecate( + "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548", + function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + } + ), // keepTime = true means only change the timezone, without affecting // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200 diff --git a/js/vendor/momentjs/moment.min.js b/js/vendor/momentjs/moment.min.js index 3fe82adf..9c1f3ade 100644 --- a/js/vendor/momentjs/moment.min.js +++ b/js/vendor/momentjs/moment.min.js @@ -1,6 +1,6 @@ //! moment.js -//! version : 2.6.0 +//! version : 2.7.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com -(function(a){function b(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function c(a,b){function c(){ib.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}var d=!0;return i(function(){return d&&(c(),d=!1),b.apply(this,arguments)},b)}function d(a,b){return function(c){return l(a.call(this,c),b)}}function e(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function f(){}function g(a){y(a),i(this,a)}function h(a){var b=r(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._bubble()}function i(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function j(a){var b,c={};for(b in a)a.hasOwnProperty(b)&&wb.hasOwnProperty(b)&&(c[b]=a[b]);return c}function k(a){return 0>a?Math.ceil(a):Math.floor(a)}function l(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.length<b;)d="0"+d;return(e?c?"+":"":"-")+d}function m(a,b,c,d){var e=b._milliseconds,f=b._days,g=b._months;d=null==d?!0:d,e&&a._d.setTime(+a._d+e*c),f&&db(a,"Date",cb(a,"Date")+f*c),g&&bb(a,cb(a,"Month")+g*c),d&&ib.updateOffset(a,f||g)}function n(a){return"[object Array]"===Object.prototype.toString.call(a)}function o(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function p(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&t(a[d])!==t(b[d]))&&g++;return g+f}function q(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=Zb[a]||$b[b]||b}return a}function r(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=q(c),b&&(d[b]=a[c]));return d}function s(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}ib[b]=function(e,f){var g,h,i=ib.fn._lang[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=ib().utc().set(d,a);return i.call(ib.fn._lang,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function t(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function u(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function v(a,b,c){return $(ib([a,11,31+b-c]),b,c).week}function w(a){return x(a)?366:365}function x(a){return a%4===0&&a%100!==0||a%400===0}function y(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[pb]<0||a._a[pb]>11?pb:a._a[qb]<1||a._a[qb]>u(a._a[ob],a._a[pb])?qb:a._a[rb]<0||a._a[rb]>23?rb:a._a[sb]<0||a._a[sb]>59?sb:a._a[tb]<0||a._a[tb]>59?tb:a._a[ub]<0||a._a[ub]>999?ub:-1,a._pf._overflowDayOfYear&&(ob>b||b>qb)&&(b=qb),a._pf.overflow=b)}function z(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function A(a){return a?a.toLowerCase().replace("_","-"):a}function B(a,b){return b._isUTC?ib(a).zone(b._offset||0):ib(a).local()}function C(a,b){return b.abbr=a,vb[a]||(vb[a]=new f),vb[a].set(b),vb[a]}function D(a){delete vb[a]}function E(a){var b,c,d,e,f=0,g=function(a){if(!vb[a]&&xb)try{require("./lang/"+a)}catch(b){}return vb[a]};if(!a)return ib.fn._lang;if(!n(a)){if(c=g(a))return c;a=[a]}for(;f<a.length;){for(e=A(a[f]).split("-"),b=e.length,d=A(a[f+1]),d=d?d.split("-"):null;b>0;){if(c=g(e.slice(0,b).join("-")))return c;if(d&&d.length>=b&&p(e,d,!0)>=b-1)break;b--}f++}return ib.fn._lang}function F(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function G(a){var b,c,d=a.match(Bb);for(b=0,c=d.length;c>b;b++)d[b]=cc[d[b]]?cc[d[b]]:F(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function H(a,b){return a.isValid()?(b=I(b,a.lang()),_b[b]||(_b[b]=G(b)),_b[b](a)):a.lang().invalidDate()}function I(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Cb.lastIndex=0;d>=0&&Cb.test(a);)a=a.replace(Cb,c),Cb.lastIndex=0,d-=1;return a}function J(a,b){var c,d=b._strict;switch(a){case"Q":return Nb;case"DDDD":return Pb;case"YYYY":case"GGGG":case"gggg":return d?Qb:Fb;case"Y":case"G":case"g":return Sb;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?Rb:Gb;case"S":if(d)return Nb;case"SS":if(d)return Ob;case"SSS":if(d)return Pb;case"DDD":return Eb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Ib;case"a":case"A":return E(b._l)._meridiemParse;case"X":return Lb;case"Z":case"ZZ":return Jb;case"T":return Kb;case"SSSS":return Hb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?Ob:Db;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Db;case"Do":return Mb;default:return c=new RegExp(R(Q(a.replace("\\","")),"i"))}}function K(a){a=a||"";var b=a.match(Jb)||[],c=b[b.length-1]||[],d=(c+"").match(Xb)||["-",0,0],e=+(60*d[1])+t(d[2]);return"+"===d[0]?-e:e}function L(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[pb]=3*(t(b)-1));break;case"M":case"MM":null!=b&&(e[pb]=t(b)-1);break;case"MMM":case"MMMM":d=E(c._l).monthsParse(b),null!=d?e[pb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[qb]=t(b));break;case"Do":null!=b&&(e[qb]=t(parseInt(b,10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=t(b));break;case"YY":e[ob]=ib.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[ob]=t(b);break;case"a":case"A":c._isPm=E(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[rb]=t(b);break;case"m":case"mm":e[sb]=t(b);break;case"s":case"ss":e[tb]=t(b);break;case"S":case"SS":case"SSS":case"SSSS":e[ub]=t(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=K(b);break;case"w":case"ww":case"W":case"WW":case"d":case"dd":case"ddd":case"dddd":case"e":case"E":a=a.substr(0,1);case"gg":case"gggg":case"GG":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=b)}}function M(a){var b,c,d,e,f,g,h,i,j,k,l=[];if(!a._d){for(d=O(a),a._w&&null==a._a[qb]&&null==a._a[pb]&&(f=function(b){var c=parseInt(b,10);return b?b.length<3?c>68?1900+c:2e3+c:c:null==a._a[ob]?ib().weekYear():a._a[ob]},g=a._w,null!=g.GG||null!=g.W||null!=g.E?h=_(f(g.GG),g.W||1,g.E,4,1):(i=E(a._l),j=null!=g.d?X(g.d,i):null!=g.e?parseInt(g.e,10)+i._week.dow:0,k=parseInt(g.w,10)||1,null!=g.d&&j<i._week.dow&&k++,h=_(f(g.gg),k,j,i._week.doy,i._week.dow)),a._a[ob]=h.year,a._dayOfYear=h.dayOfYear),a._dayOfYear&&(e=null==a._a[ob]?d[ob]:a._a[ob],a._dayOfYear>w(e)&&(a._pf._overflowDayOfYear=!0),c=W(e,0,a._dayOfYear),a._a[pb]=c.getUTCMonth(),a._a[qb]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=l[b]=d[b];for(;7>b;b++)a._a[b]=l[b]=null==a._a[b]?2===b?1:0:a._a[b];l[rb]+=t((a._tzm||0)/60),l[sb]+=t((a._tzm||0)%60),a._d=(a._useUTC?W:V).apply(null,l)}}function N(a){var b;a._d||(b=r(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],M(a))}function O(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function P(a){a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=E(a._l),h=""+a._i,i=h.length,j=0;for(d=I(a._f,g).match(Bb)||[],b=0;b<d.length;b++)e=d[b],c=(h.match(J(e,a))||[])[0],c&&(f=h.substr(0,h.indexOf(c)),f.length>0&&a._pf.unusedInput.push(f),h=h.slice(h.indexOf(c)+c.length),j+=c.length),cc[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),L(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=i-j,h.length>0&&a._pf.unusedInput.push(h),a._isPm&&a._a[rb]<12&&(a._a[rb]+=12),a._isPm===!1&&12===a._a[rb]&&(a._a[rb]=0),M(a),y(a)}function Q(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function R(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function S(a){var c,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;f<a._f.length;f++)g=0,c=i({},a),c._pf=b(),c._f=a._f[f],P(c),z(c)&&(g+=c._pf.charsLeftOver,g+=10*c._pf.unusedTokens.length,c._pf.score=g,(null==e||e>g)&&(e=g,d=c));i(a,d||c)}function T(a){var b,c,d=a._i,e=Tb.exec(d);if(e){for(a._pf.iso=!0,b=0,c=Vb.length;c>b;b++)if(Vb[b][1].exec(d)){a._f=Vb[b][0]+(e[6]||" ");break}for(b=0,c=Wb.length;c>b;b++)if(Wb[b][1].exec(d)){a._f+=Wb[b][0];break}d.match(Jb)&&(a._f+="Z"),P(a)}else ib.createFromInputFallback(a)}function U(b){var c=b._i,d=yb.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?T(b):n(c)?(b._a=c.slice(0),M(b)):o(c)?b._d=new Date(+c):"object"==typeof c?N(b):"number"==typeof c?b._d=new Date(c):ib.createFromInputFallback(b)}function V(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function W(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function X(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function Y(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Z(a,b,c){var d=nb(Math.abs(a)/1e3),e=nb(d/60),f=nb(e/60),g=nb(f/24),h=nb(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",nb(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,Y.apply({},i)}function $(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=ib(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function _(a,b,c,d,e){var f,g,h=W(a,0,1).getUTCDay();return c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:w(a-1)+g}}function ab(b){var c=b._i,d=b._f;return null===c||d===a&&""===c?ib.invalid({nullInput:!0}):("string"==typeof c&&(b._i=c=E().preparse(c)),ib.isMoment(c)?(b=j(c),b._d=new Date(+c._d)):d?n(d)?S(b):P(b):U(b),new g(b))}function bb(a,b){var c;return"string"==typeof b&&(b=a.lang().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),u(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function cb(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function db(a,b,c){return"Month"===b?bb(a,c):a._d["set"+(a._isUTC?"UTC":"")+b](c)}function eb(a,b){return function(c){return null!=c?(db(this,a,c),ib.updateOffset(this,b),this):cb(this,a)}}function fb(a){ib.duration.fn[a]=function(){return this._data[a]}}function gb(a,b){ib.duration.fn["as"+a]=function(){return+this/b}}function hb(a){"undefined"==typeof ender&&(jb=mb.moment,mb.moment=a?c("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.",ib):ib)}for(var ib,jb,kb,lb="2.6.0",mb="undefined"!=typeof global?global:this,nb=Math.round,ob=0,pb=1,qb=2,rb=3,sb=4,tb=5,ub=6,vb={},wb={_isAMomentObject:null,_i:null,_f:null,_l:null,_strict:null,_isUTC:null,_offset:null,_pf:null,_lang:null},xb="undefined"!=typeof module&&module.exports,yb=/^\/?Date\((\-?\d+)/i,zb=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Ab=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Bb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,Cb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,Db=/\d\d?/,Eb=/\d{1,3}/,Fb=/\d{1,4}/,Gb=/[+\-]?\d{1,6}/,Hb=/\d+/,Ib=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Jb=/Z|[\+\-]\d\d:?\d\d/gi,Kb=/T/i,Lb=/[\+\-]?\d+(\.\d{1,3})?/,Mb=/\d{1,2}/,Nb=/\d/,Ob=/\d\d/,Pb=/\d{3}/,Qb=/\d{4}/,Rb=/[+-]?\d{6}/,Sb=/[+-]?\d+/,Tb=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ub="YYYY-MM-DDTHH:mm:ssZ",Vb=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],Wb=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],Xb=/([\+\-]|\d\d)/gi,Yb=("Date|Hours|Minutes|Seconds|Milliseconds".split("|"),{Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6}),Zb={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",Q:"quarter",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},$b={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},_b={},ac="DDD w W M D d".split(" "),bc="M D H h m s w W".split(" "),cc={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return l(this.year()%100,2)},YYYY:function(){return l(this.year(),4)},YYYYY:function(){return l(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+l(Math.abs(a),6)},gg:function(){return l(this.weekYear()%100,2)},gggg:function(){return l(this.weekYear(),4)},ggggg:function(){return l(this.weekYear(),5)},GG:function(){return l(this.isoWeekYear()%100,2)},GGGG:function(){return l(this.isoWeekYear(),4)},GGGGG:function(){return l(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return t(this.milliseconds()/100)},SS:function(){return l(t(this.milliseconds()/10),2)},SSS:function(){return l(this.milliseconds(),3)},SSSS:function(){return l(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+l(t(a/60),2)+":"+l(t(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+l(t(a/60),2)+l(t(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},dc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];ac.length;)kb=ac.pop(),cc[kb+"o"]=e(cc[kb],kb);for(;bc.length;)kb=bc.pop(),cc[kb+kb]=d(cc[kb],2);for(cc.DDDD=d(cc.DDD,3),i(f.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=ib.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=ib([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return $(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),ib=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=c,g._f=d,g._l=e,g._strict=f,g._isUTC=!1,g._pf=b(),ab(g)},ib.suppressDeprecationWarnings=!1,ib.createFromInputFallback=c("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i)}),ib.utc=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=c,g._f=d,g._strict=f,g._pf=b(),ab(g).utc()},ib.unix=function(a){return ib(1e3*a)},ib.duration=function(a,b){var c,d,e,f=a,g=null;return ib.isDuration(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(g=zb.exec(a))?(c="-"===g[1]?-1:1,f={y:0,d:t(g[qb])*c,h:t(g[rb])*c,m:t(g[sb])*c,s:t(g[tb])*c,ms:t(g[ub])*c}):(g=Ab.exec(a))&&(c="-"===g[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},f={y:e(g[2]),M:e(g[3]),d:e(g[4]),h:e(g[5]),m:e(g[6]),s:e(g[7]),w:e(g[8])}),d=new h(f),ib.isDuration(a)&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},ib.version=lb,ib.defaultFormat=Ub,ib.momentProperties=wb,ib.updateOffset=function(){},ib.lang=function(a,b){var c;return a?(b?C(A(a),b):null===b?(D(a),a="en"):vb[a]||E(a),c=ib.duration.fn._lang=ib.fn._lang=E(a),c._abbr):ib.fn._lang._abbr},ib.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),E(a)},ib.isMoment=function(a){return a instanceof g||null!=a&&a.hasOwnProperty("_isAMomentObject")},ib.isDuration=function(a){return a instanceof h},kb=dc.length-1;kb>=0;--kb)s(dc[kb]);ib.normalizeUnits=function(a){return q(a)},ib.invalid=function(a){var b=ib.utc(0/0);return null!=a?i(b._pf,a):b._pf.userInvalidated=!0,b},ib.parseZone=function(){return ib.apply(null,arguments).parseZone()},ib.parseTwoDigitYear=function(a){return t(a)+(t(a)>68?1900:2e3)},i(ib.fn=g.prototype,{clone:function(){return ib(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=ib(this).utc();return 0<a.year()&&a.year()<=9999?H(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):H(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return z(this)},isDSTShifted:function(){return this._a?this.isValid()&&p(this._a,(this._isUTC?ib.utc(this._a):ib(this._a)).toArray())>0:!1},parsingFlags:function(){return i({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=H(this,a||ib.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?ib.duration(+b,a):ib.duration(a,b),m(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?ib.duration(+b,a):ib.duration(a,b),m(this,c,-1),this},diff:function(a,b,c){var d,e,f=B(a,this),g=6e4*(this.zone()-f.zone());return b=q(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-ib(this).startOf("month")-(f-ib(f).startOf("month")))/d,e-=6e4*(this.zone()-ib(this).startOf("month").zone()-(f.zone()-ib(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:k(e)},from:function(a,b){return ib.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(ib(),a)},calendar:function(){var a=B(ib(),this).startOf("day"),b=this.diff(a,"days",!0),c=-6>b?"sameElse":-1>b?"lastWeek":0>b?"lastDay":1>b?"sameDay":2>b?"nextDay":7>b?"nextWeek":"sameElse";return this.format(this.lang().calendar(c,this))},isLeapYear:function(){return x(this.year())},isDST:function(){return this.zone()<this.clone().month(0).zone()||this.zone()<this.clone().month(5).zone()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=X(a,this.lang()),this.add({d:a-b})):b},month:eb("Month",!0),startOf:function(a){switch(a=q(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(a){return a=q(a),this.startOf(a).add("isoWeek"===a?"week":a,1).subtract("ms",1)},isAfter:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)>+ib(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+ib(a).startOf(b)},isSame:function(a,b){return b=b||"ms",+this.clone().startOf(b)===+B(a,this).startOf(b)},min:function(a){return a=ib.apply(null,arguments),this>a?this:a},max:function(a){return a=ib.apply(null,arguments),a>this?this:a},zone:function(a,b){var c=this._offset||0;return null==a?this._isUTC?c:this._d.getTimezoneOffset():("string"==typeof a&&(a=K(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,c!==a&&(!b||this._changeInProgress?m(this,ib.duration(c-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,ib.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?ib(a).zone():0,(this.zone()-a)%60===0},daysInMonth:function(){return u(this.year(),this.month())},dayOfYear:function(a){var b=nb((ib(this).startOf("day")-ib(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=$(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=$(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=$(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this.day()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return v(this.year(),1,4)},weeksInYear:function(){var a=this._lang._week;return v(this.year(),a.dow,a.doy)},get:function(a){return a=q(a),this[a]()},set:function(a,b){return a=q(a),"function"==typeof this[a]&&this[a](b),this},lang:function(b){return b===a?this._lang:(this._lang=E(b),this)}}),ib.fn.millisecond=ib.fn.milliseconds=eb("Milliseconds",!1),ib.fn.second=ib.fn.seconds=eb("Seconds",!1),ib.fn.minute=ib.fn.minutes=eb("Minutes",!1),ib.fn.hour=ib.fn.hours=eb("Hours",!0),ib.fn.date=eb("Date",!0),ib.fn.dates=c("dates accessor is deprecated. Use date instead.",eb("Date",!0)),ib.fn.year=eb("FullYear",!0),ib.fn.years=c("years accessor is deprecated. Use year instead.",eb("FullYear",!0)),ib.fn.days=ib.fn.day,ib.fn.months=ib.fn.month,ib.fn.weeks=ib.fn.week,ib.fn.isoWeeks=ib.fn.isoWeek,ib.fn.quarters=ib.fn.quarter,ib.fn.toJSON=ib.fn.toISOString,i(ib.duration.fn=h.prototype,{_bubble:function(){var a,b,c,d,e=this._milliseconds,f=this._days,g=this._months,h=this._data;h.milliseconds=e%1e3,a=k(e/1e3),h.seconds=a%60,b=k(a/60),h.minutes=b%60,c=k(b/60),h.hours=c%24,f+=k(c/24),h.days=f%30,g+=k(f/30),h.months=g%12,d=k(g/12),h.years=d},weeks:function(){return k(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*t(this._months/12)},humanize:function(a){var b=+this,c=Z(b,!a,this.lang());return a&&(c=this.lang().pastFuture(b,c)),this.lang().postformat(c)},add:function(a,b){var c=ib.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=ib.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=q(a),this[a.toLowerCase()+"s"]()},as:function(a){return a=q(a),this["as"+a.charAt(0).toUpperCase()+a.slice(1)+"s"]()},lang:ib.fn.lang,toIsoString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"}});for(kb in Yb)Yb.hasOwnProperty(kb)&&(gb(kb,Yb[kb]),fb(kb.toLowerCase()));gb("Weeks",6048e5),ib.duration.fn.asMonths=function(){return(+this-31536e6*this.years())/2592e6+12*this.years()},ib.lang("en",{ordinal:function(a){var b=a%10,c=1===t(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),xb?module.exports=ib:"function"==typeof define&&define.amd?(define("moment",function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(mb.moment=jb),ib}),hb(!0)):hb()}).call(this);
\ No newline at end of file +(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function d(a,b){function c(){mb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}var d=!0;return j(function(){return d&&(c(),d=!1),b.apply(this,arguments)},b)}function e(a,b){return function(c){return m(a.call(this,c),b)}}function f(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function g(){}function h(a){z(a),j(this,a)}function i(a){var b=s(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._bubble()}function j(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function k(a){var b,c={};for(b in a)a.hasOwnProperty(b)&&Ab.hasOwnProperty(b)&&(c[b]=a[b]);return c}function l(a){return 0>a?Math.ceil(a):Math.floor(a)}function m(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.length<b;)d="0"+d;return(e?c?"+":"":"-")+d}function n(a,b,c,d){var e=b._milliseconds,f=b._days,g=b._months;d=null==d?!0:d,e&&a._d.setTime(+a._d+e*c),f&&hb(a,"Date",gb(a,"Date")+f*c),g&&fb(a,gb(a,"Month")+g*c),d&&mb.updateOffset(a,f||g)}function o(a){return"[object Array]"===Object.prototype.toString.call(a)}function p(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function q(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&u(a[d])!==u(b[d]))&&g++;return g+f}function r(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=bc[a]||cc[b]||b}return a}function s(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=r(c),b&&(d[b]=a[c]));return d}function t(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}mb[b]=function(e,f){var g,h,i=mb.fn._lang[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=mb().utc().set(d,a);return i.call(mb.fn._lang,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function u(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function v(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function w(a,b,c){return bb(mb([a,11,31+b-c]),b,c).week}function x(a){return y(a)?366:365}function y(a){return a%4===0&&a%100!==0||a%400===0}function z(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[tb]<0||a._a[tb]>11?tb:a._a[ub]<1||a._a[ub]>v(a._a[sb],a._a[tb])?ub:a._a[vb]<0||a._a[vb]>23?vb:a._a[wb]<0||a._a[wb]>59?wb:a._a[xb]<0||a._a[xb]>59?xb:a._a[yb]<0||a._a[yb]>999?yb:-1,a._pf._overflowDayOfYear&&(sb>b||b>ub)&&(b=ub),a._pf.overflow=b)}function A(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function B(a){return a?a.toLowerCase().replace("_","-"):a}function C(a,b){return b._isUTC?mb(a).zone(b._offset||0):mb(a).local()}function D(a,b){return b.abbr=a,zb[a]||(zb[a]=new g),zb[a].set(b),zb[a]}function E(a){delete zb[a]}function F(a){var b,c,d,e,f=0,g=function(a){if(!zb[a]&&Bb)try{require("./lang/"+a)}catch(b){}return zb[a]};if(!a)return mb.fn._lang;if(!o(a)){if(c=g(a))return c;a=[a]}for(;f<a.length;){for(e=B(a[f]).split("-"),b=e.length,d=B(a[f+1]),d=d?d.split("-"):null;b>0;){if(c=g(e.slice(0,b).join("-")))return c;if(d&&d.length>=b&&q(e,d,!0)>=b-1)break;b--}f++}return mb.fn._lang}function G(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function H(a){var b,c,d=a.match(Fb);for(b=0,c=d.length;c>b;b++)d[b]=hc[d[b]]?hc[d[b]]:G(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function I(a,b){return a.isValid()?(b=J(b,a.lang()),dc[b]||(dc[b]=H(b)),dc[b](a)):a.lang().invalidDate()}function J(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Gb.lastIndex=0;d>=0&&Gb.test(a);)a=a.replace(Gb,c),Gb.lastIndex=0,d-=1;return a}function K(a,b){var c,d=b._strict;switch(a){case"Q":return Rb;case"DDDD":return Tb;case"YYYY":case"GGGG":case"gggg":return d?Ub:Jb;case"Y":case"G":case"g":return Wb;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?Vb:Kb;case"S":if(d)return Rb;case"SS":if(d)return Sb;case"SSS":if(d)return Tb;case"DDD":return Ib;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Mb;case"a":case"A":return F(b._l)._meridiemParse;case"X":return Pb;case"Z":case"ZZ":return Nb;case"T":return Ob;case"SSSS":return Lb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?Sb:Hb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Hb;case"Do":return Qb;default:return c=new RegExp(T(S(a.replace("\\","")),"i"))}}function L(a){a=a||"";var b=a.match(Nb)||[],c=b[b.length-1]||[],d=(c+"").match(_b)||["-",0,0],e=+(60*d[1])+u(d[2]);return"+"===d[0]?-e:e}function M(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[tb]=3*(u(b)-1));break;case"M":case"MM":null!=b&&(e[tb]=u(b)-1);break;case"MMM":case"MMMM":d=F(c._l).monthsParse(b),null!=d?e[tb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[ub]=u(b));break;case"Do":null!=b&&(e[ub]=u(parseInt(b,10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=u(b));break;case"YY":e[sb]=mb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[sb]=u(b);break;case"a":case"A":c._isPm=F(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[vb]=u(b);break;case"m":case"mm":e[wb]=u(b);break;case"s":case"ss":e[xb]=u(b);break;case"S":case"SS":case"SSS":case"SSSS":e[yb]=u(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=L(b);break;case"dd":case"ddd":case"dddd":d=F(c._l).weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=u(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=mb.parseTwoDigitYear(b)}}function N(a){var c,d,e,f,g,h,i,j;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[sb],bb(mb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(j=F(a._l),g=j._week.dow,h=j._week.doy,d=b(c.gg,a._a[sb],bb(mb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=cb(d,e,f,h,g),a._a[sb]=i.year,a._dayOfYear=i.dayOfYear}function O(a){var c,d,e,f,g=[];if(!a._d){for(e=Q(a),a._w&&null==a._a[ub]&&null==a._a[tb]&&N(a),a._dayOfYear&&(f=b(a._a[sb],e[sb]),a._dayOfYear>x(f)&&(a._pf._overflowDayOfYear=!0),d=Z(f,0,a._dayOfYear),a._a[tb]=d.getUTCMonth(),a._a[ub]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];a._d=(a._useUTC?Z:Y).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()+a._tzm)}}function P(a){var b;a._d||(b=s(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],O(a))}function Q(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function R(a){if(a._f===mb.ISO_8601)return void V(a);a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=F(a._l),h=""+a._i,i=h.length,j=0;for(d=J(a._f,g).match(Fb)||[],b=0;b<d.length;b++)e=d[b],c=(h.match(K(e,a))||[])[0],c&&(f=h.substr(0,h.indexOf(c)),f.length>0&&a._pf.unusedInput.push(f),h=h.slice(h.indexOf(c)+c.length),j+=c.length),hc[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),M(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=i-j,h.length>0&&a._pf.unusedInput.push(h),a._isPm&&a._a[vb]<12&&(a._a[vb]+=12),a._isPm===!1&&12===a._a[vb]&&(a._a[vb]=0),O(a),z(a)}function S(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function T(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function U(a){var b,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;f<a._f.length;f++)g=0,b=j({},a),b._pf=c(),b._f=a._f[f],R(b),A(b)&&(g+=b._pf.charsLeftOver,g+=10*b._pf.unusedTokens.length,b._pf.score=g,(null==e||e>g)&&(e=g,d=b));j(a,d||b)}function V(a){var b,c,d=a._i,e=Xb.exec(d);if(e){for(a._pf.iso=!0,b=0,c=Zb.length;c>b;b++)if(Zb[b][1].exec(d)){a._f=Zb[b][0]+(e[6]||" ");break}for(b=0,c=$b.length;c>b;b++)if($b[b][1].exec(d)){a._f+=$b[b][0];break}d.match(Nb)&&(a._f+="Z"),R(a)}else a._isValid=!1}function W(a){V(a),a._isValid===!1&&(delete a._isValid,mb.createFromInputFallback(a))}function X(b){var c=b._i,d=Cb.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?W(b):o(c)?(b._a=c.slice(0),O(b)):p(c)?b._d=new Date(+c):"object"==typeof c?P(b):"number"==typeof c?b._d=new Date(c):mb.createFromInputFallback(b)}function Y(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function Z(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function $(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function _(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function ab(a,b,c){var d=rb(Math.abs(a)/1e3),e=rb(d/60),f=rb(e/60),g=rb(f/24),h=rb(g/365),i=d<ec.s&&["s",d]||1===e&&["m"]||e<ec.m&&["mm",e]||1===f&&["h"]||f<ec.h&&["hh",f]||1===g&&["d"]||g<=ec.dd&&["dd",g]||g<=ec.dm&&["M"]||g<ec.dy&&["MM",rb(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,_.apply({},i)}function bb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=mb(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function cb(a,b,c,d,e){var f,g,h=Z(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:x(a-1)+g}}function db(b){var c=b._i,d=b._f;return null===c||d===a&&""===c?mb.invalid({nullInput:!0}):("string"==typeof c&&(b._i=c=F().preparse(c)),mb.isMoment(c)?(b=k(c),b._d=new Date(+c._d)):d?o(d)?U(b):R(b):X(b),new h(b))}function eb(a,b){var c,d;if(1===b.length&&o(b[0])&&(b=b[0]),!b.length)return mb();for(c=b[0],d=1;d<b.length;++d)b[d][a](c)&&(c=b[d]);return c}function fb(a,b){var c;return"string"==typeof b&&(b=a.lang().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),v(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function gb(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function hb(a,b,c){return"Month"===b?fb(a,c):a._d["set"+(a._isUTC?"UTC":"")+b](c)}function ib(a,b){return function(c){return null!=c?(hb(this,a,c),mb.updateOffset(this,b),this):gb(this,a)}}function jb(a){mb.duration.fn[a]=function(){return this._data[a]}}function kb(a,b){mb.duration.fn["as"+a]=function(){return+this/b}}function lb(a){"undefined"==typeof ender&&(nb=qb.moment,qb.moment=a?d("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.",mb):mb)}for(var mb,nb,ob,pb="2.7.0",qb="undefined"!=typeof global?global:this,rb=Math.round,sb=0,tb=1,ub=2,vb=3,wb=4,xb=5,yb=6,zb={},Ab={_isAMomentObject:null,_i:null,_f:null,_l:null,_strict:null,_tzm:null,_isUTC:null,_offset:null,_pf:null,_lang:null},Bb="undefined"!=typeof module&&module.exports,Cb=/^\/?Date\((\-?\d+)/i,Db=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Eb=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Fb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,Gb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,Hb=/\d\d?/,Ib=/\d{1,3}/,Jb=/\d{1,4}/,Kb=/[+\-]?\d{1,6}/,Lb=/\d+/,Mb=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Nb=/Z|[\+\-]\d\d:?\d\d/gi,Ob=/T/i,Pb=/[\+\-]?\d+(\.\d{1,3})?/,Qb=/\d{1,2}/,Rb=/\d/,Sb=/\d\d/,Tb=/\d{3}/,Ub=/\d{4}/,Vb=/[+-]?\d{6}/,Wb=/[+-]?\d+/,Xb=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Yb="YYYY-MM-DDTHH:mm:ssZ",Zb=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],$b=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],_b=/([\+\-]|\d\d)/gi,ac=("Date|Hours|Minutes|Seconds|Milliseconds".split("|"),{Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6}),bc={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",Q:"quarter",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},cc={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},dc={},ec={s:45,m:45,h:22,dd:25,dm:45,dy:345},fc="DDD w W M D d".split(" "),gc="M D H h m s w W".split(" "),hc={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return m(this.year()%100,2)},YYYY:function(){return m(this.year(),4)},YYYYY:function(){return m(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+m(Math.abs(a),6)},gg:function(){return m(this.weekYear()%100,2)},gggg:function(){return m(this.weekYear(),4)},ggggg:function(){return m(this.weekYear(),5)},GG:function(){return m(this.isoWeekYear()%100,2)},GGGG:function(){return m(this.isoWeekYear(),4)},GGGGG:function(){return m(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return u(this.milliseconds()/100)},SS:function(){return m(u(this.milliseconds()/10),2)},SSS:function(){return m(this.milliseconds(),3)},SSSS:function(){return m(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+m(u(a/60),2)+":"+m(u(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+m(u(a/60),2)+m(u(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},ic=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];fc.length;)ob=fc.pop(),hc[ob+"o"]=f(hc[ob],ob);for(;gc.length;)ob=gc.pop(),hc[ob+ob]=e(hc[ob],2);for(hc.DDDD=e(hc.DDD,3),j(g.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=mb.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=mb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return bb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),mb=function(b,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=d,g._l=e,g._strict=f,g._isUTC=!1,g._pf=c(),db(g)},mb.suppressDeprecationWarnings=!1,mb.createFromInputFallback=d("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i)}),mb.min=function(){var a=[].slice.call(arguments,0);return eb("isBefore",a)},mb.max=function(){var a=[].slice.call(arguments,0);return eb("isAfter",a)},mb.utc=function(b,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=d,g._strict=f,g._pf=c(),db(g).utc()},mb.unix=function(a){return mb(1e3*a)},mb.duration=function(a,b){var c,d,e,f=a,g=null;return mb.isDuration(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(g=Db.exec(a))?(c="-"===g[1]?-1:1,f={y:0,d:u(g[ub])*c,h:u(g[vb])*c,m:u(g[wb])*c,s:u(g[xb])*c,ms:u(g[yb])*c}):(g=Eb.exec(a))&&(c="-"===g[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},f={y:e(g[2]),M:e(g[3]),d:e(g[4]),h:e(g[5]),m:e(g[6]),s:e(g[7]),w:e(g[8])}),d=new i(f),mb.isDuration(a)&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},mb.version=pb,mb.defaultFormat=Yb,mb.ISO_8601=function(){},mb.momentProperties=Ab,mb.updateOffset=function(){},mb.relativeTimeThreshold=function(b,c){return ec[b]===a?!1:(ec[b]=c,!0)},mb.lang=function(a,b){var c;return a?(b?D(B(a),b):null===b?(E(a),a="en"):zb[a]||F(a),c=mb.duration.fn._lang=mb.fn._lang=F(a),c._abbr):mb.fn._lang._abbr},mb.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),F(a)},mb.isMoment=function(a){return a instanceof h||null!=a&&a.hasOwnProperty("_isAMomentObject")},mb.isDuration=function(a){return a instanceof i},ob=ic.length-1;ob>=0;--ob)t(ic[ob]);mb.normalizeUnits=function(a){return r(a)},mb.invalid=function(a){var b=mb.utc(0/0);return null!=a?j(b._pf,a):b._pf.userInvalidated=!0,b},mb.parseZone=function(){return mb.apply(null,arguments).parseZone()},mb.parseTwoDigitYear=function(a){return u(a)+(u(a)>68?1900:2e3)},j(mb.fn=h.prototype,{clone:function(){return mb(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=mb(this).utc();return 0<a.year()&&a.year()<=9999?I(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):I(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return A(this)},isDSTShifted:function(){return this._a?this.isValid()&&q(this._a,(this._isUTC?mb.utc(this._a):mb(this._a)).toArray())>0:!1},parsingFlags:function(){return j({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=I(this,a||mb.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a&&"string"==typeof b?mb.duration(isNaN(+b)?+a:+b,isNaN(+b)?b:a):"string"==typeof a?mb.duration(+b,a):mb.duration(a,b),n(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a&&"string"==typeof b?mb.duration(isNaN(+b)?+a:+b,isNaN(+b)?b:a):"string"==typeof a?mb.duration(+b,a):mb.duration(a,b),n(this,c,-1),this},diff:function(a,b,c){var d,e,f=C(a,this),g=6e4*(this.zone()-f.zone());return b=r(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-mb(this).startOf("month")-(f-mb(f).startOf("month")))/d,e-=6e4*(this.zone()-mb(this).startOf("month").zone()-(f.zone()-mb(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:l(e)},from:function(a,b){return mb.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(mb(),a)},calendar:function(a){var b=a||mb(),c=C(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.lang().calendar(e,this))},isLeapYear:function(){return y(this.year())},isDST:function(){return this.zone()<this.clone().month(0).zone()||this.zone()<this.clone().month(5).zone()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=$(a,this.lang()),this.add({d:a-b})):b},month:ib("Month",!0),startOf:function(a){switch(a=r(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(a){return a=r(a),this.startOf(a).add("isoWeek"===a?"week":a,1).subtract("ms",1)},isAfter:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)>+mb(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+mb(a).startOf(b)},isSame:function(a,b){return b=b||"ms",+this.clone().startOf(b)===+C(a,this).startOf(b)},min:d("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(a){return a=mb.apply(null,arguments),this>a?this:a}),max:d("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=mb.apply(null,arguments),a>this?this:a}),zone:function(a,b){var c=this._offset||0;return null==a?this._isUTC?c:this._d.getTimezoneOffset():("string"==typeof a&&(a=L(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,c!==a&&(!b||this._changeInProgress?n(this,mb.duration(c-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,mb.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?mb(a).zone():0,(this.zone()-a)%60===0},daysInMonth:function(){return v(this.year(),this.month())},dayOfYear:function(a){var b=rb((mb(this).startOf("day")-mb(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=bb(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=bb(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=bb(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this.day()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return w(this.year(),1,4)},weeksInYear:function(){var a=this._lang._week;return w(this.year(),a.dow,a.doy)},get:function(a){return a=r(a),this[a]()},set:function(a,b){return a=r(a),"function"==typeof this[a]&&this[a](b),this},lang:function(b){return b===a?this._lang:(this._lang=F(b),this)}}),mb.fn.millisecond=mb.fn.milliseconds=ib("Milliseconds",!1),mb.fn.second=mb.fn.seconds=ib("Seconds",!1),mb.fn.minute=mb.fn.minutes=ib("Minutes",!1),mb.fn.hour=mb.fn.hours=ib("Hours",!0),mb.fn.date=ib("Date",!0),mb.fn.dates=d("dates accessor is deprecated. Use date instead.",ib("Date",!0)),mb.fn.year=ib("FullYear",!0),mb.fn.years=d("years accessor is deprecated. Use year instead.",ib("FullYear",!0)),mb.fn.days=mb.fn.day,mb.fn.months=mb.fn.month,mb.fn.weeks=mb.fn.week,mb.fn.isoWeeks=mb.fn.isoWeek,mb.fn.quarters=mb.fn.quarter,mb.fn.toJSON=mb.fn.toISOString,j(mb.duration.fn=i.prototype,{_bubble:function(){var a,b,c,d,e=this._milliseconds,f=this._days,g=this._months,h=this._data;h.milliseconds=e%1e3,a=l(e/1e3),h.seconds=a%60,b=l(a/60),h.minutes=b%60,c=l(b/60),h.hours=c%24,f+=l(c/24),h.days=f%30,g+=l(f/30),h.months=g%12,d=l(g/12),h.years=d},weeks:function(){return l(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*u(this._months/12)},humanize:function(a){var b=+this,c=ab(b,!a,this.lang());return a&&(c=this.lang().pastFuture(b,c)),this.lang().postformat(c)},add:function(a,b){var c=mb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=mb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=r(a),this[a.toLowerCase()+"s"]()},as:function(a){return a=r(a),this["as"+a.charAt(0).toUpperCase()+a.slice(1)+"s"]()},lang:mb.fn.lang,toIsoString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"}});for(ob in ac)ac.hasOwnProperty(ob)&&(kb(ob,ac[ob]),jb(ob.toLowerCase()));kb("Weeks",6048e5),mb.duration.fn.asMonths=function(){return(+this-31536e6*this.years())/2592e6+12*this.years()},mb.lang("en",{ordinal:function(a){var b=a%10,c=1===u(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),Bb?module.exports=mb:"function"==typeof define&&define.amd?(define("moment",function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(qb.moment=nb),mb}),lb(!0)):lb()}).call(this);
\ No newline at end of file diff --git a/l10n/de.php b/l10n/de.php index 50940550..f3dcb3ac 100644 --- a/l10n/de.php +++ b/l10n/de.php @@ -86,4 +86,20 @@ "Friday" => "Freitag", "Saturday" => "Samstag", "Sunday" => "Sonntag", +"Add Comment" => "Kommentar hinzufügen", +"in %s" => "in %s", +"%s ago" => "vor %s", +"seconds" => "einigen Sekunden", +"a minute" => "einer Minute", +"%d minutes" => "%d Minuten", +"an hour" => "einer Stunde", +"%d hours" => "%d Stunden", +"a day" => "ein Tag", +"%d days" => "%d Tagen", +"a month" => "einem Monat", +"%d months" => "%d Monaten", +"a year" => "einem Jahr", +"%d years" => "%d Jahren", +"Add a comment" => "Kommentar hinzufügen", +"Comment" => "Kommentieren" );
\ No newline at end of file diff --git a/lib/controller/settingscontroller.php b/lib/controller/settingscontroller.php index eb6504a5..d02d0e2a 100644 --- a/lib/controller/settingscontroller.php +++ b/lib/controller/settingscontroller.php @@ -36,7 +36,9 @@ class SettingsController extends Controller { array( 'id' => 'various', 'showHidden' => (int)\OCP\Config::getUserValue($this->api->getUserId(), 'tasks_enhanced','various_showHidden'), - 'startOfWeek' => (int)\OCP\Config::getUserValue($this->api->getUserId(), 'tasks_enhanced','various_startOfWeek') + 'startOfWeek' => (int)\OCP\Config::getUserValue($this->api->getUserId(), 'tasks_enhanced','various_startOfWeek'), + 'userID' => $this->api->getUserId() + ) ); $result = array( diff --git a/lib/controller/taskscontroller.php b/lib/controller/taskscontroller.php index 5ac072f0..e18f7811 100644 --- a/lib/controller/taskscontroller.php +++ b/lib/controller/taskscontroller.php @@ -149,7 +149,7 @@ class TasksController extends Controller { /** * @NoAdminRequired */ - public function percentComplete( $percentCompete ){ + public function percentComplete(){ $response = new JSONResponse(); try{ $percent_complete = $this->params('complete'); @@ -439,15 +439,13 @@ class TasksController extends Controller { } } - - return $response; } /** * @NoAdminRequired */ - public function setCategories($taskId, $categories){ + public function setCategories(){ $taskId = $this->params('taskID'); $categories = $this->params('categories'); $response = new JSONResponse(); @@ -465,7 +463,7 @@ class TasksController extends Controller { /** * @NoAdminRequired */ - public function setLocation($taskId, $location){ + public function setLocation(){ $taskId = $this->params('taskID'); $location = $this->params('location'); $response = new JSONResponse(); @@ -480,5 +478,93 @@ class TasksController extends Controller { return $response; } + /** + * @NoAdminRequired + */ + public function addComment(){ + $taskId = $this->params('taskID'); + $comment = $this->params('comment'); + $userId = $this->api->getUserId(); + $response = new JSONResponse(); + try { + $vcalendar = \OC_Calendar_App::getVCalendar($taskId); + $vtodo = $vcalendar->VTODO; + + // Determine new commentId by looping through all comments + $commentIds = array(); + foreach($vtodo->COMMENT as $com) { + $commentIds[] = (int)$com['ID']->value; + } + $commentId = 1+max($commentIds); + + $now = new \DateTime(); + $vtodo->addProperty('COMMENT',$comment, + array( + 'ID' => $commentId, + 'USERID' => $userId, + 'DATE-TIME' => $now->format('Ymd\THis\Z') + ) + ); + \OC_Calendar_Object::edit($taskId, $vcalendar->serialize()); + $user_timezone = \OC_Calendar_App::getTimezone(); + $now->setTimezone(new \DateTimeZone($user_timezone)); + $comment = array( + 'taskID' => $taskId, + 'id' => $commentId, + 'tmpID' => $this->params('tmpID'), + 'name' => \OCP\USER::getDisplayName(), + 'userID' => $userId, + 'comment' => $comment, + 'time' => $now->format('Ymd\THis') + ); + $result = array( + 'data' => array( + 'comment' => $comment + ) + ); + $response->setData($result); + } catch(\Exception $e) { + // throw new BusinessLayerException($e->getMessage()); + } + return $response; + } -} + /** + * @NoAdminRequired + */ + public function deleteComment(){ + $taskId = $this->params('taskID'); + $commentId = $this->params('commentID'); + $userId = $this->api->getUserId(); + $response = new JSONResponse(); + try { + $vcalendar = \OC_Calendar_App::getVCalendar($taskId); + $vtodo = $vcalendar->VTODO; + $commentIndex = $this->getCommentById($vtodo,$commentId); + $comment = $vtodo->children[$commentIndex]; + if($comment['USERID'] == $userId){ + unset($vtodo->children[$commentIndex]); + \OC_Calendar_Object::edit($taskId, $vcalendar->serialize()); + }else{ + throw new \Exception('Not allowed.'); + } + } catch(\Exception $e) { + // throw new BusinessLayerException($e->getMessage()); + } + return $response; + } + + /** + * @NoAdminRequired + */ + public function getCommentById($vtodo,$commentId) { + $idx = 0; + foreach ($vtodo->children as $i => &$property) { + if ( $property->name == 'COMMENT' && $property['ID']->value == $commentId ) { + return $idx; + } + $idx += 1; + } + throw new \Exception('Commment not found.'); + } +}
\ No newline at end of file diff --git a/lib/helper.php b/lib/helper.php index aabecbf7..94ab287a 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -169,6 +169,23 @@ Class helper { $task['completed'] = false; } $task['complete'] = $vtodo->getAsString('PERCENT-COMPLETE')==''?'0':$vtodo->getAsString('PERCENT-COMPLETE'); + $comments = $vtodo->COMMENT; + if($comments){ + $comments_parsed = array(); + foreach($comments as $com) { + $time = new \DateTime($com['DATE-TIME']->value); + $time->setTimezone(new \DateTimeZone($user_timezone)); + $time = $time->format('Ymd\THis'); + $comments_parsed[] = array( + 'id' => (int)$com['ID']->value, + 'userID' => $com['USERID']->value, + 'name' => \OCP\USER::getDisplayName($com['USERID']->value), + 'comment' => $com->value, + 'time' => $time + ); + } + } + $task['comments'] = $comments_parsed; return $task; } diff --git a/templates/part.details.php b/templates/part.details.php index ce0a5534..b1522fd1 100644 --- a/templates/part.details.php +++ b/templates/part.details.php @@ -85,26 +85,45 @@ </div> </div> <!-- <ul class="subtasks buffer"></ul> --> - <div class="note"> - <div class="note-body selectable" ng-click="editNote()" stop-event="click" oc-click-focus="{selector: '.expandingArea textarea', timeout: 0}"> - <!-- - <a class="open-fullscreen-note"> - <span class="icon note-fullscreen"></span> - </a> - --> - <div class="content-fakeable"> - <div class="display-view" ng-hide="route.parameter=='note'">{{ task.note }}</div> - <div class="edit-view" ng-show="route.parameter=='note'"> - <div class="expandingArea active"> - <pre><span>{{ task.note }}</span><br /><br /></pre> - <textarea ng-model="task.note"></textarea> + <div class="section detail-note"> + <div class="note"> + <div class="note-body selectable" ng-click="editNote()" stop-event="click" oc-click-focus="{selector: '.expandingArea textarea', timeout: 0}"> + <!-- + <a class="open-fullscreen-note"> + <span class="icon note-fullscreen"></span> + </a> + --> + <div class="content-fakeable"> + <div class="display-view" ng-hide="route.parameter=='note'">{{ task.note }}</div> + <div class="edit-view" ng-show="route.parameter=='note'"> + <div class="expandingArea active"> + <pre><span>{{ task.note }}</span><br /><br /></pre> + <textarea ng-model="task.note"></textarea> + </div> </div> </div> </div> </div> </div> + <div class="section detail-comments"> + <ul> + <li ng-repeat="comment in task.comments" class="comment-item" rel=" {{ comment.id }} "> + <div class="avatar" avatar userID="{{ comment.userID }}" size="32"></div> + <a class="detail-delete" ng-click="deleteComment(comment.id)" stop-event="click" ng-show="settingsmodel.getById('various').userID == comment.userID"> + <span class="icon detail-delete"></span> + </a> + <span class="username">{{ comment.name }}</span> + <div class="comment">{{ comment.comment }}</div> + <span class="time"> {{ comment.time | dateFromNow }} </span> + </li> + </ul> + </div> </div> <div class="footer"> + <div class="detail-addcomment"> + <input type="text" placeholder="{{ commentStrings().input }}" ng-model="CommentContent" ng-keydown="sendComment($event)"> + <input type="button" ng-click="addComment()" name="addComment" value="{{ commentStrings().button }}" ng-class="{'active':CommentContent}"> + </div> <a class="detail-trash" ng-click="deleteTask(task.id)" stop-event="click"> <span class="icon detail-trash"></span> </a> |