"),$el.after(loadingElm),$el.on("click",function(event){return event.preventDefault(),excludeClosedSprints=!excludeClosedSprints,$loading.start(loadingElm),$rootscope.$broadcast(excludeClosedSprints?"backlog:unload-closed-sprints":"backlog:load-closed-sprints")}),$scope.$on("$destroy",function(){return $el.off()}),$scope.$on("closed-sprints:reloaded",function(){return function(ctx,sprints){var text;return $loading.finish(loadingElm),text=sprints.length>0?"Hide closed sprints":"Show closed sprints",$el.find(".text").text(text)}}(this))},{link:link}},module.directive("tgBacklogToggleClosedSprintsVisualization",["$rootScope","$tgLoading",ToggleExcludeClosedSprintsVisualization])}.call(this),function(){var SprintGraphDirective,bindOnce,groupBy,mixOf,module,scopeDefer,taiga,timeout,toggleText;taiga=this.taiga,mixOf=this.taiga.mixOf,toggleText=this.taiga.toggleText,scopeDefer=this.taiga.scopeDefer,bindOnce=this.taiga.bindOnce,groupBy=this.taiga.groupBy,timeout=this.taiga.timeout,module=angular.module("taigaTaskboard"),SprintGraphDirective=function(){var link,redrawChart;return redrawChart=function(element,dataToDraw){var data,days,options,width;return width=element.width(),element.height(240),days=_.map(dataToDraw,function(x){return moment(x.day)}),data=[],data.unshift({data:_.zip(days,_.map(dataToDraw,function(d){return d.optimal_points})),lines:{fillColor:"rgba(120,120,120,0.2)"}}),data.unshift({data:_.zip(days,_.map(dataToDraw,function(d){return d.open_points})),lines:{fillColor:"rgba(102,153,51,0.3)"}}),options={grid:{borderWidth:{top:0,right:1,left:0,bottom:0},borderColor:"#ccc",hoverable:!0},xaxis:{tickSize:[1,"day"],min:days[0],max:_.last(days),mode:"time",daysNames:days,axisLabel:"Day",axisLabelUseCanvas:!0,axisLabelFontSizePixels:12,axisLabelFontFamily:"Verdana, Arial, Helvetica, Tahoma, sans-serif",axisLabelPadding:5},yaxis:{min:0},series:{shadowSize:0,lines:{show:!0,fill:!0},points:{show:!0,fill:!0,radius:4,lineWidth:2}},colors:["rgba(102,153,51,1)","rgba(120,120,120,0.2)"],tooltip:!0,tooltipOpts:{content:function(label,xval,yval,flotItem){var formattedDate,roundedValue;return formattedDate=moment(xval).format("DD MMM"),roundedValue=Math.round(yval),1===flotItem.seriesIndex?"Optimal pending points for day "+formattedDate+" should be "+roundedValue:"Real pending points for day "+formattedDate+" is "+roundedValue}}},element.empty(),element.plot(data,options).data("plot")},link=function($scope,$el){var element;return element=angular.element($el),$scope.$on("resize",function(){return $scope.stats?redrawChart(element,$scope.stats.days):void 0}),$scope.$on("taskboard:graph:toggle-visibility",function(){return $el.parent().toggleClass("open"),timeout(100,function(){return $scope.stats?redrawChart(element,$scope.stats.days):void 0})}),$scope.$watch("stats",function(){return null!=$scope.stats?redrawChart(element,$scope.stats.days):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgSprintGraph",SprintGraphDirective)}.call(this),function(){var CreateBulkTasksDirective,CreateEditTaskDirective,bindOnce,debounce,module,taiga;taiga=this.taiga,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,CreateEditTaskDirective=function($repo,$model,$rs,$rootscope,$loading,lightboxService){var link;return link=function($scope,$el){var submit,submitButton;return $scope.isNew=!0,$scope.$on("taskform:new",function(ctx,sprintId,usId){return $scope.task={project:$scope.projectId,milestone:sprintId,user_story:usId,is_archived:!1,status:$scope.project.default_task_status,assigned_to:null,tags:[]},$scope.isNew=!0,$el.find(".button-green").html("Create"),$el.find(".title").html("New task "),$el.find(".tag-input").val(""),lightboxService.open($el)}),$scope.$on("taskform:edit",function(ctx,task){return $scope.task=task,$scope.isNew=!1,$el.find(".button-green").html("Save"),$el.find(".title").html("Edit task "),$el.find(".tag-input").val(""),lightboxService.open($el)}),submitButton=$el.find(".submit-button"),submit=debounce(2e3,function(){return function(event){var broadcastEvent,form,promise;return event.preventDefault(),form=$el.find("form").checksley(),form.validate()?($scope.isNew?(promise=$repo.create("tasks",$scope.task),broadcastEvent="taskform:new:success"):(promise=$repo.save($scope.task),broadcastEvent="taskform:edit:success"),$loading.start(submitButton),promise.then(function(data){return $loading.finish(submitButton),lightboxService.close($el),$rootscope.$broadcast(broadcastEvent,data)})):void 0}}(this)),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},CreateBulkTasksDirective=function($repo,$rs,$rootscope,$loading,lightboxService){var link;return link=function($scope,$el){var submit,submitButton;return $scope.form={data:"",usId:null},submit=debounce(2e3,function(){return function(event){var data,form,projectId,promise,sprintId,usId;return event.preventDefault(),form=$el.find("form").checksley(),form.validate()?($loading.start(submitButton),data=$scope.form.data,projectId=$scope.projectId,sprintId=$scope.form.sprintId,usId=$scope.form.usId,promise=$rs.tasks.bulkCreate(projectId,sprintId,usId,data),promise.then(function(result){return $loading.finish(submitButton),$rootscope.$broadcast("taskform:bulk:success",result),lightboxService.close($el)}),promise.then(null,function(){return $loading.finish(submitButton),console.log("FAIL")})):void 0}}(this)),$scope.$on("taskform:bulk",function(ctx,sprintId,usId){return lightboxService.open($el),$scope.form={data:"",sprintId:sprintId,usId:usId}}),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module=angular.module("taigaTaskboard"),module.directive("tgLbCreateEditTask",["$tgRepo","$tgModel","$tgResources","$rootScope","$tgLoading","lightboxService",CreateEditTaskDirective]),module.directive("tgLbCreateBulkTasks",["$tgRepo","$tgResources","$rootScope","$tgLoading","lightboxService",CreateBulkTasksDirective])}.call(this),function(){var TaskboardController,TaskboardDirective,TaskboardSquishColumnDirective,TaskboardTaskDirective,TaskboardUserDirective,bindMethods,bindOnce,groupBy,mixOf,module,scopeDefer,taiga,timeout,toggleText,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,toggleText=this.taiga.toggleText,mixOf=this.taiga.mixOf,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,scopeDefer=this.taiga.scopeDefer,timeout=this.taiga.timeout,bindMethods=this.taiga.bindMethods,module=angular.module("taigaTaskboard"),TaskboardController=function(superClass){function TaskboardController(scope,rootscope,repo,confirm,rs1,params1,q,appTitle,location,navUrls,events,analytics,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs1,this.params=params1,this.q=q,this.appTitle=appTitle,this.location=location,this.navUrls=navUrls,this.events=events,this.analytics=analytics,bindMethods(this),this.scope.sectionName="Taskboard",this.initializeEventHandlers(),promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Taskboard - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(TaskboardController,superClass),TaskboardController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$appTitle","$tgLocation","$tgNavUrls","$tgEvents","$tgAnalytics","tgLoader"],TaskboardController.prototype.initializeEventHandlers=function(){return this.scope.$on("taskform:bulk:success",function(_this){return function(){return _this.loadTaskboard(),_this.analytics.trackEvent("task","create","bulk create task on taskboard",1)}}(this)),this.scope.$on("taskform:new:success",function(_this){return function(){return _this.loadTaskboard(),_this.analytics.trackEvent("task","create","create task on taskboard",1)}}(this)),this.scope.$on("taskform:edit:success",function(_this){return function(){return _this.loadTaskboard()}}(this)),this.scope.$on("taskboard:task:move",this.taskMove),this.scope.$on("assigned-to:added",function(_this){return function(ctx,userId,task){var promise;return task.assigned_to=userId,promise=_this.repo.save(task),promise.then(null,function(){return console.log("FAIL")})}}(this))},TaskboardController.prototype.initializeSubscription=function(){var routingKey,routingKey1;return routingKey="changes.project."+this.scope.projectId+".tasks",this.events.subscribe(this.scope,routingKey,function(_this){return function(){return _this.loadTaskboard()}}(this)),routingKey1="changes.project."+this.scope.projectId+".userstories",this.events.subscribe(this.scope,routingKey1,function(_this){return function(){return _this.refreshTagsColors(),_this.loadSprintStats(),_this.loadSprint()}}(this))},TaskboardController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.is_backlog_activated||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.pointsList=_.sortBy(project.points,"order"),_this.scope.pointsById=groupBy(project.points,function(e){return e.id}),_this.scope.roleById=groupBy(project.roles,function(e){return e.id}),_this.scope.taskStatusList=_.sortBy(project.task_statuses,"order"),_this.scope.usStatusList=_.sortBy(project.us_statuses,"order"),_this.scope.usStatusById=groupBy(project.us_statuses,function(e){return e.id}),_this.scope.$emit("project:loaded",project),_this.fillUsersAndRoles(project.users,project.roles),project}}(this))},TaskboardController.prototype.loadSprintStats=function(){return this.rs.sprints.stats(this.scope.projectId,this.scope.sprintId).then(function(_this){return function(stats){var completedPointsSum,remainingPointsSum,remainingTasks,totalPointsSum;return totalPointsSum=_.reduce(_.values(stats.total_points),function(res,n){return res+n},0),completedPointsSum=_.reduce(_.values(stats.completed_points),function(res,n){return res+n},0),remainingPointsSum=totalPointsSum-completedPointsSum,remainingTasks=stats.total_tasks-stats.completed_tasks,_this.scope.stats=stats,_this.scope.stats.totalPointsSum=totalPointsSum,_this.scope.stats.completedPointsSum=completedPointsSum,_this.scope.stats.remainingPointsSum=remainingPointsSum,_this.scope.stats.remainingTasks=remainingTasks,_this.scope.stats.completedPercentage=stats.totalPointsSum?Math.round(100*stats.completedPointsSum/stats.totalPointsSum):0,_this.scope.stats.openTasks=stats.total_tasks-stats.completed_tasks,stats}}(this))},TaskboardController.prototype.refreshTagsColors=function(){return this.rs.projects.tagsColors(this.scope.projectId).then(function(_this){return function(tags_colors){return _this.scope.project.tags_colors=tags_colors}}(this))},TaskboardController.prototype.loadSprint=function(){return this.rs.sprints.get(this.scope.projectId,this.scope.sprintId).then(function(_this){return function(sprint){return _this.scope.sprint=sprint,_this.scope.userstories=_.sortBy(sprint.user_stories,"sprint_order"),sprint}}(this))},TaskboardController.prototype.loadTasks=function(){return this.rs.tasks.list(this.scope.projectId,this.scope.sprintId).then(function(_this){return function(tasks){var i,j,k,len,len1,len2,ref,ref1,ref2,status,task,us;for(_this.scope.tasks=_.sortBy(tasks,"taskboard_order"),_this.scope.usTasks={},ref=_.union(_this.scope.userstories,[{id:null}]),i=0,len=ref.length;len>i;i++)for(us=ref[i],_this.scope.usTasks[us.id]={},ref1=_this.scope.taskStatusList,j=0,len1=ref1.length;len1>j;j++)status=ref1[j],_this.scope.usTasks[us.id][status.id]=[];for(ref2=_this.scope.tasks,k=0,len2=ref2.length;len2>k;k++)task=ref2[k],null!=_this.scope.usTasks[task.user_story]&&null!=_this.scope.usTasks[task.user_story][task.status]&&_this.scope.usTasks[task.user_story][task.status].push(task);return tasks}}(this))},TaskboardController.prototype.loadTaskboard=function(){return this.q.all([this.refreshTagsColors(),this.loadSprintStats(),this.loadSprint().then(function(_this){return function(){return _this.loadTasks()}}(this))])},TaskboardController.prototype.loadInitialData=function(){var params,promise;return params={pslug:this.params.pslug,sslug:this.params.sslug},promise=this.repo.resolve(params).then(function(_this){return function(data){return _this.scope.projectId=data.project,_this.scope.sprintId=data.milestone,_this.initializeSubscription(),data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadTaskboard()}}(this))},TaskboardController.prototype.refreshTasksOrder=function(tasks){var data,items;return items=this.resortTasks(tasks),data=this.prepareBulkUpdateData(items),this.rs.tasks.bulkUpdateTaskTaskboardOrder(this.scope.project.id,data)},TaskboardController.prototype.resortTasks=function(tasks){var i,index,item,items,len;for(items=[],index=i=0,len=tasks.length;len>i;index=++i)item=tasks[index],item.taskboard_order=index,item.isModified()&&items.push(item);return items},TaskboardController.prototype.prepareBulkUpdateData=function(uses){return _.map(uses,function(x){return{task_id:x.id,order:x.taskboard_order}})},TaskboardController.prototype.taskMove=function(ctx,task,usId,statusId,order){var promise,r,tasks;return r=this.scope.usTasks[task.user_story][task.status].indexOf(task),this.scope.usTasks[task.user_story][task.status].splice(r,1),tasks=this.scope.usTasks[usId][statusId],tasks.splice(order,0,task),task.user_story=usId,task.status=statusId,task.taskboard_order=order,promise=this.repo.save(task),this.rootscope.$broadcast("sprint:task:moved",task),promise.then(function(_this){return function(){return _this.refreshTasksOrder(tasks),_this.loadSprintStats()}}(this)),promise.then(null,function(){return function(){return console.log("FAIL TASK SAVE")}}(this))},TaskboardController.prototype.addNewTask=function(type,us){switch(type){case"standard":return this.rootscope.$broadcast("taskform:new",this.scope.sprintId,null!=us?us.id:void 0);case"bulk":return this.rootscope.$broadcast("taskform:bulk",this.scope.sprintId,null!=us?us.id:void 0)}},TaskboardController.prototype.editTaskAssignedTo=function(task){return this.rootscope.$broadcast("assigned-to:add",task)},TaskboardController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("TaskboardController",TaskboardController),TaskboardDirective=function($rootscope){var link;return link=function($scope,$el){var $ctrl,tableBodyDom;return $ctrl=$el.controller(),$el.on("click",".toggle-analytics-visibility",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),target.toggleClass("active"),$rootscope.$broadcast("taskboard:graph:toggle-visibility")}),tableBodyDom=$el.find(".taskboard-table-body"),tableBodyDom.on("scroll",function(event){var tableHeaderDom,target;return target=angular.element(event.currentTarget),tableHeaderDom=$el.find(".taskboard-table-header .taskboard-table-inner"),tableHeaderDom.css("left",-1*target.scrollLeft())}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgTaskboard",["$rootScope",TaskboardDirective]),TaskboardTaskDirective=function($rootscope){var link;return link=function($scope,$el){return $el.disableSelection(),$scope.$watch("task",function(task){return task.is_blocked&&!$el.hasClass("blocked")?$el.addClass("blocked"):!task.is_blocked&&$el.hasClass("blocked")?$el.removeClass("blocked"):void 0}),$el.find(".icon-edit").on("click",function(){return $el.find(".icon-edit").hasClass("noclick")?void 0:$scope.$apply(function(){return $rootscope.$broadcast("taskform:edit",$scope.task)})})},{link:link}},module.directive("tgTaskboardTask",["$rootScope",TaskboardTaskDirective]),TaskboardSquishColumnDirective=function(rs){var avatarWidth,link,maxColumnWidth;return avatarWidth=40,maxColumnWidth=300,link=function($scope,$el){var getCeilWidth,recalculateStatusColumnWidth,recalculateTaskboardWidth,refreshTaskboardTableWidth,setStatusColumnWidth;return $scope.$on("sprint:task:moved",function(){return function(){return recalculateTaskboardWidth()}}(this)),bindOnce($scope,"usTasks",function(){return $scope.statusesFolded=rs.tasks.getStatusColumnModes($scope.project.id),$scope.usFolded=rs.tasks.getUsRowModes($scope.project.id,$scope.sprintId),recalculateTaskboardWidth()}),$scope.foldStatus=function(status){return $scope.statusesFolded[status.id]=!$scope.statusesFolded[status.id],rs.tasks.storeStatusColumnModes($scope.projectId,$scope.statusesFolded),recalculateTaskboardWidth()},$scope.foldUs=function(us){return us?$scope.usFolded[us.id]=!$scope.usFolded[us.id]:$scope.usFolded[null]=!$scope.usFolded[null],rs.tasks.storeUsRowModes($scope.projectId,$scope.sprintId,$scope.usFolded),recalculateTaskboardWidth()},getCeilWidth=function(){return function(usId,statusId){var tasks,tasksMatrixSize,width;return tasks=$scope.usTasks[usId][statusId].length,$scope.statusesFolded[statusId]?(tasks&&$scope.usFolded[usId]?(tasksMatrixSize=Math.round(Math.sqrt(tasks)),width=avatarWidth*tasksMatrixSize):width=avatarWidth,width):0}}(this),setStatusColumnWidth=function(){return function(statusId,width){var column;return column=$el.find(".squish-status-"+statusId),width?column.css("max-width",width):column.css("max-width",maxColumnWidth)}}(this),refreshTaskboardTableWidth=function(){return function(){var columnWidths,columns,totalWidth;return columnWidths=[],columns=$el.find(".task-colum-name"),columnWidths=_.map(columns,function(column){return $(column).outerWidth(!0)}),totalWidth=_.reduce(columnWidths,function(total,width){return total+width}),$el.find(".taskboard-table-inner").css("width",totalWidth)}}(this),recalculateStatusColumnWidth=function(){return function(statusId){var statusFoldedWidth;return statusFoldedWidth=getCeilWidth(null,statusId),_.forEach($scope.userstories,function(us){var width;return width=getCeilWidth(us.id,statusId),width>statusFoldedWidth?statusFoldedWidth=width:void 0}),setStatusColumnWidth(statusId,statusFoldedWidth)}}(this),recalculateTaskboardWidth=function(){return function(){_.forEach($scope.taskStatusList,function(status){return recalculateStatusColumnWidth(status.id)}),refreshTaskboardTableWidth()}}(this)},{link:link}},module.directive("tgTaskboardSquishColumn",["$tgResources",TaskboardSquishColumnDirective]),TaskboardUserDirective=function(){var clickable,link;return clickable=!1,link=function($scope,$el){var username_label;return username_label=$el.parent().find("a.task-assigned"),username_label.addClass("not-clickable"),$scope.$watch("task.assigned_to",function(assigned_to){var user;return user=$scope.usersById[assigned_to],void 0===user?_.assign($scope,{name:"Unassigned",imgurl:"/images/unnamed.png",clickable:clickable}):_.assign($scope,{name:user.full_name_display,imgurl:user.photo,clickable:clickable}),username_label.text($scope.name)}),bindOnce($scope,"project",function(project){return project.my_permissions.indexOf("modify_task")>-1?(clickable=!0,$el.find(".avatar-assigned-to").on("click",function(){return function(){var $ctrl;if(!$el.find("a").hasClass("noclick"))return $ctrl=$el.controller(),$ctrl.editTaskAssignedTo($scope.task)}}(this)),username_label.removeClass("not-clickable"),username_label.on("click",function(){var $ctrl;if(!$el.find("a").hasClass("noclick"))return $ctrl=$el.controller(),$ctrl.editTaskAssignedTo($scope.task)})):void 0})},{link:link,templateUrl:"taskboard/taskboard-user.html",scope:{usersById:"=users",project:"=",task:"="}}},module.directive("tgTaskboardUserAvatar",["$log",TaskboardUserDirective])}.call(this),function(){var TaskboardSortableDirective,bindOnce,groupBy,mixOf,module,scopeDefer,taiga,toggleText;taiga=this.taiga,mixOf=this.taiga.mixOf,toggleText=this.taiga.toggleText,scopeDefer=this.taiga.scopeDefer,bindOnce=this.taiga.bindOnce,groupBy=this.taiga.groupBy,module=angular.module("taigaBacklog"),TaskboardSortableDirective=function($repo,$rs,$rootscope){var link;return link=function($scope,$el){return bindOnce($scope,"project",function(project){var deleteElement,itemEl,newParentScope,oldParentScope,tdom;if(project.my_permissions.indexOf("modify_us")>-1)return oldParentScope=null,newParentScope=null,itemEl=null,tdom=$el,deleteElement=function(itemEl){return itemEl.scope().$destroy(),itemEl.off(),itemEl.remove()},tdom.sortable({handle:".taskboard-task-inner",dropOnEmpty:!0,connectWith:".taskboard-tasks-box",revert:400}),tdom.on("sortstop",function(event,ui){var itemIndex,itemTask,newStatusId,newUsId,oldStatusId,oldUsId,parentEl;return parentEl=ui.item.parent(),itemEl=ui.item,itemTask=itemEl.scope().task,itemIndex=itemEl.index(),newParentScope=parentEl.scope(),oldUsId=oldParentScope.us?oldParentScope.us.id:null,oldStatusId=oldParentScope.st.id,newUsId=newParentScope.us?newParentScope.us.id:null,newStatusId=newParentScope.st.id,(newStatusId!==oldStatusId||newUsId!==oldUsId)&&deleteElement(itemEl),$scope.$apply(function(){return $rootscope.$broadcast("taskboard:task:move",itemTask,newUsId,newStatusId,itemIndex)}),ui.item.find("a").removeClass("noclick")}),tdom.on("sortstart",function(event,ui){return oldParentScope=ui.item.parent().scope(),ui.item.find("a").addClass("noclick")})}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgTaskboardSortable",["$tgRepo","$tgResources","$rootScope",TaskboardSortableDirective])}.call(this),function(){var KanbanArchivedStatusHeaderDirective,KanbanArchivedStatusIntroDirective,KanbanController,KanbanDirective,KanbanSquishColumnDirective,KanbanUserDirective,KanbanUserstoryDirective,KanbanWipLimitDirective,bindMethods,bindOnce,defaultViewMode,defaultViewModes,groupBy,mixOf,module,scopeDefer,taiga,timeout,toggleText,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,toggleText=this.taiga.toggleText,scopeDefer=this.taiga.scopeDefer,bindOnce=this.taiga.bindOnce,groupBy=this.taiga.groupBy,timeout=this.taiga.timeout,bindMethods=this.taiga.bindMethods,module=angular.module("taigaKanban"),defaultViewMode="maximized",defaultViewModes={maximized:{cardClass:"kanban-task-maximized"},minimized:{cardClass:"kanban-task-minimized"}},KanbanController=function(superClass){function KanbanController(scope,rootscope,repo,confirm,rs1,params1,q,location,appTitle,navUrls,events,analytics,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs1,this.params=params1,this.q=q,this.location=location,this.appTitle=appTitle,this.navUrls=navUrls,this.events=events,this.analytics=analytics,bindMethods(this),this.scope.sectionName="Kanban",this.scope.statusViewModes={},this.initializeEventHandlers(),promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Kanban - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(KanbanController,superClass),KanbanController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$appTitle","$tgNavUrls","$tgEvents","$tgAnalytics","tgLoader"],KanbanController.prototype.initializeEventHandlers=function(){return this.scope.$on("usform:new:success",function(_this){return function(){return _this.loadUserstories(),_this.refreshTagsColors(),_this.analytics.trackEvent("userstory","create","create userstory on kanban",1)}}(this)),this.scope.$on("usform:bulk:success",function(_this){return function(){return _this.loadUserstories(),_this.analytics.trackEvent("userstory","create","bulk create userstory on kanban",1)}}(this)),this.scope.$on("usform:edit:success",function(_this){return function(){return _this.loadUserstories(),_this.refreshTagsColors()}}(this)),this.scope.$on("assigned-to:added",this.onAssignedToChanged),this.scope.$on("kanban:us:move",this.moveUs),this.scope.$on("kanban:show-userstories-for-status",this.loadUserStoriesForStatus),this.scope.$on("kanban:hide-userstories-for-status",this.hideUserStoriesForStatus)},KanbanController.prototype.addNewUs=function(type,statusId){switch(type){case"standard":return this.rootscope.$broadcast("usform:new",this.scope.projectId,statusId,this.scope.usStatusList);case"bulk":return this.rootscope.$broadcast("usform:bulk",this.scope.projectId,statusId)}},KanbanController.prototype.changeUsAssignedTo=function(us){return this.rootscope.$broadcast("assigned-to:add",us)},KanbanController.prototype.onAssignedToChanged=function(ctx,userid,us){var promise;return us.assigned_to=userid,promise=this.repo.save(us),promise.then(null,function(){return console.log("FAIL")})},KanbanController.prototype.refreshTagsColors=function(){return this.rs.projects.tagsColors(this.scope.projectId).then(function(_this){return function(tags_colors){return _this.scope.project.tags_colors=tags_colors}}(this))},KanbanController.prototype.loadUserstories=function(){var params;return params={status__is_archived:!1},this.rs.userstories.listAll(this.scope.projectId,params).then(function(_this){return function(userstories){var i,j,k,len,len1,len2,ref,ref1,ref2,status,us,usByStatus,us_archived;for(_this.scope.userstories=userstories,usByStatus=_.groupBy(userstories,"status"),us_archived=[],ref=_this.scope.usStatusList,i=0,len=ref.length;len>i;i++){if(status=ref[i],null==usByStatus[status.id]&&(usByStatus[status.id]=[]),null!=_this.scope.usByStatus)for(ref1=_this.scope.usByStatus[status.id],j=0,len1=ref1.length;len1>j;j++)us=ref1[j],us.status!==status.id&&us_archived.push(us);if(status.is_archived&&null!=_this.scope.usByStatus&&0!==_this.scope.usByStatus[status.id].length)for(ref2=_this.scope.usByStatus[status.id].concat(us_archived),k=0,len2=ref2.length;len2>k;k++)us=ref2[k],us.status===status.id&&usByStatus[status.id].push(us);usByStatus[status.id]=_.sortBy(usByStatus[status.id],"kanban_order")}return _this.scope.usByStatus=usByStatus,scopeDefer(_this.scope,function(){return _this.scope.$broadcast("userstories:loaded",userstories)}),userstories}}(this))},KanbanController.prototype.loadUserStoriesForStatus=function(ctx,statusId){var params;return params={status:statusId},this.rs.userstories.listAll(this.scope.projectId,params).then(function(_this){return function(userstories){return _this.scope.usByStatus[statusId]=_.sortBy(userstories,"kanban_order"),_this.scope.$broadcast("kanban:shown-userstories-for-status",statusId,userstories),userstories}}(this))},KanbanController.prototype.hideUserStoriesForStatus=function(ctx,statusId){return this.scope.usByStatus[statusId]=[],this.scope.$broadcast("kanban:hidden-userstories-for-status",statusId)},KanbanController.prototype.loadKanban=function(){return this.q.all([this.refreshTagsColors(),this.loadUserstories()])},KanbanController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return project.is_kanban_activated||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.projectId=project.id,_this.scope.project=project,_this.scope.projectId=project.id,_this.scope.points=_.sortBy(project.points,"order"),_this.scope.pointsById=groupBy(project.points,function(x){return x.id}),_this.scope.usStatusById=groupBy(project.us_statuses,function(x){return x.id}),_this.scope.usStatusList=_.sortBy(project.us_statuses,"order"),_this.generateStatusViewModes(),_this.scope.$emit("project:loaded",project),project}}(this))},KanbanController.prototype.initializeSubscription=function(){var routingKey1;return routingKey1="changes.project."+this.scope.projectId+".userstories",this.events.subscribe(this.scope,routingKey1,function(_this){return function(){return _this.loadUserstories()}}(this))},KanbanController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.initializeSubscription(),_this.loadKanban().then(function(){return _this.scope.$broadcast("redraw:wip")
})}}(this))},KanbanController.prototype.generateStatusViewModes=function(){var i,len,mode,ref,status,storedStatusViewModes;for(storedStatusViewModes=this.rs.kanban.getStatusViewModes(this.scope.projectId),this.scope.statusViewModes={},ref=this.scope.usStatusList,i=0,len=ref.length;len>i;i++)status=ref[i],mode=storedStatusViewModes[status.id],this.scope.statusViewModes[status.id]=_.has(defaultViewModes,mode)?mode:defaultViewMode;return this.storeStatusViewModes()},KanbanController.prototype.storeStatusViewModes=function(){return this.rs.kanban.storeStatusViewModes(this.scope.projectId,this.scope.statusViewModes)},KanbanController.prototype.updateStatusViewMode=function(statusId,newViewMode){return this.scope.statusViewModes[statusId]=newViewMode,this.storeStatusViewModes()},KanbanController.prototype.getCardClass=function(statusId){var mode;return mode=this.scope.statusViewModes[statusId]||defaultViewMode,defaultViewModes[mode].cardClass||defaultViewModes[defaultViewMode].cardClass},KanbanController.prototype.prepareBulkUpdateData=function(uses,field){return null==field&&(field="kanban_order"),_.map(uses,function(x){return{us_id:x.id,order:x[field]}})},KanbanController.prototype.resortUserStories=function(uses){var i,index,item,items,len;for(items=[],index=i=0,len=uses.length;len>i;index=++i)item=uses[index],item.kanban_order=index,item.isModified()&&items.push(item);return items},KanbanController.prototype.moveUs=function(ctx,us,oldStatusId,newStatusId,index){var itemsToSave,promise,r;return oldStatusId!==newStatusId?(r=this.scope.usByStatus[oldStatusId].indexOf(us),this.scope.usByStatus[oldStatusId].splice(r,1),this.scope.usByStatus[newStatusId].splice(index,0,us),us.status=newStatusId):(r=this.scope.usByStatus[newStatusId].indexOf(us),this.scope.usByStatus[newStatusId].splice(r,1),this.scope.usByStatus[newStatusId].splice(index,0,us)),itemsToSave=this.resortUserStories(this.scope.usByStatus[newStatusId]),this.scope.usByStatus[newStatusId]=_.sortBy(this.scope.usByStatus[newStatusId],"kanban_order"),promise=this.repo.save(us),promise=promise.then(function(_this){return function(){var data;return itemsToSave=_.reject(itemsToSave,{id:us.id}),data=_this.prepareBulkUpdateData(itemsToSave),_this.rs.userstories.bulkUpdateKanbanOrder(us.project,data).then(function(){return itemsToSave})}}(this))},KanbanController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("KanbanController",KanbanController),KanbanDirective=function(){var link;return link=function($scope,$el){var tableBodyDom;return tableBodyDom=$el.find(".kanban-table-body"),tableBodyDom.on("scroll",function(event){var tableHeaderDom,target;return target=angular.element(event.currentTarget),tableHeaderDom=$el.find(".kanban-table-header .kanban-table-inner"),tableHeaderDom.css("left",-1*target.scrollLeft())}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgKanban",["$tgRepo","$rootScope",KanbanDirective]),KanbanArchivedStatusHeaderDirective=function($rootscope){var hideArchivedText,link,showArchivedText;return showArchivedText="Show archived",hideArchivedText="Hide archived",link=function($scope,$el,$attrs){var hidden,status;return status=$scope.$eval($attrs.tgKanbanArchivedStatusHeader),hidden=!0,$scope["class"]="icon icon-open-eye",$scope.title=showArchivedText,$el.on("click",function(){return hidden=!hidden,$scope.$apply(function(){return hidden?($scope["class"]="icon icon-open-eye",$scope.title=showArchivedText,$rootscope.$broadcast("kanban:hide-userstories-for-status",status.id)):($scope["class"]="icon icon-closed-eye",$scope.title=hideArchivedText,$rootscope.$broadcast("kanban:show-userstories-for-status",status.id))})}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgKanbanArchivedStatusHeader",["$rootScope",KanbanArchivedStatusHeaderDirective]),KanbanArchivedStatusIntroDirective=function(){var hiddenUserStoriexText,link,userStories;return hiddenUserStoriexText="The user stories in this status are hidden by default",userStories=[],link=function($scope,$el,$attrs){var status,updateIntroText;return status=$scope.$eval($attrs.tgKanbanArchivedStatusIntro),$el.text(hiddenUserStoriexText),updateIntroText=function(){return $el.text(userStories.length>0?"":hiddenUserStoriexText)},$scope.$on("kanban:us:move",function(ctx,itemUs,oldStatusId,newStatusId,itemIndex){var r;return status.id===newStatusId?status.id===oldStatusId?(r=userStories.indexOf(itemUs),userStories.splice(r,1),userStories.splice(itemIndex,0,itemUs)):(itemUs.isArchived=!0,userStories.splice(itemIndex,0,itemUs)):status.id===oldStatusId&&(itemUs.isArchived=!1,r=userStories.indexOf(itemUs),userStories.splice(r,1)),updateIntroText()}),$scope.$on("kanban:shown-userstories-for-status",function(ctx,statusId,userStoriesLoaded){return statusId===status.id?(userStories=_.filter(userStoriesLoaded,function(us){return us.status===status.id}),updateIntroText()):void 0}),$scope.$on("kanban:hidden-userstories-for-status",function(ctx,statusId){return statusId===status.id?(userStories=[],updateIntroText()):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgKanbanArchivedStatusIntro",KanbanArchivedStatusIntroDirective),KanbanUserstoryDirective=function($rootscope){var link;return link=function($scope,$el,$attrs,$model){return $el.disableSelection(),$scope.$watch("us",function(us){return us.is_blocked&&!$el.hasClass("blocked")?$el.addClass("blocked"):!us.is_blocked&&$el.hasClass("blocked")?$el.removeClass("blocked"):void 0}),$el.find(".icon-edit").on("click",function(){return $el.find(".icon-edit").hasClass("noclick")?void 0:$scope.$apply(function(){return $rootscope.$broadcast("usform:edit",$model.$modelValue)})}),$scope.$on("$destroy",function(){return $el.off()})},{templateUrl:"kanban/kanban-task.html",link:link,require:"ngModel"}},module.directive("tgKanbanUserstory",["$rootScope",KanbanUserstoryDirective]),KanbanSquishColumnDirective=function(rs){var link;return link=function($scope,$el){var updateTableWidth;return $scope.$on("project:loaded",function(event,project){return $scope.folds=rs.kanban.getStatusColumnModes(project.id),updateTableWidth()}),$scope.foldStatus=function(status){$scope.folds[status.id]=!$scope.folds[status.id],rs.kanban.storeStatusColumnModes($scope.projectId,$scope.folds),updateTableWidth()},updateTableWidth=function(){var columnWidths,totalWidth;return columnWidths=_.map($scope.usStatusList,function(status){return $scope.folds[status.id]?40:310}),totalWidth=_.reduce(columnWidths,function(total,width){return total+width}),$el.find(".kanban-table-inner").css("width",totalWidth)}},{link:link}},module.directive("tgKanbanSquishColumn",["$tgResources",KanbanSquishColumnDirective]),KanbanWipLimitDirective=function(){var link;return link=function($scope,$el,$attrs){var redrawWipLimit;return $el.disableSelection(),redrawWipLimit=function(){return $el.find(".kanban-wip-limit").remove(),timeout(200,function(){var element;return element=$el.find(".kanban-task")[$scope.$eval($attrs.tgKanbanWipLimit)],element?angular.element(element).before("
"):void 0})},$scope.$on("redraw:wip",redrawWipLimit),$scope.$on("kanban:us:move",redrawWipLimit),$scope.$on("usform:new:success",redrawWipLimit),$scope.$on("usform:bulk:success",redrawWipLimit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgKanbanWipLimit",KanbanWipLimitDirective),KanbanUserDirective=function($log){var clickable,link,template;return template=_.template('
\n class="not-clickable"<% } %>>\n \n \n '),clickable=!1,link=function($scope,$el,$attrs,$model){var render,username_label,wtid;return username_label=$el.parent().find("a.task-assigned"),username_label.addClass("not-clickable"),$attrs.tgKanbanUserAvatar?(wtid=$scope.$watch($attrs.tgKanbanUserAvatar,function(v){var user;return null==$scope.usersById?($log.error("KanbanUserDirective requires userById set in scope."),wtid()):(user=$scope.usersById[v],render(user))}),render=function(user){var ctx,html;return ctx=void 0===user?{name:"Unassigned",imgurl:"/images/unnamed.png",clickable:clickable}:{name:user.full_name_display,imgurl:user.photo,clickable:clickable},html=template(ctx),$el.html(html),username_label.text(ctx.name)},bindOnce($scope,"project",function(project){return project.my_permissions.indexOf("modify_us")>-1?(clickable=!0,$el.on("click",function(){return function(){var $ctrl,us;if(!$el.find("a").hasClass("noclick"))return us=$model.$modelValue,$ctrl=$el.controller(),$ctrl.changeUsAssignedTo(us)}}(this)),username_label.removeClass("not-clickable"),username_label.on("click",function(){var $ctrl,us;if(!$el.find("a").hasClass("noclick"))return us=$model.$modelValue,$ctrl=$el.controller(),$ctrl.changeUsAssignedTo(us)})):void 0}),$scope.$on("$destroy",function(){return $el.off()})):$log.error("KanbanUserDirective: no attr is defined")},{link:link,require:"ngModel"}},module.directive("tgKanbanUserAvatar",["$log",KanbanUserDirective])}.call(this),function(){var KanbanSortableDirective,bindOnce,groupBy,mixOf,module,scopeDefer,taiga,timeout,toggleText;taiga=this.taiga,mixOf=this.taiga.mixOf,toggleText=this.taiga.toggleText,scopeDefer=this.taiga.scopeDefer,bindOnce=this.taiga.bindOnce,groupBy=this.taiga.groupBy,timeout=this.taiga.timeout,module=angular.module("taigaKanban"),KanbanSortableDirective=function($repo,$rs,$rootscope){var link;return link=function($scope,$el){return bindOnce($scope,"project",function(project){var deleteElement,itemEl,newParentScope,oldParentScope,tdom;if(project.my_permissions.indexOf("modify_us")>-1)return oldParentScope=null,newParentScope=null,itemEl=null,tdom=$el,deleteElement=function(itemEl){return itemEl.scope().$destroy(),itemEl.off(),itemEl.remove()},tdom.sortable({handle:".kanban-task-inner",dropOnEmpty:!0,connectWith:".kanban-uses-box",revert:400}),tdom.on("sortstop",function(event,ui){var itemIndex,itemUs,newStatusId,oldStatusId,parentEl;return parentEl=ui.item.parent(),itemEl=ui.item,itemUs=itemEl.scope().us,itemIndex=itemEl.index(),newParentScope=parentEl.scope(),newStatusId=newParentScope.s.id,oldStatusId=oldParentScope.s.id,newStatusId!==oldStatusId&&deleteElement(itemEl),$scope.$apply(function(){return $rootscope.$broadcast("kanban:us:move",itemUs,itemUs.status,newStatusId,itemIndex)}),ui.item.find("a").removeClass("noclick")}),tdom.on("sortstart",function(event,ui){return oldParentScope=ui.item.parent().scope(),ui.item.find("a").addClass("noclick")})}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgKanbanSortable",["$tgRepo","$tgResources","$rootScope",KanbanSortableDirective])}.call(this),function(){var IssueDetailController,IssuePriorityButtonDirective,IssueSeverityButtonDirective,IssueStatusButtonDirective,IssueStatusDisplayDirective,IssueTypeButtonDirective,PromoteIssueToUsButtonDirective,bindOnce,groupBy,joinStr,mixOf,module,taiga,toString,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,toString=this.taiga.toString,joinStr=this.taiga.joinStr,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,module=angular.module("taigaIssues"),IssueDetailController=function(superClass){function IssueDetailController(scope,rootscope,repo,confirm,rs,params,q,location,log,appTitle,analytics,navUrls,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.log=log,this.appTitle=appTitle,this.analytics=analytics,this.navUrls=navUrls,this.scope.issueRef=this.params.issueref,this.scope.sectionName="Issue Details",this.initializeEventHandlers(),promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set(_this.scope.issue.subject+" - "+_this.scope.project.name),_this.initializeOnDeleteGoToUrl()}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(IssueDetailController,superClass),IssueDetailController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$log","$appTitle","$tgAnalytics","$tgNavUrls","tgLoader"],IssueDetailController.prototype.initializeEventHandlers=function(){return this.scope.$on("attachment:create",function(_this){return function(){return _this.rootscope.$broadcast("history:reload"),_this.analytics.trackEvent("attachment","create","create attachment on issue",1)}}(this)),this.scope.$on("attachment:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("attachment:delete",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("promote-issue-to-us:success",function(_this){return function(){return _this.analytics.trackEvent("issue","promoteToUserstory","promote issue to userstory",1),_this.rootscope.$broadcast("history:reload"),_this.loadIssue()}}(this)),this.scope.$on("custom-attributes-values:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this))},IssueDetailController.prototype.initializeOnDeleteGoToUrl=function(){var ctx;return ctx={project:this.scope.project.slug},this.scope.onDeleteGoToUrl=this.scope.project.is_issues_activated?this.navUrls.resolve("project-issues",ctx):this.navUrls.resolve("project",ctx)},IssueDetailController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return _this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.statusList=project.issue_statuses,_this.scope.statusById=groupBy(project.issue_statuses,function(x){return x.id}),_this.scope.typeById=groupBy(project.issue_types,function(x){return x.id}),_this.scope.typeList=_.sortBy(project.issue_types,"order"),_this.scope.severityList=project.severities,_this.scope.severityById=groupBy(project.severities,function(x){return x.id}),_this.scope.priorityList=project.priorities,_this.scope.priorityById=groupBy(project.priorities,function(x){return x.id}),_this.scope.membersById=groupBy(project.memberships,function(x){return x.user}),project}}(this))},IssueDetailController.prototype.loadIssue=function(){return this.rs.issues.getByRef(this.scope.projectId,this.params.issueref).then(function(_this){return function(issue){var ctx;return _this.scope.issue=issue,_this.scope.issueId=issue.id,_this.scope.commentModel=issue,null!=_this.scope.issue.neighbors.previous.ref&&(ctx={project:_this.scope.project.slug,ref:_this.scope.issue.neighbors.previous.ref},_this.scope.previousUrl=_this.navUrls.resolve("project-issues-detail",ctx)),null!=_this.scope.issue.neighbors.next.ref?(ctx={project:_this.scope.project.slug,ref:_this.scope.issue.neighbors.next.ref},_this.scope.nextUrl=_this.navUrls.resolve("project-issues-detail",ctx)):void 0}}(this))},IssueDetailController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.loadIssue()}}(this))},IssueDetailController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("IssueDetailController",IssueDetailController),IssueStatusDisplayDirective=function($template){var link,template;return template=$template.get("common/components/status-display.html",!0),link=function($scope,$el,$attrs){var render;return render=function(issue){var html,status;return status=$scope.statusById[issue.status],html=template({is_closed:status.is_closed,status:status}),$el.html(html)},$scope.$watch($attrs.ngModel,function(issue){return null!=issue?render(issue):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgIssueStatusDisplay",["$tgTemplate",IssueStatusDisplayDirective]),IssueStatusButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("issue/issues-status-button.html",!0),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_issue")},render=function(){return function(issue){var html,status;return status=$scope.statusById[issue.status],html=template({status:status,statuses:$scope.statusList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(statusId){var issue,onError,onSuccess;return $.fn.popover().closeAll(),issue=$model.$modelValue.clone(),issue.status=statusId,onSuccess=function(){return $confirm.notify("success"),$model.$setViewValue(issue),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),issue.revert(),$model.$setViewValue(issue),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save(issue).then(onSuccess,onError)}}(this)),$el.on("click",".status-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-status").popover().open():void 0}),$el.on("click",".status",function(event){var target;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),save(target.data("status-id"))):void 0}),$scope.$watch($attrs.ngModel,function(issue){return issue?render(issue):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgIssueStatusButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",IssueStatusButtonDirective]),IssueTypeButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("issue/issue-type-button.html",!0),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_issue")},render=function(){return function(issue){var html,type;return type=$scope.typeById[issue.type],html=template({type:type,typees:$scope.typeList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(type){var issue,onError,onSuccess;return $.fn.popover().closeAll(),issue=$model.$modelValue.clone(),issue.type=type,onSuccess=function(){return $confirm.notify("success"),$model.$setViewValue(issue),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),issue.revert(),$model.$setViewValue(issue),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save(issue).then(onSuccess,onError)}}(this)),$el.on("click",".type-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-type").popover().open():void 0}),$el.on("click",".type",function(event){var target,type;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),type=target.data("type-id"),save(type)):void 0}),$scope.$watch($attrs.ngModel,function(issue){return issue?render(issue):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgIssueTypeButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",IssueTypeButtonDirective]),IssueSeverityButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("issue/issue-severity-button.html",!0),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_issue")},render=function(){return function(issue){var html,severity;return severity=$scope.severityById[issue.severity],html=template({severity:severity,severityes:$scope.severityList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(severity){var issue,onError,onSuccess;return $.fn.popover().closeAll(),issue=$model.$modelValue.clone(),issue.severity=severity,onSuccess=function(){return $confirm.notify("success"),$model.$setViewValue(issue),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),issue.revert(),$model.$setViewValue(issue),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save(issue).then(onSuccess,onError)}}(this)),$el.on("click",".severity-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-severity").popover().open():void 0}),$el.on("click",".severity",function(event){var severity,target;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),severity=target.data("severity-id"),save(severity)):void 0}),$scope.$watch($attrs.ngModel,function(issue){return issue?render(issue):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgIssueSeverityButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",IssueSeverityButtonDirective]),IssuePriorityButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("issue/issue-priority-button.html",!0),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_issue")},render=function(){return function(issue){var html,priority;return priority=$scope.priorityById[issue.priority],html=template({priority:priority,priorityes:$scope.priorityList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(priority){var issue,onError,onSuccess;return $.fn.popover().closeAll(),issue=$model.$modelValue.clone(),issue.priority=priority,onSuccess=function(){return $confirm.notify("success"),$model.$setViewValue(issue),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),issue.revert(),$model.$setViewValue(issue),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save(issue).then(onSuccess,onError)}}(this)),$el.on("click",".priority-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-priority").popover().open():void 0}),$el.on("click",".priority",function(event){var priority,target;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),priority=target.data("priority-id"),save(priority)):void 0}),$scope.$watch($attrs.ngModel,function(issue){return issue?render(issue):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgIssuePriorityButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",IssuePriorityButtonDirective]),PromoteIssueToUsButtonDirective=function($rootScope,$repo,$confirm,$qqueue){var link;return link=function($scope,$el,$attrs,$model){var save;return save=$qqueue.bindAdd(function(){return function(issue,finish){var data,onError,onSuccess;return data={generated_from_issue:issue.id,project:issue.project,subject:issue.subject,description:issue.description,tags:issue.tags,is_blocked:issue.is_blocked,blocked_note:issue.blocked_note},onSuccess=function(){return finish(),$confirm.notify("success"),$rootScope.$broadcast("promote-issue-to-us:success")},onError=function(){return finish(!1),$confirm.notify("error")},$repo.create("userstories",data).then(onSuccess,onError)}}(this)),$el.on("click","a",function(event){var issue,message,subtitle,title;return event.preventDefault(),issue=$model.$modelValue,title="Promote this issue to a new user story",message="Are you sure you want to create a new US from this Issue?",subtitle=issue.subject,$confirm.ask(title,subtitle,message).then(function(){return function(finish){return save(issue,finish)}}(this))}),$scope.$on("$destroy",function(){return $el.off()})},{restrict:"AE",require:"ngModel",templateUrl:"issue/promote-issue-to-us-button.html",link:link}},module.directive("tgPromoteIssueToUsButton",["$rootScope","$tgRepo","$tgConfirm","$tgQqueue",PromoteIssueToUsButtonDirective])}.call(this),function(){var CreateBulkIssuesDirective,CreateIssueDirective,bindOnce,debounce,module,taiga;taiga=this.taiga,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,module=angular.module("taigaIssues"),CreateIssueDirective=function($repo,$confirm,$rootscope,lightboxService,$loading){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley(),$scope.issue={},$scope.$on("issueform:new",function(ctx,project){return $el.find(".tag-input").val(""),lightboxService.open($el),$scope.issue={project:project.id,subject:"",status:project.default_issue_status,type:project.default_issue_type,priority:project.default_priority,severity:project.default_severity,tags:[]}}),$scope.$on("$destroy",function(){return $el.off()}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.create("issues",$scope.issue),promise.then(function(data){return $loading.finish(submitButton),$rootscope.$broadcast("issueform:new:success",data),lightboxService.close($el),$confirm.notify("success")}),promise.then(null,function(){return $loading.finish(submitButton),$confirm.notify("error")})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgLbCreateIssue",["$tgRepo","$tgConfirm","$rootScope","lightboxService","$tgLoading",CreateIssueDirective]),CreateBulkIssuesDirective=function($repo,$rs,$confirm,$rootscope,$loading,lightboxService){var link;return link=function($scope,$el){var submit,submitButton;return $scope.$on("issueform:bulk",function(ctx,projectId){return lightboxService.open($el),$scope["new"]={projectId:projectId,bulk:""}}),submit=debounce(2e3,function(){return function(event){var data,form,projectId,promise;return event.preventDefault(),form=$el.find("form").checksley(),form.validate()?($loading.start(submitButton),data=$scope["new"].bulk,projectId=$scope["new"].projectId,promise=$rs.issues.bulkCreate(projectId,data),promise.then(function(result){return $loading.finish(submitButton),$rootscope.$broadcast("issueform:new:success",result),lightboxService.close($el),$confirm.notify("success")}),promise.then(null,function(){return $loading.finish(submitButton),$confirm.notify("error")})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgLbCreateBulkIssues",["$tgRepo","$tgResources","$tgConfirm","$rootScope","$tgLoading","lightboxService",CreateBulkIssuesDirective])}.call(this),function(){var IssueAssignedToInlineEditionDirective,IssueStatusInlineEditionDirective,IssuesController,IssuesDirective,IssuesFiltersDirective,bindOnce,debounceLeading,groupBy,joinStr,mixOf,module,startswith,taiga,toString,trim,bind=function(fn,me){return function(){return fn.apply(me,arguments)}},extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,trim=this.taiga.trim,toString=this.taiga.toString,joinStr=this.taiga.joinStr,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,debounceLeading=this.taiga.debounceLeading,startswith=this.taiga.startswith,module=angular.module("taigaIssues"),IssuesController=function(superClass){function IssuesController(scope,rootscope,repo,confirm,rs,urls,params,q,location,appTitle,navUrls,events,analytics,tgLoader){var filters,promise;return this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.urls=urls,this.params=params,this.q=q,this.location=location,this.appTitle=appTitle,this.navUrls=navUrls,this.events=events,this.analytics=analytics,this.loadIssues=bind(this.loadIssues,this),this.scope.sectionName="Issues",this.scope.filters={},_.isEmpty(this.location.search())?(filters=this.rs.issues.getFilters(this.params.pslug),filters.page=1,this.location.search(filters),void this.location.replace()):(promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Issues - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded),void this.scope.$on("issueform:new:success",function(_this){return function(){return _this.analytics.trackEvent("issue","create","create issue on issues list",1),_this.loadIssues(),_this.loadFilters()}}(this)))}return extend(IssuesController,superClass),IssuesController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$tgUrls","$routeParams","$q","$tgLocation","$appTitle","$tgNavUrls","$tgEvents","$tgAnalytics","tgLoader"],IssuesController.prototype.initializeSubscription=function(){var routingKey;return routingKey="changes.project."+this.scope.projectId+".issues",this.events.subscribe(this.scope,routingKey,function(_this){return function(){return _this.loadIssues()}}(this))},IssuesController.prototype.storeFilters=function(){return this.rs.issues.storeFilters(this.params.pslug,this.location.search())},IssuesController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return project.is_issues_activated||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.issueStatusById=groupBy(project.issue_statuses,function(x){return x.id}),_this.scope.issueStatusList=_.sortBy(project.issue_statuses,"order"),_this.scope.severityById=groupBy(project.severities,function(x){return x.id}),_this.scope.severityList=_.sortBy(project.severities,"order"),_this.scope.priorityById=groupBy(project.priorities,function(x){return x.id}),_this.scope.priorityList=_.sortBy(project.priorities,"order"),_this.scope.issueTypes=_.sortBy(project.issue_types,"order"),_this.scope.issueTypeById=groupBy(project.issue_types,function(x){return x.id}),_this.scope.membersById=groupBy(project.memberships,function(x){return x.user}),project}}(this))},IssuesController.prototype.getUrlFilters=function(){var filters;return filters=_.pick(this.location.search(),"page","tags","statuses","types","q","severities","priorities","assignedTo","createdBy","orderBy"),filters.page||(filters.page=1),filters},IssuesController.prototype.getUrlFilter=function(name){var filters;return filters=_.pick(this.location.search(),name),filters[name]},IssuesController.prototype.loadMyFilters=function(){return this.rs.issues.getMyFilters(this.scope.projectId).then(function(){return function(filters){return _.map(filters,function(value,key){return{id:key,name:key,type:"myFilters",selected:!1}})}}(this))},IssuesController.prototype.removeNotExistingFiltersFromUrl=function(){var currentSearch,existingValues,filterName,filterValue,splittedValues,urlfilters;
currentSearch=this.location.search(),urlfilters=this.getUrlFilters();for(filterName in urlfilters)filterValue=urlfilters[filterName],"page"!==filterName&&"orderBy"!==filterName&&"q"!==filterName&&(splittedValues="tags"===filterName?_.map((""+filterValue).split(",")):_.map((""+filterValue).split(","),function(x){return"null"===x?null:parseInt(x)}),existingValues=_.intersection(splittedValues,_.map(this.scope.filters[filterName],"id")),splittedValues.length!==existingValues.length&&this.location.search(filterName,existingValues.join()));return currentSearch!==this.location.search()?this.location.replace():void 0},IssuesController.prototype.markSelectedFilters=function(filters,urlfilters){var isSelected,j,key,len,name,obj,ref,ref1,results,searchdata,val,value;searchdata={},ref=_.omit(urlfilters,"page","orderBy");for(name in ref)for(value=ref[name],null==searchdata[name]&&(searchdata[name]={}),ref1=(""+value).split(","),j=0,len=ref1.length;len>j;j++)val=ref1[j],searchdata[name][val]=!0;isSelected=function(type,id){return null!=searchdata[type]&&searchdata[type][id]?!0:!1},results=[];for(key in filters)value=filters[key],results.push(function(){var k,len1,results1;for(results1=[],k=0,len1=value.length;len1>k;k++)obj=value[k],results1.push(obj.selected=isSelected(obj.type,obj.id)?!0:void 0);return results1}());return results},IssuesController.prototype.loadFilters=function(){var promise,urlfilters;return urlfilters=this.getUrlFilters(),urlfilters.q&&(this.scope.filtersQ=urlfilters.q),promise=this.loadMyFilters().then(function(_this){return function(myFilters){return _this.scope.filters.myFilters=myFilters,myFilters}}(this)),promise=promise.then(function(_this){return function(){return _this.rs.issues.filtersData(_this.scope.projectId)}}(this)),promise.then(function(_this){return function(data){var choicesFiltersFormat,tagsFilterFormat,usersFiltersFormat;return usersFiltersFormat=function(users,type,unknownOption){var reformatedUsers,unknownItem;return reformatedUsers=_.map(users,function(t){return{id:t[0],count:t[1],type:type,name:t[0]?_this.scope.usersById[t[0]].full_name_display:unknownOption}}),unknownItem=_.remove(reformatedUsers,function(u){return!u.id}),reformatedUsers=_.sortBy(reformatedUsers,function(u){return u.name.toUpperCase()}),unknownItem.length>0&&reformatedUsers.unshift(unknownItem[0]),reformatedUsers},choicesFiltersFormat=function(choices,type,byIdObject){return _.map(choices,function(t){return{id:t[0],name:byIdObject[t[0]].name,color:byIdObject[t[0]].color,count:t[1],type:type}})},tagsFilterFormat=function(tags){return _.map(tags,function(t){return{id:t[0],name:t[0],color:_this.scope.project.tags_colors[t[0]],count:t[1],type:"tags"}})},_this.scope.filters.statuses=choicesFiltersFormat(data.statuses,"statuses",_this.scope.issueStatusById),_this.scope.filters.severities=choicesFiltersFormat(data.severities,"severities",_this.scope.severityById),_this.scope.filters.priorities=choicesFiltersFormat(data.priorities,"priorities",_this.scope.priorityById),_this.scope.filters.assignedTo=usersFiltersFormat(data.assigned_to,"assignedTo","Unassigned"),_this.scope.filters.createdBy=usersFiltersFormat(data.created_by,"createdBy","Unknown"),_this.scope.filters.types=choicesFiltersFormat(data.types,"types",_this.scope.issueTypeById),_this.scope.filters.tags=tagsFilterFormat(data.tags),_this.removeNotExistingFiltersFromUrl(),_this.markSelectedFilters(_this.scope.filters,urlfilters),_this.rootscope.$broadcast("filters:loaded",_this.scope.filters)}}(this))},IssuesController.prototype.loadIssuesRequests=0,IssuesController.prototype.loadIssues=function(){var name,promise,ref,values;this.scope.urlFilters=this.getUrlFilters(),this.scope.httpParams={},ref=this.scope.urlFilters;for(name in ref)values=ref[name],"severities"===name?name="severity":"orderBy"===name?name="order_by":"priorities"===name?name="priority":"assignedTo"===name?name="assigned_to":"createdBy"===name?name="owner":"statuses"===name?name="status":"types"===name&&(name="type"),this.scope.httpParams[name]=values;return promise=this.rs.issues.list(this.scope.projectId,this.scope.httpParams),this.loadIssuesRequests+=1,promise.index=this.loadIssuesRequests,promise.then(function(_this){return function(data){return promise.index===_this.loadIssuesRequests&&(_this.scope.issues=data.models,_this.scope.page=data.current,_this.scope.count=data.count,_this.scope.paginatedBy=data.paginatedBy),data}}(this))},IssuesController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.initializeSubscription(),_this.q.all([_this.loadFilters(),_this.loadIssues()])}}(this))},IssuesController.prototype.saveCurrentFiltersTo=function(newFilter){var deferred;return deferred=this.q.defer(),this.rs.issues.getMyFilters(this.scope.projectId).then(function(_this){return function(filters){return filters[newFilter]=_this.location.search(),_this.rs.issues.storeMyFilters(_this.scope.projectId,filters).then(function(){return deferred.resolve()})}}(this)),deferred.promise},IssuesController.prototype.deleteMyFilter=function(filter){var deferred;return deferred=this.q.defer(),this.rs.issues.getMyFilters(this.scope.projectId).then(function(_this){return function(filters){return delete filters[filter],_this.rs.issues.storeMyFilters(_this.scope.projectId,filters).then(function(){return deferred.resolve()})}}(this)),deferred.promise},IssuesController.prototype.addNewIssue=function(){return this.rootscope.$broadcast("issueform:new",this.scope.project)},IssuesController.prototype.addIssuesInBulk=function(){return this.rootscope.$broadcast("issueform:bulk",this.scope.projectId)},IssuesController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("IssuesController",IssuesController),IssuesDirective=function($log,$location,$template){var link,linkOrdering,linkPagination,template;return template=$template.get("issue/issue-paginator.html",!0),linkPagination=function($scope,$el,$attrs,$ctrl){var $pagEl,afterCurrent,atBegin,atEnd,beforeCurrent,getNumPages,renderPagination;return afterCurrent=2,beforeCurrent=4,atBegin=2,atEnd=2,$pagEl=$el.find(".issues-paginator"),getNumPages=function(){var numPages;return numPages=$scope.count/$scope.paginatedBy,numPages=parseInt(numPages,10)
=numPages)return void $pagEl.hide();for($pagEl.show(),pages=[],options={},options.pages=pages,options.showPrevious=$scope.page>1,options.showNext=!($scope.page===numPages),cpage=$scope.page,i=j=1,ref=numPages;ref>=1?ref>=j:j>=ref;i=ref>=1?++j:--j)i===cpage+afterCurrent&&numPages>cpage+afterCurrent+atEnd?pages.push({classes:"dots",type:"dots"}):i===cpage-beforeCurrent&&cpage>atBegin+beforeCurrent?pages.push({classes:"dots",type:"dots"}):i>cpage+afterCurrent&&numPages-atEnd>=i||cpage-beforeCurrent>i&&i>atBegin||pages.push(i===cpage?{classes:"active",num:i,type:"page-active"}:{classes:"page",num:i,type:"page"});return $pagEl.html(template(options))},$scope.$watch("issues",function(value){return value?renderPagination():void 0}),$el.on("click",".issues-paginator a.next",function(event){return event.preventDefault(),$scope.$apply(function(){return $ctrl.selectFilter("page",$scope.page+1),$ctrl.loadIssues()})}),$el.on("click",".issues-paginator a.previous",function(event){return event.preventDefault(),$scope.$apply(function(){return $ctrl.selectFilter("page",$scope.page-1),$ctrl.loadIssues()})}),$el.on("click",".issues-paginator li.page > a",function(event){var pagenum,target;return event.preventDefault(),target=angular.element(event.currentTarget),pagenum=target.data("pagenum"),$scope.$apply(function(){return $ctrl.selectFilter("page",pagenum),$ctrl.loadIssues()})})},linkOrdering=function($scope,$el,$attrs,$ctrl){var colHeadElement,currentOrder,icon;return currentOrder=$ctrl.getUrlFilter("orderBy")||"created_date",currentOrder&&(icon=startswith(currentOrder,"-")?"icon-caret-up":"icon-caret-down",colHeadElement=$el.find(".row.title > div[data-fieldname='"+trim(currentOrder,"-")+"']"),colHeadElement.html(colHeadElement.html()+" ")),$el.on("click",".row.title > div",function(event){var finalOrder,newOrder,target;return target=angular.element(event.currentTarget),currentOrder=$ctrl.getUrlFilter("orderBy"),newOrder=target.data("fieldname"),finalOrder=currentOrder===newOrder?"-"+newOrder:newOrder,$scope.$apply(function(){return $ctrl.replaceFilter("orderBy",finalOrder),$ctrl.storeFilters(),$ctrl.loadIssues().then(function(){return $el.find(".row.title > div > span.icon").remove(),icon=startswith(finalOrder,"-")?"icon-caret-up":"icon-caret-down",target.html(target.html()+" ")})})})},link=function($scope,$el,$attrs){var $ctrl;return $ctrl=$el.controller(),linkOrdering($scope,$el,$attrs,$ctrl),linkPagination($scope,$el,$attrs,$ctrl),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgIssues",["$log","$tgLocation","$tgTemplate",IssuesDirective]),IssuesFiltersDirective=function($log,$location,$rs,$confirm,$loading,$template){var link,template,templateSelected;return template=$template.get("issue/issues-filters.html",!0),templateSelected=$template.get("issue/issues-filters-selected.html",!0),link=function($scope,$el){var $ctrl,initializeSelectedFilters,renderFilters,renderSelectedFilters,selectQFilter,selectedFilters,showCategories,showFilters,toggleFilterSelection;return $ctrl=$el.closest(".wrapper").controller(),selectedFilters=[],showFilters=function(title,type){return $el.find(".filters-cats").hide(),$el.find(".filter-list").removeClass("hidden"),$el.find("h2.breadcrumb").removeClass("hidden"),$el.find("h2 a.subfilter span.title").html(title),$el.find("h2 a.subfilter span.title").prop("data-type",type)},showCategories=function(){return $el.find(".filters-cats").show(),$el.find(".filter-list").addClass("hidden"),$el.find("h2.breadcrumb").addClass("hidden")},initializeSelectedFilters=function(filters){var j,len,name,val,values;selectedFilters=[];for(name in filters)for(values=filters[name],j=0,len=values.length;len>j;j++)val=values[j],val.selected&&selectedFilters.push(val);return renderSelectedFilters(selectedFilters)},renderSelectedFilters=function(selectedFilters){var html;return _.filter(selectedFilters,function(){return function(f){return f.color?f.style="border-left: 3px solid "+f.color:void 0}}(this)),html=templateSelected({filters:selectedFilters}),$el.find(".filters-applied").html(html),selectedFilters.length>0?$el.find(".save-filters").show():$el.find(".save-filters").hide()},renderFilters=function(filters){var html;return _.filter(filters,function(){return function(f){return f.color?f.style="border-left: 3px solid "+f.color:void 0}}(this)),html=template({filters:filters}),$el.find(".filter-list").html(html)},toggleFilterSelection=function(type,id){var currentFiltersType,filter,filterId,filters;return"myFilters"===type?($rs.issues.getMyFilters($scope.projectId).then(function(data){var filters,myFilters;return myFilters=data,filters=myFilters[id],filters.page=1,$ctrl.replaceAllFilters(filters),$ctrl.storeFilters(),$ctrl.loadIssues(),$ctrl.markSelectedFilters($scope.filters,filters),initializeSelectedFilters($scope.filters)}),null):(filters=$scope.filters[type],filterId="tags"===type?taiga.toString(id):id,filter=_.find(filters,{id:filterId}),filter.selected=!filter.selected,null===id&&(id="null"),filter.selected?(selectedFilters.push(filter),$scope.$apply(function(){return $ctrl.selectFilter(type,id),$ctrl.selectFilter("page",1),$ctrl.storeFilters(),$ctrl.loadIssues()})):(selectedFilters=_.reject(selectedFilters,filter),$scope.$apply(function(){return $ctrl.unselectFilter(type,id),$ctrl.selectFilter("page",1),$ctrl.storeFilters(),$ctrl.loadIssues()})),renderSelectedFilters(selectedFilters),currentFiltersType=$el.find("h2 a.subfilter span.title").prop("data-type"),type===currentFiltersType?renderFilters(_.reject(filters,"selected")):void 0)},$scope.$on("filters:loaded",function(ctx,filters){return initializeSelectedFilters(filters)}),$scope.$on("filters:issueupdate",function(ctx,filters){var html;return html=template({filters:filters.statuses}),$el.find(".filter-list").html(html)}),selectQFilter=debounceLeading(100,function(value){return void 0!==value?($ctrl.replaceFilter("page",null),0===value.length?($ctrl.replaceFilter("q",null),$ctrl.storeFilters()):($ctrl.replaceFilter("q",value),$ctrl.storeFilters()),$ctrl.loadIssues()):void 0}),$scope.$watch("filtersQ",selectQFilter),$el.on("click",".filters-cats > ul > li > a",function(event){var tags,target;return event.preventDefault(),target=angular.element(event.currentTarget),tags=$scope.filters[target.data("type")],renderFilters(_.reject(tags,"selected")),showFilters(target.attr("title"),target.data("type"))}),$el.on("click",".filters-inner > .filters-step-cat > .breadcrumb > .back",function(event){return event.preventDefault(),showCategories($el)}),$el.on("click",".filters-applied a",function(event){var id,target,type;return event.preventDefault(),target=angular.element(event.currentTarget),id=target.data("id")||null,type=target.data("type"),toggleFilterSelection(type,id)}),$el.on("click",".filter-list .single-filter",function(event){var id,target,type;return event.preventDefault(),target=angular.element(event.currentTarget),target.toggleClass("active"),id=target.data("id")||null,type=target.data("type"),"myFilters"===type&&target.removeClass("active"),toggleFilterSelection(type,id)}),$el.on("click",".filter-list .single-filter .icon-delete",function(event){var customFilterName,message,target,title;return event.preventDefault(),event.stopPropagation(),target=angular.element(event.currentTarget),customFilterName=target.parent().data("id"),title="Delete custom filter",message="the custom filter '"+customFilterName+"'",$confirm.askOnDelete(title,message).then(function(finish){var promise;return promise=$ctrl.deleteMyFilter(customFilterName),promise.then(function(){return promise=$ctrl.loadMyFilters(),promise.then(function(filters){return finish(),$scope.filters.myFilters=filters,renderFilters($scope.filters.myFilters)}),promise.then(null,function(){return finish()})}),promise.then(null,function(){return finish(!1),$confirm.notify("error")})})}),$el.on("click",".save-filters",function(event){return event.preventDefault(),renderFilters($scope.filters.myFilters),showFilters("My filters","myFilters"),$el.find(".save-filters").hide(),$el.find(".my-filter-name").removeClass("hidden"),$el.find(".my-filter-name").focus()}),$el.on("keyup",".my-filter-name",function(event){var newFilter,promise,target;return event.preventDefault(),13===event.keyCode?(target=angular.element(event.currentTarget),newFilter=target.val(),$loading.start($el.find(".new")),promise=$ctrl.saveCurrentFiltersTo(newFilter),promise.then(function(){var loadPromise;return loadPromise=$ctrl.loadMyFilters(),loadPromise.then(function(filters){var currentfilterstype;return $loading.finish($el.find(".new")),$scope.filters.myFilters=filters,currentfilterstype=$el.find("h2 a.subfilter span.title").prop("data-type"),"myFilters"===currentfilterstype&&renderFilters($scope.filters.myFilters),$el.find(".my-filter-name").addClass("hidden"),$el.find(".save-filters").show()}),loadPromise.then(null,function(){return $loading.finish($el.find(".new")),$confirm.notify("error","Error loading custom filters")})}),promise.then(null,function(){return $loading.finish($el.find(".new")),$el.find(".my-filter-name").val(newFilter).focus().select(),$confirm.notify("error","Filter not saved")})):27===event.keyCode?($el.find(".my-filter-name").val(""),$el.find(".my-filter-name").addClass("hidden"),$el.find(".save-filters").show()):void 0})},{link:link}},module.directive("tgIssuesFilters",["$log","$tgLocation","$tgResources","$tgConfirm","$tgLoading","$tgTemplate",IssuesFiltersDirective]),IssueStatusInlineEditionDirective=function($repo,$template,$rootscope){var link,selectionTemplate,updateIssueStatus;return selectionTemplate=$template.get("issue/issue-status-inline-edition-selection.html",!0),updateIssueStatus=function($el,issue,issueStatusById){var issueStatusDom,issueStatusDomParent,status;return issueStatusDomParent=$el.find(".issue-status"),issueStatusDom=$el.find(".issue-status .issue-status-bind"),status=issueStatusById[issue.status],status?(issueStatusDom.text(status.name),issueStatusDom.prop("title",status.name),issueStatusDomParent.css("color",status.color)):void 0},link=function($scope,$el,$attrs){var $ctrl,issue;return $ctrl=$el.controller(),issue=$scope.$eval($attrs.tgIssueStatusInlineEdition),$el.on("click",".issue-status",function(event){return event.preventDefault(),event.stopPropagation(),$el.find(".pop-status").popover().open()}),$el.on("click",".status",function(event){var filter,j,len,ref,target;for(event.preventDefault(),event.stopPropagation(),target=angular.element(event.currentTarget),ref=$scope.filters.statuses,j=0,len=ref.length;len>j;j++)filter=ref[j],filter.id===issue.status&&filter.count--;return issue.status=target.data("status-id"),$el.find(".pop-status").popover().close(),updateIssueStatus($el,issue,$scope.issueStatusById),$scope.$apply(function(){var k,len1,ref1;for($repo.save(issue).then,ref1=$scope.filters.statuses,k=0,len1=ref1.length;len1>k;k++)filter=ref1[k],filter.id===issue.status&&filter.count++;return $rootscope.$broadcast("filters:issueupdate",$scope.filters)})}),taiga.bindOnce($scope,"project",function(project){return $el.append(selectionTemplate({statuses:project.issue_statuses})),updateIssueStatus($el,issue,$scope.issueStatusById),-1===project.my_permissions.indexOf("modify_issue")?($el.unbind("click"),$el.find("a").addClass("not-clickable")):void 0}),$scope.$watch($attrs.tgIssueStatusInlineEdition,function(){return function(val){return updateIssueStatus($el,val,$scope.issueStatusById)}}(this)),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgIssueStatusInlineEdition",["$tgRepo","$tgTemplate","$rootScope",IssueStatusInlineEditionDirective]),IssueAssignedToInlineEditionDirective=function($repo,$rootscope){var link,template;return template=_.template(' \n<%- name %> '),link=function($scope,$el,$attrs){var $ctrl,issue,updateIssue;return updateIssue=function(issue){var ctx,member;return ctx={name:"Unassigned",imgurl:"/images/unnamed.png"},member=$scope.usersById[issue.assigned_to],member&&(ctx.imgurl=member.photo,ctx.name=member.full_name_display),$el.find(".avatar").html(template(ctx)),$el.find(".issue-assignedto").attr("title",ctx.name)},$ctrl=$el.controller(),issue=$scope.$eval($attrs.tgIssueAssignedToInlineEdition),updateIssue(issue),$el.on("click",".issue-assignedto",function(){return $rootscope.$broadcast("assigned-to:add",issue)}),taiga.bindOnce($scope,"project",function(project){return-1===project.my_permissions.indexOf("modify_issue")?($el.unbind("click"),$el.find("a").addClass("not-clickable")):void 0}),$scope.$on("assigned-to:added",function(){return function(ctx,userId,updatedIssue){return updatedIssue.id===issue.id?(updatedIssue.assigned_to=userId,$repo.save(updatedIssue),updateIssue(updatedIssue)):void 0}}(this)),$scope.$watch($attrs.tgIssueAssignedToInlineEdition,function(){return function(val){return updateIssue(val)}}(this)),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgIssueAssignedToInlineEdition",["$tgRepo","$rootScope",IssueAssignedToInlineEditionDirective])}.call(this),function(){var UsClientRequirementButtonDirective,UsStatusButtonDirective,UsStatusDisplayDirective,UsTasksProgressDisplayDirective,UsTeamRequirementButtonDirective,UserStoryDetailController,bindOnce,groupBy,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,module=angular.module("taigaUserStories"),UserStoryDetailController=function(superClass){function UserStoryDetailController(scope,rootscope,repo,confirm,rs,params,q,location,log,appTitle,navUrls,analytics,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.log=log,this.appTitle=appTitle,this.navUrls=navUrls,this.analytics=analytics,this.scope.usRef=this.params.usref,this.scope.sectionName="User Story Details",this.initializeEventHandlers(),promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set(_this.scope.us.subject+" - "+_this.scope.project.name),_this.initializeOnDeleteGoToUrl()}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(UserStoryDetailController,superClass),UserStoryDetailController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$log","$appTitle","$tgNavUrls","$tgAnalytics","tgLoader"],UserStoryDetailController.prototype.initializeEventHandlers=function(){return this.scope.$on("related-tasks:update",function(_this){return function(){return _this.loadUs(),_this.scope.tasks=_.clone(_this.scope.tasks,!1)}}(this)),this.scope.$on("attachment:create",function(_this){return function(){return _this.analytics.trackEvent("attachment","create","create attachment on userstory",1),_this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("attachment:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("attachment:delete",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("custom-attributes-values:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this))},UserStoryDetailController.prototype.initializeOnDeleteGoToUrl=function(){var ctx;return ctx={project:this.scope.project.slug},this.scope.onDeleteGoToUrl=this.navUrls.resolve("project",ctx),this.scope.project.is_backlog_activated?this.scope.us.milestone?(ctx.sprint=this.scope.sprint.slug,this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-taskboard",ctx)):this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-backlog",ctx):this.scope.project.is_kanban_activated?this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-kanban",ctx):void 0},UserStoryDetailController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return _this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.statusList=project.us_statuses,_this.scope.statusById=groupBy(project.us_statuses,function(x){return x.id}),_this.scope.taskStatusById=groupBy(project.task_statuses,function(x){return x.id}),_this.scope.membersById=groupBy(project.memberships,function(x){return x.user}),_this.scope.pointsList=_.sortBy(project.points,"order"),_this.scope.pointsById=groupBy(_this.scope.pointsList,function(e){return e.id}),project}}(this))},UserStoryDetailController.prototype.loadUs=function(){return this.rs.userstories.getByRef(this.scope.projectId,this.params.usref).then(function(_this){return function(us){var ctx;return _this.scope.us=us,_this.scope.usId=us.id,_this.scope.commentModel=us,null!=_this.scope.us.neighbors.previous.ref&&(ctx={project:_this.scope.project.slug,ref:_this.scope.us.neighbors.previous.ref},_this.scope.previousUrl=_this.navUrls.resolve("project-userstories-detail",ctx)),null!=_this.scope.us.neighbors.next.ref&&(ctx={project:_this.scope.project.slug,ref:_this.scope.us.neighbors.next.ref},_this.scope.nextUrl=_this.navUrls.resolve("project-userstories-detail",ctx)),us}}(this))},UserStoryDetailController.prototype.loadSprint=function(){return this.scope.us.milestone?this.rs.sprints.get(this.scope.us.project,this.scope.us.milestone).then(function(_this){return function(sprint){return _this.scope.sprint=sprint,sprint}}(this)):void 0},UserStoryDetailController.prototype.loadTasks=function(){return this.rs.tasks.list(this.scope.projectId,null,this.scope.usId).then(function(_this){return function(tasks){return _this.scope.tasks=tasks,tasks}}(this))},UserStoryDetailController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.loadUs().then(function(){return _this.q.all([_this.loadSprint(),_this.loadTasks()])})}}(this))},UserStoryDetailController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("UserStoryDetailController",UserStoryDetailController),UsStatusDisplayDirective=function($template){var link,template;return template=$template.get("common/components/status-display.html",!0),link=function($scope,$el,$attrs){var render;return render=function(us){var html;return html=template({is_closed:us.is_closed,status:$scope.statusById[us.status]}),$el.html(html)},$scope.$watch($attrs.ngModel,function(us){return null!=us?render(us):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgUsStatusDisplay",["$tgTemplate",UsStatusDisplayDirective]),UsTasksProgressDisplayDirective=function($template){var link,template;return template=$template.get("us/us-task-progress.html",!0),link=function($scope,$el,$attrs){var render;return render=function(tasks){var html,progress,totalClosedTasks,totalTasks;return totalTasks=tasks.length,totalClosedTasks=_.filter(tasks,function(){return function(task){return $scope.taskStatusById[task.status].is_closed}}(this)).length,progress=totalTasks>0?100*totalClosedTasks/totalTasks:0,html=template({totalTasks:totalTasks,totalClosedTasks:totalClosedTasks,progress:progress}),$el.html(html)},$scope.$watch($attrs.ngModel,function(tasks){return null!=tasks?render(tasks):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgUsTasksProgressDisplay",["$tgTemplate",UsTasksProgressDisplayDirective]),UsStatusButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("us/us-status-button.html",!0),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_us")},render=function(){return function(us){var html,status;return status=$scope.statusById[us.status],html=template({status:status,statuses:$scope.statusList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(status){var onError,onSuccess,us;return us=$model.$modelValue.clone(),us.status=status,$.fn.popover().closeAll(),$model.$setViewValue(us),onSuccess=function(){return $confirm.notify("success"),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),us.revert(),$model.$setViewValue(us),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save($model.$modelValue).then(onSuccess,onError)}}(this)),$el.on("click",".status-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-status").popover().open():void 0}),$el.on("click",".status",function(event){var status,target;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),status=target.data("status-id"),save(status)):void 0}),$scope.$watch($attrs.ngModel,function(us){return us?render(us):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgUsStatusButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",UsStatusButtonDirective]),UsTeamRequirementButtonDirective=function($rootscope,$tgrepo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("us/us-team-requirement-button.html",!0),link=function($scope,$el,$attrs,$model){var canEdit,render,save;return canEdit=function(){return-1!==$scope.project.my_permissions.indexOf("modify_us")},render=function(us){var ctx,html;return canEdit()||us.team_requirement?(ctx={canEdit:canEdit(),isRequired:us.team_requirement},html=template(ctx),$el.html(html)):void $el.html("")},save=$qqueue.bindAdd(function(){return function(team_requirement){var promise,us;return us=$model.$modelValue.clone(),us.team_requirement=team_requirement,$model.$setViewValue(us),$loading.start($el.find("label")),promise=$tgrepo.save($model.$modelValue),promise.then(function(){return $loading.finish($el.find("label")),$rootscope.$broadcast("history:reload")}),promise.then(null,function(){return $loading.finish($el.find("label")),$confirm.notify("error"),us.revert(),$model.$setViewValue(us)})}}(this)),$el.on("click",".team-requirement",function(){var team_requirement;if(canEdit())return team_requirement=!$model.$modelValue.team_requirement,save(team_requirement)}),$scope.$watch($attrs.ngModel,function(us){return us?render(us):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgUsTeamRequirementButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",UsTeamRequirementButtonDirective]),UsClientRequirementButtonDirective=function($rootscope,$tgrepo,$confirm,$loading,$qqueue,$template){var link,template;return template=$template.get("us/us-client-requirement-button.html",!0),link=function($scope,$el,$attrs,$model){var canEdit,render,save;return canEdit=function(){return-1!==$scope.project.my_permissions.indexOf("modify_us")},render=function(us){var ctx,html;return canEdit()||us.client_requirement?(ctx={canEdit:canEdit(),isRequired:us.client_requirement},html=template(ctx),$el.html(html)):void $el.html("")},save=$qqueue.bindAdd(function(){return function(client_requirement){var promise,us;return us=$model.$modelValue.clone(),us.client_requirement=client_requirement,$model.$setViewValue(us),$loading.start($el.find("label")),promise=$tgrepo.save($model.$modelValue),promise.then(function(){return $loading.finish($el.find("label")),$rootscope.$broadcast("history:reload")}),promise.then(null,function(){return $loading.finish($el.find("label")),$confirm.notify("error"),us.revert(),$model.$setViewValue(us)})}}(this)),$el.on("click",".client-requirement",function(){var client_requirement;if(canEdit())return client_requirement=!$model.$modelValue.client_requirement,save(client_requirement)}),$scope.$watch($attrs.ngModel,function(us){return us?render(us):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgUsClientRequirementButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue","$tgTemplate",UsClientRequirementButtonDirective])}.call(this),function(){var TaskDetailController,TaskIsIocaineButtonDirective,TaskStatusButtonDirective,TaskStatusDisplayDirective,groupBy,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,groupBy=this.taiga.groupBy,module=angular.module("taigaTasks"),TaskDetailController=function(superClass){function TaskDetailController(scope,rootscope,repo,confirm,rs,params,q,location,log,appTitle,navUrls,analytics,tgLoader){var promise;
this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.log=log,this.appTitle=appTitle,this.navUrls=navUrls,this.analytics=analytics,this.scope.taskRef=this.params.taskref,this.scope.sectionName="Task Details",this.initializeEventHandlers(),promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set(_this.scope.task.subject+" - "+_this.scope.project.name),_this.initializeOnDeleteGoToUrl()}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(TaskDetailController,superClass),TaskDetailController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$log","$appTitle","$tgNavUrls","$tgAnalytics","tgLoader"],TaskDetailController.prototype.initializeEventHandlers=function(){return this.scope.$on("attachment:create",function(_this){return function(){return _this.analytics.trackEvent("attachment","create","create attachment on task",1),_this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("attachment:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("attachment:delete",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this)),this.scope.$on("custom-attributes-values:edit",function(_this){return function(){return _this.rootscope.$broadcast("history:reload")}}(this))},TaskDetailController.prototype.initializeOnDeleteGoToUrl=function(){var ctx;if(ctx={project:this.scope.project.slug},this.scope.onDeleteGoToUrl=this.navUrls.resolve("project",ctx),this.scope.project.is_backlog_activated){if(this.scope.task.milestone)return ctx.sprint=this.scope.sprint.slug,this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-taskboard",ctx);if(this.scope.task.us)return ctx.ref=this.scope.us.ref,this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-userstories-detail",ctx)}else if(this.scope.project.is_kanban_activated&&this.scope.us)return ctx.ref=this.scope.us.ref,this.scope.onDeleteGoToUrl=this.navUrls.resolve("project-userstories-detail",ctx)},TaskDetailController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return _this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.statusList=project.task_statuses,_this.scope.statusById=groupBy(project.task_statuses,function(x){return x.id}),_this.scope.membersById=groupBy(project.memberships,function(x){return x.user}),project}}(this))},TaskDetailController.prototype.loadTask=function(){return this.rs.tasks.getByRef(this.scope.projectId,this.params.taskref).then(function(_this){return function(task){var ctx;return _this.scope.task=task,_this.scope.taskId=task.id,_this.scope.commentModel=task,null!=_this.scope.task.neighbors.previous.ref&&(ctx={project:_this.scope.project.slug,ref:_this.scope.task.neighbors.previous.ref},_this.scope.previousUrl=_this.navUrls.resolve("project-tasks-detail",ctx)),null!=_this.scope.task.neighbors.next.ref&&(ctx={project:_this.scope.project.slug,ref:_this.scope.task.neighbors.next.ref},_this.scope.nextUrl=_this.navUrls.resolve("project-tasks-detail",ctx)),task}}(this))},TaskDetailController.prototype.loadSprint=function(){return this.scope.task.milestone?this.rs.sprints.get(this.scope.task.project,this.scope.task.milestone).then(function(_this){return function(sprint){return _this.scope.sprint=sprint,sprint}}(this)):void 0},TaskDetailController.prototype.loadUserStory=function(){return this.scope.task.user_story?this.rs.userstories.get(this.scope.task.project,this.scope.task.user_story).then(function(_this){return function(us){return _this.scope.us=us,us}}(this)):void 0},TaskDetailController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.loadTask().then(function(){return _this.q.all([_this.loadSprint(),_this.loadUserStory()])})}}(this))},TaskDetailController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("TaskDetailController",TaskDetailController),TaskStatusDisplayDirective=function($template){var link,template;return template=$template.get("common/components/status-display.html",!0),link=function($scope,$el,$attrs){var render;return render=function(task){var html,status;return status=$scope.statusById[task.status],html=template({is_closed:status.is_closed,status:status}),$el.html(html)},$scope.$watch($attrs.ngModel,function(task){return null!=task?render(task):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgTaskStatusDisplay",["$tgTemplate",TaskStatusDisplayDirective]),TaskStatusButtonDirective=function($rootScope,$repo,$confirm,$loading,$qqueue){var link,template;return template=_.template('\n
\n
<%- status.name %> \n <% if(editable){ %>
<% }%>\n
status \n\n
\n <% _.each(statuses, function(st) { %>\n <%- st.name %> \n <% }); %>\n \n
'),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_task")},render=function(){return function(task){var html,status;return status=$scope.statusById[task.status],html=template({status:status,statuses:$scope.statusList,editable:isEditable()}),$el.html(html)}}(this),save=$qqueue.bindAdd(function(){return function(status){var onError,onSuccess,task;return task=$model.$modelValue.clone(),task.status=status,$model.$setViewValue(task),onSuccess=function(){return $confirm.notify("success"),$rootScope.$broadcast("history:reload"),$loading.finish($el.find(".level-name"))},onError=function(){return $confirm.notify("error"),task.revert(),$model.$setViewValue(task),$loading.finish($el.find(".level-name"))},$loading.start($el.find(".level-name")),$repo.save($model.$modelValue).then(onSuccess,onError)}}(this)),$el.on("click",".status-data",function(event){return event.preventDefault(),event.stopPropagation(),isEditable()?$el.find(".pop-status").popover().open():void 0}),$el.on("click",".status",function(event){var target;return event.preventDefault(),event.stopPropagation(),isEditable()?(target=angular.element(event.currentTarget),$.fn.popover().closeAll(),save(target.data("status-id"))):void 0}),$scope.$watch($attrs.ngModel,function(task){return task?render(task):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgTaskStatusButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue",TaskStatusButtonDirective]),TaskIsIocaineButtonDirective=function($rootscope,$tgrepo,$confirm,$loading,$qqueue){var link,template;return template=_.template('\n \n Iocaine\n \n \n '),link=function($scope,$el,$attrs,$model){var isEditable,render,save;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_task")},render=function(task){var ctx,html;return isEditable()||task.is_iocaine?(ctx={isIocaine:task.is_iocaine,isEditable:isEditable()},html=template(ctx),$el.html(html)):void $el.html("")},save=$qqueue.bindAdd(function(){return function(is_iocaine){var promise,task;return task=$model.$modelValue.clone(),task.is_iocaine=is_iocaine,$model.$setViewValue(task),$loading.start($el.find("label")),promise=$tgrepo.save(task),promise.then(function(){return $confirm.notify("success"),$rootscope.$broadcast("history:reload")}),promise.then(null,function(){return task.revert(),$model.$setViewValue(task),$confirm.notify("error")}),promise["finally"](function(){return $loading.finish($el.find("label"))})}}(this)),$el.on("click",".is-iocaine",function(){var is_iocaine;if(isEditable())return is_iocaine=!$model.$modelValue.is_iocaine,save(is_iocaine)}),$scope.$watch($attrs.ngModel,function(task){return task?render(task):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgTaskIsIocaineButton",["$rootScope","$tgRepo","$tgConfirm","$tgLoading","$tgQqueue",TaskIsIocaineButtonDirective])}.call(this),function(){var LeaveProjectDirective,TeamController,TeamFiltersDirective,TeamMemberCurrentUserDirective,TeamMemberStatsDirective,TeamMembersDirective,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,module=angular.module("taigaTeam"),TeamController=function(superClass){function TeamController(scope,rootscope,repo,rs,params,q,location,navUrls,appTitle,auth,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,this.auth=auth,this.scope.sectionName="Team",promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Team - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(TeamController,superClass),TeamController.$inject=["$scope","$rootScope","$tgRepo","$tgResources","$routeParams","$q","$location","$tgNavUrls","$appTitle","$tgAuth","tgLoader"],TeamController.prototype.setRole=function(role){return this.scope.filtersRole=role?role:null},TeamController.prototype.loadMembers=function(){return this.rs.memberships.list(this.scope.projectId,{},!1).then(function(_this){return function(data){var currentUser,i,len,membership,ref;for(currentUser=_this.auth.getUser(),null!=currentUser&&null==currentUser.photo&&(currentUser.photo="/images/unnamed.png"),_this.scope.currentUser=_.find(data,function(membership){return null!=currentUser&&membership.user===currentUser.id}),_this.scope.totals={},_.forEach(data,function(membership){return _this.scope.totals[membership.user]=0}),_this.scope.memberships=_.filter(data,function(membership){return membership.user&&(null==currentUser||membership.user!==currentUser.id)&&membership.is_user_active?membership:void 0}),ref=_this.scope.memberships,i=0,len=ref.length;len>i;i++)membership=ref[i],null==membership.photo&&(membership.photo="/images/unnamed.png");return data}}(this))},TeamController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return _this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.issuesEnabled=project.is_issues_activated,_this.scope.tasksEnabled=project.is_kanban_activated||project.is_backlog_activated,_this.scope.wikiEnabled=project.is_wiki_activated,project}}(this))},TeamController.prototype.loadMemberStats=function(){return this.rs.projects.memberStats(this.scope.projectId).then(function(_this){return function(stats){var totals;return totals={},_.forEach(_this.scope.totals,function(total,userId){var vals;return vals=_.map(stats,function(memberStats){return memberStats[userId]}),total=_.reduce(vals,function(sum,el){return sum+el}),_this.scope.totals[userId]=total}),_this.scope.stats=_this.processStats(stats),_this.scope.stats.totals=_this.scope.totals}}(this))},TeamController.prototype.processStat=function(stat){var max,min,singleStat;return max=_.max(stat),min=_.min(stat),singleStat=_.map(stat,function(value,key){return value===min?[key,.1]:value===max?[key,1]:[key,.5*value/max]}),singleStat=_.object(singleStat)},TeamController.prototype.processStats=function(stats){var key,value;for(key in stats)value=stats[key],stats[key]=this.processStat(value);return stats},TeamController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.loadMembers().then(function(){return _this.loadMemberStats()})}}(this))},TeamController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("TeamController",TeamController),TeamFiltersDirective=function(){return{templateUrl:"team/team-filter.html"}},module.directive("tgTeamFilters",[TeamFiltersDirective]),TeamMemberStatsDirective=function(){return{templateUrl:"team/team-member-stats.html",scope:{stats:"=",userId:"=user",issuesEnabled:"=issuesenabled",tasksEnabled:"=tasksenabled",wikiEnabled:"=wikienabled"}}},module.directive("tgTeamMemberStats",TeamMemberStatsDirective),TeamMemberCurrentUserDirective=function(){return{templateUrl:"team/team-member-current-user.html",scope:{projectId:"=projectid",currentUser:"=currentuser",stats:"=",issuesEnabled:"=issuesenabled",tasksEnabled:"=tasksenabled",wikiEnabled:"=wikienabled"}}},module.directive("tgTeamCurrentUser",TeamMemberCurrentUserDirective),TeamMembersDirective=function(){var template;return template="team/team-members.html",{templateUrl:template,scope:{memberships:"=",filtersQ:"=filtersq",filtersRole:"=filtersrole",stats:"=",issuesEnabled:"=issuesenabled",tasksEnabled:"=tasksenabled",wikiEnabled:"=wikienabled"}}},module.directive("tgTeamMembers",TeamMembersDirective),LeaveProjectDirective=function($repo,$confirm,$location,$rs,$navurls){var link;return link=function($scope,$el,$attrs){return $scope.leave=function(){return $confirm.ask("Leave this project","Are you sure you want to leave the project?").then(function(){return function(finish){var promise;return promise=$rs.projects.leave($attrs.projectid),promise.then(function(){return finish(),$confirm.notify("success"),$location.path($navurls.resolve("home"))}),promise.then(null,function(response){return finish(),$confirm.notify("error",response.data._error_message)})}}(this))}},{scope:{},templateUrl:"team/leave-project.html",link:link}},module.directive("tgLeaveProject",["$tgRepo","$tgConfirm","$tgLocation","$tgResources","$tgNavUrls",LeaveProjectDirective]),module.filter("membersRoleFilter",function(){return function(input,filtersRole){return null!=filtersRole?_.filter(input,{role:filtersRole.id}):input}})}.call(this),function(){var EditableWikiContentDirective,WikiDetailController,WikiSummaryDirective,bindOnce,debounce,groupBy,mixOf,module,taiga,unslugify,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,unslugify=this.taiga.unslugify,debounce=this.taiga.debounce,module=angular.module("taigaWiki"),WikiDetailController=function(superClass){function WikiDetailController(scope,rootscope,repo,model,confirm,rs,params,q,location,filter,log,appTitle,navUrls,analytics,tgLoader){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.model=model,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.filter=filter,this.log=log,this.appTitle=appTitle,this.navUrls=navUrls,this.analytics=analytics,this.scope.projectSlug=this.params.pslug,this.scope.wikiSlug=this.params.slug,this.scope.sectionName="Wiki",promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Wiki - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(WikiDetailController,superClass),WikiDetailController.$inject=["$scope","$rootScope","$tgRepo","$tgModel","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$filter","$log","$appTitle","$tgNavUrls","$tgAnalytics","tgLoader"],WikiDetailController.prototype.loadProject=function(){return this.rs.projects.getBySlug(this.params.pslug).then(function(_this){return function(project){return project.is_wiki_activated||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.projectId=project.id,_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.membersById=groupBy(project.memberships,function(x){return x.user}),project}}(this))},WikiDetailController.prototype.loadWiki=function(){var promise;return promise=this.rs.wiki.getBySlug(this.scope.projectId,this.params.slug),promise.then(function(_this){return function(wiki){return _this.scope.wiki=wiki,_this.scope.wikiId=wiki.id,_this.scope.wiki}}(this)),promise.then(null,function(_this){return function(){var data;return _this.scope.wikiId=null,-1===_this.scope.project.my_permissions.indexOf("add_wiki_page")?null:(data={project:_this.scope.projectId,slug:_this.scope.wikiSlug,content:""},_this.scope.wiki=_this.model.make_model("wiki",data),_this.scope.wiki)}}(this))},WikiDetailController.prototype.loadWikiLinks=function(){return this.rs.wiki.listLinks(this.scope.projectId).then(function(_this){return function(wikiLinks){return _this.scope.wikiLinks=wikiLinks}}(this))},WikiDetailController.prototype.loadInitialData=function(){var promise;return promise=this.loadProject(),promise.then(function(_this){return function(project){return _this.fillUsersAndRoles(project.users,project.roles),_this.q.all([_this.loadWikiLinks(),_this.loadWiki()])}}(this))},WikiDetailController.prototype["delete"]=function(){var message,title;return title="Delete Wiki Page",message=unslugify(this.scope.wiki.slug),this.confirm.askOnDelete(title,message).then(function(_this){return function(finish){var onError,onSuccess;return onSuccess=function(){var ctx;return finish(),ctx={project:_this.scope.projectSlug},_this.location.path(_this.navUrls.resolve("project-wiki",ctx)),_this.confirm.notify("success")},onError=function(){return finish(!1),_this.confirm.notify("error")},_this.repo.remove(_this.scope.wiki).then(onSuccess,onError)}}(this))},WikiDetailController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("WikiDetailController",WikiDetailController),WikiSummaryDirective=function($log,$template){var link,template;return template=$template.get("wiki/wiki-summary.html",!0),link=function($scope,$el,$attrs){var render;return render=function(wiki){var ctx,html,user;return null==$scope.usersById?$log.error("WikiSummaryDirective requires userById set in scope."):user=$scope.usersById[wiki.last_modifier],user=void 0===user?{name:"unknown",imgUrl:"/images/unnamed.png"}:{name:user.full_name_display,imgUrl:user.photo},ctx={totalEditions:wiki.editions,lastModifiedDate:moment(wiki.modified_date).format("DD MMM YYYY HH:mm"),user:user},html=template(ctx),$el.html(html)},$scope.$watch($attrs.ngModel,function(wikiPage){return wikiPage?render(wikiPage):void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgWikiSummary",["$log","$tgTemplate",WikiSummaryDirective]),EditableWikiContentDirective=function($window,$document,$repo,$confirm,$loading,$analytics,$qqueue){var link;return link=function($scope,$el,$attrs,$model){var cancelEdition,disableEdition,getSelectedText,isEditable,save,switchToEditMode,switchToReadMode;return isEditable=function(){return-1!==$scope.project.my_permissions.indexOf("modify_wiki_page")},switchToEditMode=function(){return $el.find(".edit-wiki-content").show(),$el.find(".view-wiki-content").hide(),$el.find("textarea").focus()},switchToReadMode=function(){return $el.find(".edit-wiki-content").hide(),$el.find(".view-wiki-content").show()},disableEdition=function(){return $el.find(".view-wiki-content .edit").remove(),$el.find(".edit-wiki-content").remove()},cancelEdition=function(){return $model.$modelValue.id?($scope.$apply(function(){return function(){return $model.$modelValue.revert()}}(this)),switchToReadMode()):void 0},getSelectedText=function(){return $window.getSelection?$window.getSelection().toString():$document.selection?$document.selection.createRange().text:null},save=$qqueue.bindAdd(function(wiki){var onError,onSuccess,promise;return onSuccess=function(wikiPage){return null==wiki.id&&$analytics.trackEvent("wikipage","create","create wiki page",1),$model.$setViewValue(wikiPage),$confirm.notify("success"),switchToReadMode()},onError=function(){return $confirm.notify("error")},$loading.start($el.find(".save-container")),promise=null!=wiki.id?$repo.save(wiki).then(onSuccess,onError):$repo.create("wiki",wiki).then(onSuccess,onError),promise["finally"](function(){return $loading.finish($el.find(".save-container"))})}),$el.on("mousedown",".view-wiki-content",function(event){var target;target=angular.element(event.target),isEditable()&&2===event.button}),$el.on("mouseup",".view-wiki-content",function(event){var target;return target=angular.element(event.target),getSelectedText()||!isEditable()||target.is("a")||target.is("pre")?void 0:switchToEditMode()}),$el.on("click",".save",debounce(2e3,function(){return save($scope.wiki)})),$el.on("click",".cancel",function(){return cancelEdition()}),$el.on("keydown","textarea",function(event){return 27===event.keyCode?cancelEdition():void 0}),$scope.$watch($attrs.ngModel,function(wikiPage){return wikiPage?isEditable()?($el.addClass("editable"),null==wikiPage.id?switchToEditMode():void 0):disableEdition():void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,restrict:"EA",require:"ngModel",templateUrl:"wiki/editable-wiki-content.html"}},module.directive("tgEditableWikiContent",["$window","$document","$tgRepo","$tgConfirm","$tgLoading","$tgAnalytics","$tgQqueue",EditableWikiContentDirective])}.call(this),function(){var WikiNavDirective,bindOnce,groupBy,mixOf,module,slugify,taiga,unslugify;taiga=this.taiga,mixOf=this.taiga.mixOf,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,slugify=this.taiga.slugify,unslugify=this.taiga.slugify,module=angular.module("taigaWiki"),WikiNavDirective=function($tgrepo,$log,$location,$confirm,$navUrls,$analytics,$loading,$template){var link,template;return template=$template.get("wiki/wiki-nav.html",!0),link=function($scope,$el,$attrs){var $ctrl,render;return $ctrl=$el.controller(),null==$attrs.ngModel?$log.error("WikiNavDirective: no ng-model attr is defined"):(render=function(wikiLinks){var addWikiLinkPermission,deleteWikiLinkPermission,html;return addWikiLinkPermission=$scope.project.my_permissions.indexOf("add_wiki_link")>-1,deleteWikiLinkPermission=$scope.project.my_permissions.indexOf("delete_wiki_link")>-1,html=template({wikiLinks:wikiLinks,projectSlug:$scope.projectSlug,addWikiLinkPermission:addWikiLinkPermission,deleteWikiLinkPermission:deleteWikiLinkPermission}),$el.off(),$el.html(html),$el.on("click",".wiki-link .link-title",function(event){var linkId,linkSlug,target;return event.preventDefault(),target=angular.element(event.currentTarget),linkId=target.parents(".wiki-link").data("id"),linkSlug=$scope.wikiLinks[linkId].href,$scope.$apply(function(){var ctx;return ctx={project:$scope.projectSlug,slug:linkSlug},$location.path($navUrls.resolve("project-wiki-page",ctx))})}),$el.on("click",".add-button",function(event){return event.preventDefault(),$el.find(".new").removeClass("hidden"),$el.find(".new input").focus(),$el.find(".add-button").hide()}),$el.on("click",".wiki-link .icon-delete",function(event){var linkId,message,target,title;return event.preventDefault(),event.stopPropagation(),target=angular.element(event.currentTarget),linkId=target.parents(".wiki-link").data("id"),title="Delete Wiki Link",message=$scope.wikiLinks[linkId].title,$confirm.askOnDelete(title,message).then(function(){return function(finish){var promise;return promise=$tgrepo.remove($scope.wikiLinks[linkId]),promise.then(function(){return promise=$ctrl.loadWikiLinks(),promise.then(function(){return finish(),render($scope.wikiLinks)}),promise.then(null,function(){return finish()})}),promise.then(null,function(){return finish(!1),$confirm.notify("error")})}}(this))}),$el.on("keyup",".new input",function(event){var newLink,promise,target;return event.preventDefault(),13===event.keyCode?(target=angular.element(event.currentTarget),newLink=target.val(),$loading.start($el.find(".new")),promise=$tgrepo.create("wiki-links",{project:$scope.projectId,title:newLink,href:slugify(newLink)}),promise.then(function(){var loadPromise;return $analytics.trackEvent("wikilink","create","create wiki link",1),loadPromise=$ctrl.loadWikiLinks(),loadPromise.then(function(){return $loading.finish($el.find(".new")),$el.find(".new").addClass("hidden"),$el.find(".new input").val(""),$el.find(".add-button").show(),render($scope.wikiLinks)}),loadPromise.then(null,function(){return $loading.finish($el.find(".new")),$el.find(".new").addClass("hidden"),$el.find(".new input").val(""),$el.find(".add-button").show(),$confirm.notify("error","Error loading wiki links")})}),promise.then(null,function(error){var ref;return $loading.finish($el.find(".new")),$el.find(".new input").val(newLink),$el.find(".new input").focus().select(),null!=(null!=error&&null!=(ref=error.__all__)?ref[0]:void 0)?$confirm.notify("error","The link already exists"):$confirm.notify("error")})):27===event.keyCode?(target=angular.element(event.currentTarget),$el.find(".new").addClass("hidden"),$el.find(".new input").val(""),$el.find(".add-button").show()):void 0})},bindOnce($scope,$attrs.ngModel,render))},{link:link}},module.directive("tgWikiNav",["$tgRepo","$log","$tgLocation","$tgConfirm","$tgNavUrls","$tgAnalytics","$tgLoading","$tgTemplate",WikiNavDirective])}.call(this),function(){var CreateMembersDirective,MAX_MEMBERSHIP_FIELDSETS,debounce,module,taiga;taiga=this.taiga,debounce=this.taiga.debounce,module=angular.module("taigaKanban"),MAX_MEMBERSHIP_FIELDSETS=4,CreateMembersDirective=function($rs,$rootScope,$confirm,$loading,lightboxService){var extraTextTemplate,link,template;return extraTextTemplate='',template=_.template('\n
\n data-required="true" <% } %> data-type="email" />\n \n
\n data-required="true" <% } %> data-required="true">\n <% _.each(roleList, function(role) { %>\n <%- role.name %> \n <% }); %>\n \n \n \n
'),link=function($scope,$el){var createFieldSet,resetForm,submit,submitButton;return createFieldSet=function(required){var ctx;return null==required&&(required=!0),ctx={roleList:$scope.roles,required:required},template(ctx)},resetForm=function(){var fieldSet,invitations;return $el.find("form textarea").remove(""),$el.find("form .add-member-wrapper").remove(),invitations=$el.find(".add-member-forms"),invitations.html(extraTextTemplate),fieldSet=createFieldSet(),invitations.prepend(fieldSet)},$scope.$on("membersform:new",function(){return resetForm(),lightboxService.open($el)}),$scope.$on("$destroy",function(){return $el.off()}),$el.on("click",".delete-fieldset",function(event){var fieldSet,lastActionButton,target;return event.preventDefault(),target=angular.element(event.currentTarget),fieldSet=target.closest(".add-member-wrapper"),fieldSet.remove(),lastActionButton=$el.find("fieldset:last > a"),lastActionButton.hasClass("icon-delete delete-fieldset")?lastActionButton.removeClass("icon-delete delete-fieldset").addClass("icon-plus add-fieldset"):void 0}),$el.on("click",".add-fieldset",function(event){var fieldSet,newFieldSet,target;return event.preventDefault(),target=angular.element(event.currentTarget),fieldSet=target.closest(".add-member-wrapper"),target.removeClass("icon-plus add-fieldset").addClass("icon-delete delete-fieldset"),newFieldSet=createFieldSet(!1),fieldSet.after(newFieldSet),$el.find(".add-member-wrapper").length===MAX_MEMBERSHIP_FIELDSETS?$el.find(".add-member-wrapper fieldset:last > a").removeClass("icon-plus add-fieldset").addClass("icon-delete delete-fieldset"):void 0}),submit=debounce(2e3,function(){return function(event){var form,invitation_extra_text,invitations,memberWrappers,onError,onSuccess;return event.preventDefault(),$loading.start(submitButton),onSuccess=function(){return $loading.finish(submitButton),lightboxService.close($el),$confirm.notify("success"),$rootScope.$broadcast("membersform:new:success")},onError=function(){return $loading.finish(submitButton),lightboxService.close($el),$confirm.notify("error"),$rootScope.$broadcast("membersform:new:error")},form=$el.find("form").checksley(),form.destroy(),form.initialize(),form.validate()?(memberWrappers=$el.find("form .add-member-wrapper"),memberWrappers=_.filter(memberWrappers,function(mw){return angular.element(mw).find("input").hasClass("checksley-ok")}),invitations=_.map(memberWrappers,function(mw){var email,memberWrapper,role;return memberWrapper=angular.element(mw),email=memberWrapper.find("input"),role=memberWrapper.find("select"),{email:email.val(),role_id:role.val()}}),invitations.length?(invitation_extra_text=$el.find("form textarea").val(),$rs.memberships.bulkCreateMemberships($scope.project.id,invitations,invitation_extra_text).then(onSuccess,onError)):void 0):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgLbCreateMembers",["$tgResources","$rootScope","$tgConfirm","$tgLoading","lightboxService",CreateMembersDirective])}.call(this),function(){var MembershipsController,MembershipsDirective,MembershipsRowActionsDirective,MembershipsRowAdminCheckboxDirective,MembershipsRowAvatarDirective,MembershipsRowRoleSelectorDirective,bindMethods,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,bindMethods=this.taiga.bindMethods,module=angular.module("taigaAdmin"),MembershipsController=function(superClass){function MembershipsController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,analytics,appTitle){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.analytics=analytics,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Manage Members",this.scope.project={},this.scope.filters={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Membership - "+_this.scope.project.name)
}}(this)),promise.then(null,this.onInitialDataError.bind(this)),this.scope.$on("membersform:new:success",function(_this){return function(){return _this.loadMembers(),_this.analytics.trackEvent("membership","create","create memberships on admin",1)}}(this))}return extend(MembershipsController,superClass),MembershipsController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$tgAnalytics","$appTitle"],MembershipsController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.i_am_owner||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},MembershipsController.prototype.loadMembers=function(){var httpFilters;return httpFilters=this.getUrlFilters(),this.rs.memberships.list(this.scope.projectId,httpFilters).then(function(_this){return function(data){return _this.scope.memberships=_.filter(data.models,function(membership){return null===membership.user||membership.is_user_active}),_this.scope.page=data.current,_this.scope.count=data.count,_this.scope.paginatedBy=data.paginatedBy,data}}(this))},MembershipsController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadUsersAndRoles()}}(this)).then(function(_this){return function(){return _this.loadMembers()}}(this))},MembershipsController.prototype.getUrlFilters=function(){var filters;return filters=_.pick(this.location.search(),"page"),filters.page||(filters.page=1),filters},MembershipsController.prototype.addNewMembers=function(){return this.rootscope.$broadcast("membersform:new")},MembershipsController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("MembershipsController",MembershipsController),MembershipsDirective=function($template){var link,linkPagination,template;return template=$template.get("admin/admin-membership-paginator.html",!0),linkPagination=function($scope,$el,$attrs,$ctrl){var $pagEl,afterCurrent,atBegin,atEnd,beforeCurrent,getNumPages,renderPagination;return afterCurrent=2,beforeCurrent=4,atBegin=2,atEnd=2,$pagEl=$el.find(".memberships-paginator"),getNumPages=function(){var numPages;return numPages=$scope.count/$scope.paginatedBy,numPages=parseInt(numPages,10)=numPages)return void $pagEl.hide();for(pages=[],options={},options.pages=pages,options.showPrevious=$scope.page>1,options.showNext=!($scope.page===numPages),cpage=$scope.page,i=j=1,ref=numPages;ref>=1?ref>=j:j>=ref;i=ref>=1?++j:--j)i===cpage+afterCurrent&&numPages>cpage+afterCurrent+atEnd?pages.push({classes:"dots",type:"dots"}):i===cpage-beforeCurrent&&cpage>atBegin+beforeCurrent?pages.push({classes:"dots",type:"dots"}):i>cpage+afterCurrent&&numPages-atEnd>=i||cpage-beforeCurrent>i&&i>atBegin||pages.push(i===cpage?{classes:"active",num:i,type:"page-active"}:{classes:"page",num:i,type:"page"});return $pagEl.html(template(options))},$scope.$watch("memberships",function(value){return value?renderPagination():void 0}),$el.on("click",".memberships-paginator a.next",function(event){return event.preventDefault(),$scope.$apply(function(){return $ctrl.selectFilter("page",$scope.page+1),$ctrl.loadMembers()})}),$el.on("click",".memberships-paginator a.previous",function(event){return event.preventDefault(),$scope.$apply(function(){return $ctrl.selectFilter("page",$scope.page-1),$ctrl.loadMembers()})}),$el.on("click",".memberships-paginator li.page > a",function(event){var pagenum,target;return event.preventDefault(),target=angular.element(event.currentTarget),pagenum=target.data("pagenum"),$scope.$apply(function(){return $ctrl.selectFilter("page",pagenum),$ctrl.loadMembers()})})},link=function($scope,$el,$attrs){var $ctrl;return $ctrl=$el.controller(),linkPagination($scope,$el,$attrs,$ctrl),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgMemberships",["$tgTemplate",MembershipsDirective]),MembershipsRowAvatarDirective=function($log,$template){var link,template;return template=$template.get("admin/memberships-row-avatar.html",!0),link=function($scope,$el,$attrs){var member,render;return render=function(member){var ctx,html;return ctx={full_name:member.full_name?member.full_name:"",email:member.user_email?member.user_email:member.email,imgurl:member.photo?member.photo:"/images/unnamed.png"},html=template(ctx),$el.html(html)},null==$attrs.tgMembershipsRowAvatar?$log.error("MembershipsRowAvatarDirective: the directive need a member"):(member=$scope.$eval($attrs.tgMembershipsRowAvatar),render(member),$scope.$on("$destroy",function(){return $el.off()}))},{link:link}},module.directive("tgMembershipsRowAvatar",["$log","$tgTemplate",MembershipsRowAvatarDirective]),MembershipsRowAdminCheckboxDirective=function($log,$repo,$confirm,$template){var link,template;return template=$template.get("admin/admin-memberships-row-checkbox.html",!0),link=function($scope,$el,$attrs){var html,member,render;return render=function(member){var ctx,html;return ctx={inputId:"is-admin-"+member.id},html=template(ctx),$el.html(html)},null==$attrs.tgMembershipsRowAdminCheckbox?$log.error("MembershipsRowAdminCheckboxDirective: the directive need a member"):(member=$scope.$eval($attrs.tgMembershipsRowAdminCheckbox),html=render(member),member.is_owner&&$el.find(":checkbox").prop("checked",!0),$el.on("click",":checkbox",function(){return function(event){var onError,onSuccess,target;return onSuccess=function(){return $confirm.notify("success")},onError=function(data){return member.revert(),$el.find(":checkbox").prop("checked",member.is_owner),$confirm.notify("error",data.is_owner[0])},target=angular.element(event.currentTarget),member.is_owner=target.prop("checked"),$repo.save(member).then(onSuccess,onError)}}(this)),$scope.$on("$destroy",function(){return $el.off()}))},{link:link}},module.directive("tgMembershipsRowAdminCheckbox",["$log","$tgRepo","$tgConfirm","$tgTemplate",MembershipsRowAdminCheckboxDirective]),MembershipsRowRoleSelectorDirective=function($log,$repo,$confirm){var link,template;return template=_.template('\n <% _.each(roleList, function(role) { %>\n selected="selected"<% } %>>\n <%- role.name %>\n \n <% }); %>\n '),link=function($scope,$el,$attrs){var $ctrl,html,member,render;return render=function(member){var ctx,html;return ctx={roleList:$scope.roles,selectedRole:member.role},html=template(ctx),$el.html(html)},null==$attrs.tgMembershipsRowRoleSelector?$log.error("MembershipsRowRoleSelectorDirective: the directive need a member"):($ctrl=$el.controller(),member=$scope.$eval($attrs.tgMembershipsRowRoleSelector),html=render(member),$el.on("change","select",function(){return function(event){var newRole,onError,onSuccess,target;return onSuccess=function(){return $confirm.notify("success")},onError=function(){return $confirm.notify("error")},target=angular.element(event.currentTarget),newRole=parseInt(target.val(),10),member.role!==newRole?(member.role=newRole,$repo.save(member).then(onSuccess,onError)):void 0}}(this)),$scope.$on("$destroy",function(){return $el.off()}))},{link:link}},module.directive("tgMembershipsRowRoleSelector",["$log","$tgRepo","$tgConfirm",MembershipsRowRoleSelectorDirective]),MembershipsRowActionsDirective=function($log,$repo,$rs,$confirm){var activedTemplate,link,pendingTemplate;return activedTemplate=_.template('\n Active\n
\n\n \n '),pendingTemplate=_.template('\n Pending\n \n \n\n \n '),link=function($scope,$el,$attrs){var $ctrl,member,render;return render=function(member){var html;return html=member.user?activedTemplate():pendingTemplate(),$el.html(html)},null==$attrs.tgMembershipsRowActions?$log.error("MembershipsRowActionsDirective: the directive need a member"):($ctrl=$el.controller(),member=$scope.$eval($attrs.tgMembershipsRowActions),render(member),$el.on("click",".pending",function(event){var onError,onSuccess;return event.preventDefault(),onSuccess=function(){return $confirm.notify("success","We've sent the invitationi again to '"+$scope.member.email+"'.")},onError=function(){return $confirm.notify("error","We haven't sent the invitation.")},$rs.memberships.resendInvitation($scope.member.id).then(onSuccess,onError)}),$el.on("click",".delete",function(event){var message,title;return event.preventDefault(),title="Delete member",message=member.user?member.full_name:"the invitation to "+member.email,$confirm.askOnDelete(title,message).then(function(finish){var onError,onSuccess;return onSuccess=function(){return finish(),$ctrl.loadMembers(),$confirm.notify("success",null,"We've deleted "+message+".")},onError=function(){return finish(!1),$confirm.notify("error",null,"We have not been able to delete "+message+".")},$repo.remove(member).then(onSuccess,onError)})}),$scope.$on("$destroy",function(){return $el.off()}))},{link:link}},module.directive("tgMembershipsRowActions",["$log","$tgRepo","$tgResources","$tgConfirm",MembershipsRowActionsDirective])}.call(this),function(){var AdminNavigationDirective,module;AdminNavigationDirective=function(){var link;return link=function($scope,$el,$attrs){var section;return section=$attrs.tgAdminNavigation,$el.find(".active").removeClass("active"),$el.find("#adminmenu-"+section+" a").addClass("active"),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module=angular.module("taigaAdmin"),module.directive("tgAdminNavigation",AdminNavigationDirective)}.call(this),function(){var CsvExporterController,CsvExporterIssuesController,CsvExporterTasksController,CsvExporterUserstoriesController,ProjectDefaultValuesDirective,ProjectExportDirective,ProjectModulesDirective,ProjectProfileController,ProjectProfileDirective,bindOnce,debounce,groupBy,joinStr,mixOf,module,taiga,toString,trim,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};taiga=this.taiga,mixOf=this.taiga.mixOf,trim=this.taiga.trim,toString=this.taiga.toString,joinStr=this.taiga.joinStr,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,module=angular.module("taigaAdmin"),ProjectProfileController=function(superClass){function ProjectProfileController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,appTitle){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Project profile - "+_this.scope.sectionName+" - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),this.scope.$on("project:loaded",function(_this){return function(){return _this.appTitle.set("Project profile - "+_this.scope.sectionName+" - "+_this.scope.project.name)}}(this))}return extend(ProjectProfileController,superClass),ProjectProfileController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$appTitle"],ProjectProfileController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.i_am_owner||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.pointsList=_.sortBy(project.points,"order"),_this.scope.usStatusList=_.sortBy(project.us_statuses,"order"),_this.scope.taskStatusList=_.sortBy(project.task_statuses,"order"),_this.scope.prioritiesList=_.sortBy(project.priorities,"order"),_this.scope.severitiesList=_.sortBy(project.severities,"order"),_this.scope.issueTypesList=_.sortBy(project.issue_types,"order"),_this.scope.issueStatusList=_.sortBy(project.issue_statuses,"order"),_this.scope.$emit("project:loaded",project),project}}(this))},ProjectProfileController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this))},ProjectProfileController.prototype.openDeleteLightbox=function(){return this.rootscope.$broadcast("deletelightbox:new",this.scope.project)},ProjectProfileController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("ProjectProfileController",ProjectProfileController),ProjectProfileDirective=function($repo,$confirm,$loading,$navurls,$location){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley({onlyOneErrorElement:!0}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.save($scope.project),promise.then(function(){var newUrl;return $loading.finish(submitButton),$confirm.notify("success"),newUrl=$navurls.resolve("project-admin-project-profile-details",{project:$scope.project.slug}),$location.path(newUrl),$scope.$emit("project:loaded",$scope.project)}),promise.then(null,function(data){return $loading.finish(target),form.setErrors(data),data._error_message?$confirm.notify("error",data._error_message):void 0})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgProjectProfile",["$tgRepo","$tgConfirm","$tgLoading","$tgNavUrls","$tgLocation",ProjectProfileDirective]),ProjectDefaultValuesDirective=function($repo,$confirm,$loading){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley({onlyOneErrorElement:!0}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.save($scope.project),promise.then(function(){return $loading.finish(submitButton),$confirm.notify("success")}),promise.then(null,function(data){return $loading.finish(target),form.setErrors(data),data._error_message?$confirm.notify("error",data._error_message):void 0})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgProjectDefaultValues",["$tgRepo","$tgConfirm","$tgLoading",ProjectDefaultValuesDirective]),ProjectModulesDirective=function($repo,$confirm,$loading){var link;return link=function($scope,$el){var form,submit;return form=$el.find("form").checksley(),submit=function(){return function(){var promise,target;if(form.validate())return target=angular.element(".admin-functionalities a.button-green"),$loading.start(target),promise=$repo.save($scope.project),promise.then(function(){return $loading.finish(target),$confirm.notify("success"),$scope.$emit("project:loaded",$scope.project)}),promise.then(null,function(data){return $loading.finish(target),$confirm.notify("error",data._error_message)})}}(this),$el.on("submit","form",function(event){return event.preventDefault(),submit()}),$el.on("click",".admin-functionalities a.button-green",function(event){return event.preventDefault(),submit()}),$scope.$watch("isVideoconferenceActivated",function(isVideoconferenceActivated){return isVideoconferenceActivated?$el.find(".videoconference-attributes").removeClass("hidden"):($el.find(".videoconference-attributes").addClass("hidden"),$scope.project.videoconferences=null,$scope.project.videoconferences_salt="")}),$scope.$watch("project",function(project){return $scope.isVideoconferenceActivated=null!=project.videoconferences?!0:!1})},{link:link}},module.directive("tgProjectModules",["$tgRepo","$tgConfirm","$tgLoading",ProjectModulesDirective]),ProjectExportDirective=function($window,$rs,$confirm){var link;return link=function($scope,$el){var buttonsEl,hideButtons,hideResult,hideSpinner,resultEl,resultMessageEl,resultTitleEl,setAsyncMessage,setAsyncTitle,setLoadingMessage,setLoadingTitle,setSyncMessage,setSyncTitle,showButtons,showErrorMode,showExportResultAsyncMode,showExportResultSyncMode,showLoadingMode,showResult,showSpinner,spinnerEl;return buttonsEl=$el.find(".admin-project-export-buttons"),showButtons=function(){return buttonsEl.removeClass("hidden")},hideButtons=function(){return buttonsEl.addClass("hidden")},resultEl=$el.find(".admin-project-export-result"),showResult=function(){return resultEl.removeClass("hidden")},hideResult=function(){return resultEl.addClass("hidden")},spinnerEl=$el.find(".spin"),showSpinner=function(){return spinnerEl.removeClass("hidden")},hideSpinner=function(){return spinnerEl.addClass("hidden")},resultTitleEl=$el.find(".result-title"),setLoadingTitle=function(){return resultTitleEl.html("We are generating your dump file")},setAsyncTitle=function(){return resultTitleEl.html("We are generating your dump file")},setSyncTitle=function(){return resultTitleEl.html("Your dump file is ready!")},resultMessageEl=$el.find(".result-message "),setLoadingMessage=function(){return resultMessageEl.html("Please don't close this page.")},setAsyncMessage=function(){return resultMessageEl.html("We will send you an email when ready.")},setSyncMessage=function(url){return resultMessageEl.html("If the download doesn't start automatically click here.")},showLoadingMode=function(){return showSpinner(),setLoadingTitle(),setLoadingMessage(),hideButtons(),showResult()},showExportResultAsyncMode=function(){return hideSpinner(),setAsyncTitle(),setAsyncMessage()},showExportResultSyncMode=function(url){return hideSpinner(),setSyncTitle(),setSyncMessage(url)},showErrorMode=function(){return hideSpinner(),hideResult(),showButtons()},$el.on("click","a.button-export",debounce(2e3,function(){return function(event){var onError,onSuccess;return event.preventDefault(),onSuccess=function(result){var dumpUrl;return 202===result.status?showExportResultAsyncMode():(dumpUrl=result.data.url,showExportResultSyncMode(dumpUrl),$window.open(dumpUrl,"_blank"))},onError=function(result){var errorMsg,ref;return showErrorMode(),errorMsg="Our oompa loompas have some problems generasting your dump. Please try again. ",429===result.status?errorMsg="Sorry, our oompa loompas are very busy right now. Please try again in a few minutes. ":(null!=(ref=result.data)?ref._error_message:void 0)&&(errorMsg="Our oompa loompas have some problems generasting your dump: "+result.data._error_message),$confirm.notify("error",errorMsg)},showLoadingMode(),$rs.projects["export"]($scope.projectId).then(onSuccess,onError)}}(this)))},{link:link}},module.directive("tgProjectExport",["$window","$tgResources","$tgConfirm",ProjectExportDirective]),CsvExporterController=function(superClass){function CsvExporterController(scope,rootscope,urls,confirm,rs){this.scope=scope,this.rootscope=rootscope,this.urls=urls,this.confirm=confirm,this.rs=rs,this._generateUuid=bind(this._generateUuid,this),this.setCsvUuid=bind(this.setCsvUuid,this),this.rootscope.$on("project:loaded",this.setCsvUuid),this.scope.$watch("csvUuid",function(_this){return function(value){return _this.scope.csvUrl=value?_this.urls.resolveAbsolute(_this.type+"-csv",value):""}}(this))}return extend(CsvExporterController,superClass),CsvExporterController.$inject=["$scope","$rootScope","$tgUrls","$tgConfirm","$tgResources"],CsvExporterController.prototype.setCsvUuid=function(){return this.scope.csvUuid=this.scope.project[this.type+"_csv_uuid"]},CsvExporterController.prototype._generateUuid=function(finish){var promise;return promise=this.rs.projects["regenerate_"+this.type+"_csv_uuid"](this.scope.projectId),promise.then(function(_this){return function(data){var ref;return _this.scope.csvUuid=null!=(ref=data.data)?ref.uuid:void 0}}(this)),promise.then(null,function(_this){return function(){return _this.confirm.notify("error")}}(this)),promise["finally"](function(){return finish()}),promise},CsvExporterController.prototype.regenerateUuid=function(){var subtitle,title;return this.scope.csvUuid?(title="Change URL",subtitle="You going to change the CSV data access url. The previous url will be disabled. Are you sure?",this.confirm.ask(title,subtitle).then(this._generateUuid)):this._generateUuid(_.identity)},CsvExporterController}(taiga.Controller),CsvExporterUserstoriesController=function(superClass){function CsvExporterUserstoriesController(){return CsvExporterUserstoriesController.__super__.constructor.apply(this,arguments)}return extend(CsvExporterUserstoriesController,superClass),CsvExporterUserstoriesController.prototype.type="userstories",CsvExporterUserstoriesController}(CsvExporterController),CsvExporterTasksController=function(superClass){function CsvExporterTasksController(){return CsvExporterTasksController.__super__.constructor.apply(this,arguments)}return extend(CsvExporterTasksController,superClass),CsvExporterTasksController.prototype.type="tasks",CsvExporterTasksController}(CsvExporterController),CsvExporterIssuesController=function(superClass){function CsvExporterIssuesController(){return CsvExporterIssuesController.__super__.constructor.apply(this,arguments)}return extend(CsvExporterIssuesController,superClass),CsvExporterIssuesController.prototype.type="issues",CsvExporterIssuesController}(CsvExporterController),module.controller("CsvExporterUserstoriesController",CsvExporterUserstoriesController),module.controller("CsvExporterTasksController",CsvExporterTasksController),module.controller("CsvExporterIssuesController",CsvExporterIssuesController)}.call(this),function(){var ColorSelectionDirective,ProjectCustomAttributesController,ProjectCustomAttributesDirective,ProjectValuesController,ProjectValuesDirective,ProjectValuesSectionController,bindOnce,debounce,groupBy,joinStr,mixOf,module,taiga,toString,trim,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};taiga=this.taiga,mixOf=this.taiga.mixOf,trim=this.taiga.trim,toString=this.taiga.toString,joinStr=this.taiga.joinStr,groupBy=this.taiga.groupBy,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,module=angular.module("taigaAdmin"),ProjectValuesSectionController=function(superClass){function ProjectValuesSectionController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,appTitle){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Project values - "+_this.scope.sectionName+" - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this))}return extend(ProjectValuesSectionController,superClass),ProjectValuesSectionController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$appTitle"],ProjectValuesSectionController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.i_am_owner||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},ProjectValuesSectionController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this))},ProjectValuesSectionController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("ProjectValuesSectionController",ProjectValuesSectionController),ProjectValuesController=function(superClass){function ProjectValuesController(scope,rootscope,repo,confirm,rs){this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.moveValue=bind(this.moveValue,this),this.loadValues=bind(this.loadValues,this),this.scope.$on("admin:project-values:move",this.moveValue),this.rootscope.$on("project:loaded",this.loadValues)}return extend(ProjectValuesController,superClass),ProjectValuesController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources"],ProjectValuesController.prototype.loadValues=function(){return this.rs[this.scope.resource].listValues(this.scope.projectId,this.scope.type).then(function(_this){return function(values){return _this.scope.values=values,_this.scope.maxValueOrder=_.max(values,"order").order,values}}(this))},ProjectValuesController.prototype.moveValue=function(ctx,itemValue,itemIndex){var r,values;return values=this.scope.values,r=values.indexOf(itemValue),values.splice(r,1),values.splice(itemIndex,0,itemValue),_.each(values,function(value,index){return value.order=index}),this.repo.saveAll(values)},ProjectValuesController}(taiga.Controller),module.controller("ProjectValuesController",ProjectValuesController),ProjectValuesDirective=function($log,$repo,$confirm){var link,linkDragAndDrop,linkValue;return linkDragAndDrop=function($scope,$el){var itemEl,newParentScope,oldParentScope,tdom;return oldParentScope=null,newParentScope=null,itemEl=null,tdom=$el.find(".sortable"),tdom.sortable({handle:".row.table-main.visualization",dropOnEmpty:!0,connectWith:".project-values-body",revert:400,axis:"y"}),tdom.on("sortstop",function(event,ui){var itemIndex,itemValue;return itemEl=ui.item,itemValue=itemEl.scope().value,itemIndex=itemEl.index(),$scope.$broadcast("admin:project-values:move",itemValue,itemIndex)}),$scope.$on("$destroy",function(){return $el.off()})},linkValue=function($scope,$el,$attrs){var $ctrl,cancel,goToBottomList,initializeNewValue,saveNewValue,saveValue,valueType;return $ctrl=$el.controller(),valueType=$attrs.type,initializeNewValue=function(){return $scope.newValue={name:"",is_closed:!1,is_archived:!1}},initializeNewValue(),goToBottomList=function(){return function(focus){var table;return null==focus&&(focus=!1),table=$el.find(".table-main"),$(document.body).scrollTop(table.offset().top+table.height()),focus?$el.find(".new-value input:visible").first().focus():void 0}}(this),saveValue=function(target){var form,formEl,promise,value;return formEl=target.parents("form"),form=formEl.checksley(),form.validate()?(value=formEl.scope().value,promise=$repo.save(value),promise.then(function(){return function(){var row;return row=target.parents(".row.table-main"),row.addClass("hidden"),row.siblings(".visualization").removeClass("hidden")}}(this)),promise.then(null,function(data){return form.setErrors(data)})):void 0},saveNewValue=function(target){var form,formEl,promise;return formEl=target.parents("form"),form=formEl.checksley(),form.validate()?($scope.newValue.project=$scope.project.id,$scope.newValue.order=$scope.maxValueOrder?$scope.maxValueOrder+1:1,promise=$repo.create(valueType,$scope.newValue),promise.then(function(){return function(data){return target.addClass("hidden"),$scope.values.push(data),$scope.maxValueOrder=data.order,initializeNewValue()}}(this)),promise.then(null,function(data){return form.setErrors(data)})):void 0},cancel=function(target){var formEl,row,value;return row=target.parents(".row.table-main"),formEl=target.parents("form"),value=formEl.scope().value,$scope.$apply(function(){return row.addClass("hidden"),value.revert(),row.siblings(".visualization").removeClass("hidden")})},$el.on("click",".show-add-new",function(event){return event.preventDefault(),$el.find(".new-value").removeClass("hidden"),goToBottomList(!0)}),$el.on("click",".add-new",debounce(2e3,function(event){var target;return event.preventDefault(),target=$el.find(".new-value"),saveNewValue(target)})),$el.on("click",".delete-new",function(event){return event.preventDefault(),$el.find(".new-value").addClass("hidden"),initializeNewValue()}),$el.on("click",".edit-value",function(event){var editionRow,row,target;return event.preventDefault(),target=angular.element(event.currentTarget),row=target.parents(".row.table-main"),row.addClass("hidden"),editionRow=row.siblings(".edition"),editionRow.removeClass("hidden"),editionRow.find("input:visible").first().focus().select()}),$el.on("keyup",".edition input",function(event){var target;return 13===event.keyCode?(target=angular.element(event.currentTarget),saveValue(target)):27===event.keyCode?(target=angular.element(event.currentTarget),cancel(target)):void 0}),$el.on("keyup",".new-value input",function(event){var target;return 13===event.keyCode?(target=$el.find(".new-value"),saveNewValue(target)):27===event.keyCode?($el.find(".new-value").addClass("hidden"),initializeNewValue()):void 0}),$el.on("click",".save",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),saveValue(target)}),$el.on("click",".cancel",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),cancel(target)}),$el.on("click",".delete-value",function(event){var choices,formEl,replacement,subtitle,target,title,value;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.parents("form"),value=formEl.scope().value,choices={},_.each($scope.values,function(option){return value.id!==option.id?choices[option.id]=option.name:void 0}),title="Delete value",subtitle=value.name,replacement="All items with this value will be changed to",0===_.keys(choices).length?$confirm.error("You can't delete all values."):$confirm.askChoice(title,subtitle,choices,replacement).then(function(response){var onError,onSucces;return onSucces=function(){return $ctrl.loadValues()["finally"](function(){return response.finish()})},onError=function(){return $confirm.notify("error")},$repo.remove(value,{moveTo:response.selected}).then(onSucces,onError)})})},link=function($scope,$el,$attrs){return linkDragAndDrop($scope,$el,$attrs),linkValue($scope,$el,$attrs),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgProjectValues",["$log","$tgRepo","$tgConfirm","$tgLocation","animationFrame",ProjectValuesDirective]),ColorSelectionDirective=function(){var link;return link=function($scope,$el,$attrs,$model){var $ctrl;return $ctrl=$el.controller(),$scope.$watch($attrs.ngModel,function(element){return $scope.color=element.color}),$el.on("click",".current-color",function(event){var body,target;return event.preventDefault(),event.stopPropagation(),target=angular.element(event.currentTarget),$el.find(".select-color").hide(),target.siblings(".select-color").show(),body=angular.element("body"),body.on("click",function(){return function(event){return 0===angular.element(event.target).parent(".select-color").length?($el.find(".select-color").hide(),body.unbind("click")):void 0
}}(this))}),$el.on("click",".select-color .color",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),$scope.$apply(function(){return $model.$modelValue.color=target.data("color")}),$el.find(".select-color").hide()}),$el.on("click",".select-color .selected-color",function(event){return event.preventDefault(),$scope.$apply(function(){return $model.$modelValue.color=$scope.color}),$el.find(".select-color").hide()}),$scope.$on("$destroy",function(){return $el.off()})},{link:link,require:"ngModel"}},module.directive("tgColorSelection",ColorSelectionDirective),ProjectCustomAttributesController=function(superClass){function ProjectCustomAttributesController(scope,rootscope,repo,rs,params,q,location,navUrls,appTitle){this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,this.moveCustomAttributes=bind(this.moveCustomAttributes,this),this.deleteCustomAttribute=bind(this.deleteCustomAttribute,this),this.saveCustomAttribute=bind(this.saveCustomAttribute,this),this.createCustomAttribute=bind(this.createCustomAttribute,this),this.loadCustomAttributes=bind(this.loadCustomAttributes,this),this.scope.project={},this.rootscope.$on("project:loaded",function(_this){return function(){return _this.loadCustomAttributes(),_this.appTitle.set("Project Custom Attributes - "+_this.scope.sectionName+" - "+_this.scope.project.name)}}(this))}return extend(ProjectCustomAttributesController,superClass),ProjectCustomAttributesController.$inject=["$scope","$rootScope","$tgRepo","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$appTitle"],ProjectCustomAttributesController.prototype.loadCustomAttributes=function(){return this.rs.customAttributes[this.scope.type].list(this.scope.projectId).then(function(_this){return function(customAttributes){return _this.scope.customAttributes=customAttributes,_this.scope.maxOrder=_.max(customAttributes,"order").order,customAttributes}}(this))},ProjectCustomAttributesController.prototype.createCustomAttribute=function(attrValues){return this.repo.create("custom-attributes/"+this.scope.type,attrValues)},ProjectCustomAttributesController.prototype.saveCustomAttribute=function(attrModel){return this.repo.save(attrModel)},ProjectCustomAttributesController.prototype.deleteCustomAttribute=function(attrModel){return this.repo.remove(attrModel)},ProjectCustomAttributesController.prototype.moveCustomAttributes=function(attrModel,newIndex){var customAttributes,r;return customAttributes=this.scope.customAttributes,r=customAttributes.indexOf(attrModel),customAttributes.splice(r,1),customAttributes.splice(newIndex,0,attrModel),_.each(customAttributes,function(val,idx){return val.order=idx}),this.repo.saveAll(customAttributes)},ProjectCustomAttributesController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("ProjectCustomAttributesController",ProjectCustomAttributesController),ProjectCustomAttributesDirective=function($log,$confirm){var link;return link=function($scope,$el){var $ctrl,cancelCreate,cancelUpdate,create,deleteCustomAttribute,hideAddButton,hideCancelButton,hideCreateForm,hideEditForm,resetNewAttr,revertChangesInCustomAttribute,showAddButton,showCancelButton,showCreateForm,showEditForm,sortableEl,update;return $ctrl=$el.controller(),$scope.$on("$destroy",function(){return $el.off()}),sortableEl=$el.find(".js-sortable"),sortableEl.sortable({handle:".js-view-custom-field",dropOnEmpty:!0,revert:400,axis:"y"}),sortableEl.on("sortstop",function(event,ui){var itemAttr,itemEl,itemIndex;return itemEl=ui.item,itemAttr=itemEl.scope().attr,itemIndex=itemEl.index(),$ctrl.moveCustomAttributes(itemAttr,itemIndex)}),showCreateForm=function(){return $el.find(".js-new-custom-field").removeClass("hidden"),$el.find(".js-new-custom-field input:visible").first().focus()},hideCreateForm=function(){return $el.find(".js-new-custom-field").addClass("hidden")},showAddButton=function(){return $el.find(".js-add-custom-field-button").removeClass("hidden")},hideAddButton=function(){return $el.find(".js-add-custom-field-button").addClass("hidden")},showCancelButton=function(){return $el.find(".js-cancel-new-custom-field-button").removeClass("hidden")},hideCancelButton=function(){return $el.find(".js-cancel-new-custom-field-button").addClass("hidden")},resetNewAttr=function(){return $scope.newAttr={}},create=function(formEl){var attr,form,onError,onSucces;return form=formEl.checksley(),form.validate()?(onSucces=function(){return function(){return $ctrl.loadCustomAttributes(),hideCreateForm(),resetNewAttr(),$confirm.notify("success")}}(this),onError=function(){return function(data){return form.setErrors(data)}}(this),attr=$scope.newAttr,attr.project=$scope.projectId,attr.order=$scope.maxOrder?$scope.maxOrder+1:1,$ctrl.createCustomAttribute(attr).then(onSucces,onError)):void 0},cancelCreate=function(){return hideCreateForm(),resetNewAttr()},$scope.$watch("customAttributes",function(customAttributes){return customAttributes?0===customAttributes.length?(hideCancelButton(),hideAddButton(),showCreateForm()):(hideCreateForm(),showAddButton(),showCancelButton()):void 0}),$el.on("click",".js-add-custom-field-button",function(event){return event.preventDefault(),showCreateForm()}),$el.on("click",".js-create-custom-field-button",debounce(2e3,function(event){var formEl,target;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.closest("form"),create(formEl)})),$el.on("click",".js-cancel-new-custom-field-button",function(event){return event.preventDefault(),cancelCreate()}),$el.on("keyup",".js-new-custom-field input",function(event){var formEl,target;return 13===event.keyCode?(target=angular.element(event.currentTarget),formEl=target.closest("form"),create(formEl)):27===event.keyCode?cancelCreate():void 0}),showEditForm=function(formEl){return formEl.find(".js-view-custom-field").addClass("hidden"),formEl.find(".js-edit-custom-field").removeClass("hidden"),formEl.find(".js-edit-custom-field input:visible").first().focus().select()},hideEditForm=function(formEl){return formEl.find(".js-edit-custom-field").addClass("hidden"),formEl.find(".js-view-custom-field").removeClass("hidden")},revertChangesInCustomAttribute=function(formEl){return $scope.$apply(function(){return formEl.scope().attr.revert()})},update=function(formEl){var attr,form,onError,onSucces;return form=formEl.checksley(),form.validate()?(onSucces=function(){return function(){return $ctrl.loadCustomAttributes(),hideEditForm(formEl),$confirm.notify("success")}}(this),onError=function(){return function(data){return form.setErrors(data)}}(this),attr=formEl.scope().attr,$ctrl.saveCustomAttribute(attr).then(onSucces,onError)):void 0},cancelUpdate=function(formEl){return hideEditForm(formEl),revertChangesInCustomAttribute(formEl)},$el.on("click",".js-edit-custom-field-button",function(event){var formEl,target;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.closest("form"),showEditForm(formEl)}),$el.on("click",".js-update-custom-field-button",debounce(2e3,function(event){var formEl,target;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.closest("form"),update(formEl)})),$el.on("click",".js-cancel-edit-custom-field-button",function(event){var formEl,target;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.closest("form"),cancelUpdate(formEl)}),$el.on("keyup",".js-edit-custom-field input",function(event){var formEl,target;return 13===event.keyCode?(target=angular.element(event.currentTarget),formEl=target.closest("form"),update(formEl)):27===event.keyCode?(target=angular.element(event.currentTarget),formEl=target.closest("form"),cancelUpdate(formEl)):void 0}),deleteCustomAttribute=function(formEl){var attr,message,subtitle,title;return attr=formEl.scope().attr,title="Delete custom attribute",subtitle="Remeber that all values in this custom field will be deleted. Are you sure you want to continue?",message=attr.name,$confirm.ask(title,subtitle,message).then(function(finish){var onError,onSucces;return onSucces=function(){return $ctrl.loadCustomAttributes()["finally"](function(){return finish()})},onError=function(){return finish(!1),$confirm.notify("error",null,"We have not been able to delete '"+message+"'.")},$ctrl.deleteCustomAttribute(attr).then(onSucces,onError)})},$el.on("click",".js-delete-custom-field-button",debounce(2e3,function(event){var formEl,target;return event.preventDefault(),target=angular.element(event.currentTarget),formEl=target.closest("form"),deleteCustomAttribute(formEl)}))},{link:link}},module.directive("tgProjectCustomAttributes",["$log","$tgConfirm","animationFrame",ProjectCustomAttributesDirective])}.call(this),function(){var EditRoleDirective,NewRoleDirective,RolePermissionsDirective,RolesController,RolesDirective,bindMethods,bindOnce,debounce,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;l>i;i++)if(i in this&&this[i]===item)return i;return-1};taiga=this.taiga,mixOf=this.taiga.mixOf,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,bindMethods=this.taiga.bindMethods,module=angular.module("taigaAdmin"),RolesController=function(superClass){function RolesController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,appTitle){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Permissions",this.scope.project={},this.scope.anyComputableRole=!0,promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Roles - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this))}return extend(RolesController,superClass),RolesController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$appTitle"],RolesController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.i_am_owner||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.anyComputableRole=_.some(_.map(project.roles,function(point){return point.computable})),project}}(this))},RolesController.prototype.loadExternalUserRole=function(roles){var public_permission;return roles=roles.map(function(role){return role.external_user=!1,role}),public_permission={name:"External User",permissions:this.scope.project.public_permissions,external_user:!0},roles.push(public_permission),roles},RolesController.prototype.loadRoles=function(){return this.rs.roles.list(this.scope.projectId).then(this.loadExternalUserRole).then(function(_this){return function(roles){return _this.scope.roles=roles,_this.scope.role=_this.scope.roles[0],roles}}(this))},RolesController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadUsersAndRoles()}}(this)).then(function(_this){return function(){return _this.loadRoles()}}(this))},RolesController.prototype.setRole=function(role){return this.scope.role=role,this.scope.$broadcast("role:changed",this.scope.role)},RolesController.prototype["delete"]=function(){var choices,i,len,ref,replacement,role,subtitle,title,warning;for(title="Delete Role",subtitle=this.scope.role.name,replacement="All the users with this role will be moved to",warning="Be careful, all role estimations will be removed ",choices={},ref=this.scope.roles,i=0,len=ref.length;len>i;i++)role=ref[i],role.id!==this.scope.role.id&&(choices[role.id]=role.name);return 0===_.keys(choices).length?this.confirm.error("You can't delete all values."):this.confirm.askChoice(title,subtitle,choices,replacement,warning).then(function(_this){return function(response){var promise;return promise=_this.repo.remove(_this.scope.role,{moveTo:response.selected}),promise.then(function(){return _this.loadProject(),_this.loadRoles()["finally"](function(){return response.finish()})}),promise.then(null,function(){return _this.confirm.notify("error")})}}(this))},RolesController.prototype.setComputable=debounce(2e3,function(){var onError,onSuccess;return onSuccess=function(_this){return function(){return _this.confirm.notify("success"),_this.loadProject()}}(this),onError=function(_this){return function(){return _this.confirm.notify("error"),_this.scope.role.revert()}}(this),this.repo.save(this.scope.role).then(onSuccess,onError)}),RolesController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("RolesController",RolesController),EditRoleDirective=function($repo,$confirm){var link;return link=function($scope,$el){var submit,toggleView;return toggleView=function(){return $el.find(".total").toggle(),$el.find(".edit-role").toggle()},submit=function(){var promise;return $scope.role.name=$el.find("input").val(),promise=$repo.save($scope.role),promise.then(function(){return $confirm.notify("success")}),promise.then(null,function(){return $confirm.notify("error")}),toggleView()},$el.on("click","a.icon-edit",function(){return toggleView(),$el.find("input").focus(),$el.find("input").val($scope.role.name)}),$el.on("click","a.save",submit),$el.on("keyup","input",function(event){return 13===event.keyCode?submit():27===event.keyCode?toggleView():void 0}),$scope.$on("role:changed",function(){return $el.find(".edit-role").is(":visible")?toggleView():void 0}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgEditRole",["$tgRepo","$tgConfirm",EditRoleDirective]),RolesDirective=function(){var link;return link=function($scope,$el){var $ctrl;return $ctrl=$el.controller(),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgRoles",RolesDirective),NewRoleDirective=function($tgrepo,$confirm){var DEFAULT_PERMISSIONS,link;return DEFAULT_PERMISSIONS=["view_project","view_milestones","view_us","view_tasks","view_issues"],link=function($scope,$el){var $ctrl;return $ctrl=$el.controller(),$scope.$on("$destroy",function(){return $el.off()}),$el.on("click","a.add-button",function(event){return event.preventDefault(),$el.find(".new").removeClass("hidden"),$el.find(".new").focus(),$el.find(".add-button").hide()}),$el.on("keyup",".new",function(event){var newRole,onError,onSuccess,target;return event.preventDefault(),13===event.keyCode?(target=angular.element(event.currentTarget),newRole={project:$scope.projectId,name:target.val(),permissions:DEFAULT_PERMISSIONS,order:_.max($scope.roles,function(r){return r.order}).order+1,computable:!1},$el.find(".new").addClass("hidden"),$el.find(".new").val(""),onSuccess=function(role){return $scope.roles.push(role),$ctrl.setRole(role),$el.find(".add-button").show(),$ctrl.loadProject()},onError=function(){return $confirm.notify("error")},$tgrepo.create("roles",newRole).then(onSuccess,onError)):27===event.keyCode?(target=angular.element(event.currentTarget),$el.find(".new").addClass("hidden"),$el.find(".new").val(""),$el.find(".add-button").show()):void 0})},{link:link}},module.directive("tgNewRole",["$tgRepo","$tgConfirm",NewRoleDirective]),RolePermissionsDirective=function($rootscope,$repo,$confirm){var baseTemplate,categoryTemplate,link,resumeTemplate;return resumeTemplate=_.template('<%- category.name %>
\n\n
<%- category.activePermissions %>/<%- category.permissions.length %>
\n <% _.each(category.permissions, function(permission) { %>\n
\n <% }) %>\n
\n
'),categoryTemplate=_.template('\n
\n
\n
\n
\n <% _.each(category.permissions, function(permission) { %>\n
\n
<%- permission.description %> \n
\n
disabled="disabled"<% } %> <% if(permission.active) { %>checked="checked"<% } %>/>\n
\n
Yes \n
No \n
\n
\n <% }) %>\n
\n
\n
'),baseTemplate=_.template('
'),link=function($scope,$el,$attrs){var $ctrl,generateCategoriesFromRole,renderCategory,renderPermissions,renderResume;return $ctrl=$el.controller(),generateCategoriesFromRole=function(role){var categories,isPermissionEditable,issuePermissions,milestonePermissions,setActivePermissions,setActivePermissionsPerCategory,taskPermissions,userStoryPermissions,wikiPermissions;return setActivePermissions=function(permissions){return _.map(permissions,function(x){var ref;return _.extend({},x,{active:(ref=x.key,indexOf.call(role.permissions,ref)>=0)})})},isPermissionEditable=function(permission,role,project){return role.external_user&&!project.is_private&&0===permission.key.indexOf("view_")?!1:!0},setActivePermissionsPerCategory=function(category){return _.map(category,function(cat){return cat.permissions=cat.permissions.map(function(permission){return permission.editable=isPermissionEditable(permission,role,$scope.project),permission}),_.extend({},cat,{activePermissions:_.filter(cat.permissions,"active").length})})},categories=[],milestonePermissions=[{key:"view_milestones",description:"View sprints"},{key:"add_milestone",description:"Add sprint"},{key:"modify_milestone",description:"Modify sprint"},{key:"delete_milestone",description:"Delete sprint"}],categories.push({name:"Sprints",permissions:setActivePermissions(milestonePermissions)}),userStoryPermissions=[{key:"view_us",description:"View user story"},{key:"add_us",description:"Add user story"},{key:"modify_us",description:"Modify user story"},{key:"delete_us",description:"Delete user story"}],categories.push({name:"User Stories",permissions:setActivePermissions(userStoryPermissions)}),taskPermissions=[{key:"view_tasks",description:"View tasks"},{key:"add_task",description:"Add task"},{key:"modify_task",description:"Modify task"},{key:"delete_task",description:"Delete task"}],categories.push({name:"Tasks",permissions:setActivePermissions(taskPermissions)}),issuePermissions=[{key:"view_issues",description:"View issues"},{key:"add_issue",description:"Add issue"},{key:"modify_issue",description:"Modify issue"},{key:"delete_issue",description:"Delete issue"}],categories.push({name:"Issues",permissions:setActivePermissions(issuePermissions)}),wikiPermissions=[{key:"view_wiki_pages",description:"View wiki pages"},{key:"add_wiki_page",description:"Add wiki page"},{key:"modify_wiki_page",description:"Modify wiki page"},{key:"delete_wiki_page",description:"Delete wiki page"},{key:"view_wiki_links",description:"View wiki links"},{key:"add_wiki_link",description:"Add wiki link"},{key:"delete_wiki_link",description:"Delete wiki link"}],categories.push({name:"Wiki",permissions:setActivePermissions(wikiPermissions)}),setActivePermissionsPerCategory(categories)},renderResume=function(element,category){return element.find(".resume").html(resumeTemplate({category:category}))},renderCategory=function(category,index){var html;return html=categoryTemplate({category:category,index:index}),html=angular.element(html),renderResume(html,category),html},renderPermissions=function(){var html;return $el.off(),html=baseTemplate(),_.each(generateCategoriesFromRole($scope.role),function(category,index){return html=angular.element(html).append(renderCategory(category,index))}),$el.html(html),$el.on("click",".resume",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),target.next().toggleClass("open")}),$el.on("change",".category-item input",function(event){var getActivePermissions,onError,onSuccess,target;return getActivePermissions=function(){var activePermissions;return activePermissions=_.filter($el.find(".category-item input"),function(t){return angular.element(t).is(":checked")}),activePermissions=_.sortBy(_.map(activePermissions,function(t){var permission;return permission=angular.element(t).parents(".category-item").data("id")})),activePermissions.push("view_project"),activePermissions},target=angular.element(event.currentTarget),$scope.role.permissions=getActivePermissions(),onSuccess=function(){var categories,categoryId;return categories=generateCategoriesFromRole($scope.role),categoryId=target.parents(".category-config").data("id"),renderResume(target.parents(".category-config"),categories[categoryId]),$rootscope.$broadcast("projects:reload"),$confirm.notify("success"),$ctrl.loadProject()},onError=function(){return $confirm.notify("error"),target.prop("checked",!target.prop("checked")),$scope.role.permissions=getActivePermissions()},$scope.role.external_user?($scope.project.public_permissions=$scope.role.permissions,$scope.project.anon_permissions=$scope.role.permissions.filter(function(permission){return 0===permission.indexOf("view_")}),$repo.save($scope.project).then(onSuccess,onError)):$repo.save($scope.role).then(onSuccess,onError)})},$scope.$on("$destroy",function(){return $el.off()}),$scope.$on("role:changed",function(){return renderPermissions()}),bindOnce($scope,$attrs.ngModel,renderPermissions)},{link:link}},module.directive("tgRolePermissions",["$rootScope","$tgRepo","$tgConfirm",RolePermissionsDirective])}.call(this),function(){var BitbucketController,BitbucketWebhooksDirective,GithubController,GithubWebhooksDirective,GitlabController,GitlabWebhooksDirective,NewWebhookDirective,SelectInputText,ValidOriginIpsDirective,WebhookDirective,WebhooksController,bindMethods,debounce,mixOf,module,taiga,timeout,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,bindMethods=this.taiga.bindMethods,debounce=this.taiga.debounce,timeout=this.taiga.timeout,module=angular.module("taigaAdmin"),WebhooksController=function(superClass){function WebhooksController(scope,repo,rs,params,location,navUrls,appTitle){var promise;this.scope=scope,this.repo=repo,this.rs=rs,this.params=params,this.location=location,this.navUrls=navUrls,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Webhooks",this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Webhooks - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),this.scope.$on("webhooks:reload",this.loadWebhooks)}return extend(WebhooksController,superClass),WebhooksController.$inject=["$scope","$tgRepo","$tgResources","$routeParams","$tgLocation","$tgNavUrls","$appTitle"],WebhooksController.prototype.loadWebhooks=function(){return this.rs.webhooks.list(this.scope.projectId).then(function(_this){return function(webhooks){return _this.scope.webhooks=webhooks}}(this))},WebhooksController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return project.i_am_owner||_this.location.path(_this.navUrls.resolve("permission-denied")),_this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},WebhooksController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadWebhooks()}}(this))},WebhooksController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("WebhooksController",WebhooksController),WebhookDirective=function($rs,$repo,$confirm){var link;return link=function($scope,$el,$attrs){var cancel,openHistory,save,showEditMode,showVisualizationMode,updateLogs,updateShowHideHistoryText,webhook;return webhook=$scope.$eval($attrs.tgWebhook),updateLogs=function(){return $rs.webhooklogs.list(webhook.id).then(function(){return function(webhooklogs){var i,len,log,ref;for(i=0,len=webhooklogs.length;len>i;i++)log=webhooklogs[i],log.validStatus=200<=(ref=log.status)&&300>ref,log.prettySentHeaders=_.map(_.pairs(log.request_headers),function(arg){var header,value;return header=arg[0],value=arg[1],header+": "+value}).join("\n"),log.prettySentData=JSON.stringify(log.request_data),log.prettyDate=moment(log.created).format("DD MMM YYYY [at] hh:mm:ss");return webhook.logs_counter=webhooklogs.length,webhook.logs=webhooklogs,updateShowHideHistoryText()}}(this))},updateShowHideHistoryText=function(){var historyElement,textElement;return textElement=$el.find(".toggle-history"),historyElement=textElement.parents(".single-webhook-wrapper").find(".webhooks-history"),textElement.text(historyElement.hasClass("open")?"(Hide history)":"(Show history)")},showVisualizationMode=function(){return $el.find(".edition-mode").addClass("hidden"),$el.find(".visualization-mode").removeClass("hidden")},showEditMode=function(){return $el.find(".visualization-mode").addClass("hidden"),$el.find(".edition-mode").removeClass("hidden")},openHistory=function(){return $el.find(".webhooks-history").addClass("open")},cancel=function(){return showVisualizationMode(),$scope.$apply(function(){return webhook.revert()})},save=debounce(2e3,function(target){var form,promise;return form=target.parents("form").checksley(),form.validate()?(promise=$repo.save(webhook),promise.then(function(){return function(){return showVisualizationMode()}}(this)),promise.then(null,function(data){return $confirm.notify("error"),form.setErrors(data)})):void 0}),$el.on("click",".test-webhook",function(){return openHistory(),$rs.webhooks.test(webhook.id).then(function(){return function(){return updateLogs()}}(this))}),$el.on("click",".edit-webhook",function(){return showEditMode()}),$el.on("click",".cancel-existing",function(){return cancel()}),$el.on("click",".edit-existing",function(event){var target;return event.preventDefault(),target=angular.element(event.currentTarget),save(target)}),$el.on("keyup",".edition-mode input",function(event){var target;return 13===event.keyCode?(target=angular.element(event.currentTarget),save(target)):27===event.keyCode?(target=angular.element(event.currentTarget),cancel(target)):void 0}),$el.on("click",".delete-webhook",function(){var message,title;return title="Delete webhook",message="Webhook '"+webhook.name+"'",$confirm.askOnDelete(title,message).then(function(){return function(finish){var onError,onSucces;return onSucces=function(){return finish(),$scope.$emit("webhooks:reload")},onError=function(){return finish(!1),$confirm.notify("error")},$repo.remove(webhook).then(onSucces,onError)}}(this))}),$el.on("click",".toggle-history",function(event){var target;return target=angular.element(event.currentTarget),null==webhook.logs||0===webhook.logs.length?updateLogs().then(function(){return timeout(0,function(){return $el.find(".webhooks-history").toggleClass("open"),updateShowHideHistoryText()})}):($el.find(".webhooks-history").toggleClass("open"),$scope.$apply(function(){return updateShowHideHistoryText()}))}),$el.on("click",".history-single",function(event){var target;return target=angular.element(event.currentTarget),target.toggleClass("history-single-open"),target.siblings(".history-single-response").toggleClass("open")}),$el.on("click",".resend-request",function(event){var log,target;return target=angular.element(event.currentTarget),log=target.data("log"),$rs.webhooklogs.resend(log).then(function(){return function(){return updateLogs()}}(this))})},{link:link}},module.directive("tgWebhook",["$tgResources","$tgRepo","$tgConfirm","$tgLoading",WebhookDirective]),NewWebhookDirective=function($rs,$repo,$confirm){var link;return link=function($scope,$el,$attrs){var addWebhookDOMNode,formDOMNode,initializeNewValue,save,webhook;return webhook=$scope.$eval($attrs.tgWebhook),formDOMNode=$el.find(".new-webhook-form"),addWebhookDOMNode=$el.find(".add-webhook"),initializeNewValue=function(){return $scope.newValue={name:"",url:"",key:""}},initializeNewValue(),$scope.$watch("webhooks",function(webhooks){return null!=webhooks?0===webhooks.length?(formDOMNode.removeClass("hidden"),addWebhookDOMNode.addClass("hidden"),formDOMNode.find("input")[0].focus()):(formDOMNode.addClass("hidden"),addWebhookDOMNode.removeClass("hidden")):void 0}),save=debounce(2e3,function(){var form,promise;return form=formDOMNode.checksley(),form.validate()?($scope.newValue.project=$scope.project.id,promise=$repo.create("webhooks",$scope.newValue),promise.then(function(){return function(){return $scope.$emit("webhooks:reload"),initializeNewValue()}}(this)),promise.then(null,function(data){return $confirm.notify("error"),form.setErrors(data)})):void 0}),formDOMNode.on("click",".add-new",function(event){return event.preventDefault(),save()}),formDOMNode.on("keyup","input",function(event){return 13===event.keyCode?save():void 0}),formDOMNode.on("click",".cancel-new",function(){return $scope.$apply(function(){return initializeNewValue()})}),addWebhookDOMNode.on("click",function(){return formDOMNode.removeClass("hidden"),formDOMNode.find("input")[0].focus()})},{link:link}},module.directive("tgNewWebhook",["$tgResources","$tgRepo","$tgConfirm","$tgLoading",NewWebhookDirective]),GithubController=function(superClass){function GithubController(scope,repo,rs,params,appTitle){var promise;this.scope=scope,this.repo=repo,this.rs=rs,this.params=params,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Github",this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Github - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this))}return extend(GithubController,superClass),GithubController.$inject=["$scope","$tgRepo","$tgResources","$routeParams","$appTitle"],GithubController.prototype.loadModules=function(){return this.rs.modules.list(this.scope.projectId,"github").then(function(_this){return function(github){return _this.scope.github=github}}(this))},GithubController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},GithubController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()
}}(this)).then(function(_this){return function(){return _this.loadModules()}}(this))},GithubController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("GithubController",GithubController),GitlabController=function(superClass){function GitlabController(scope,repo,rs,params,appTitle){var promise;this.scope=scope,this.repo=repo,this.rs=rs,this.params=params,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Gitlab",this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Gitlab - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),this.scope.$on("project:modules:reload",function(_this){return function(){return _this.loadModules()}}(this))}return extend(GitlabController,superClass),GitlabController.$inject=["$scope","$tgRepo","$tgResources","$routeParams","$appTitle"],GitlabController.prototype.loadModules=function(){return this.rs.modules.list(this.scope.projectId,"gitlab").then(function(_this){return function(gitlab){return _this.scope.gitlab=gitlab}}(this))},GitlabController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},GitlabController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadModules()}}(this))},GitlabController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("GitlabController",GitlabController),BitbucketController=function(superClass){function BitbucketController(scope,repo,rs,params,appTitle){var promise;this.scope=scope,this.repo=repo,this.rs=rs,this.params=params,this.appTitle=appTitle,bindMethods(this),this.scope.sectionName="Bitbucket",this.scope.project={},promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set("Bitbucket - "+_this.scope.project.name)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),this.scope.$on("project:modules:reload",function(_this){return function(){return _this.loadModules()}}(this))}return extend(BitbucketController,superClass),BitbucketController.$inject=["$scope","$tgRepo","$tgResources","$routeParams","$appTitle"],BitbucketController.prototype.loadModules=function(){return this.rs.modules.list(this.scope.projectId,"bitbucket").then(function(_this){return function(bitbucket){return _this.scope.bitbucket=bitbucket}}(this))},BitbucketController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},BitbucketController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadModules()}}(this))},BitbucketController}(mixOf(taiga.Controller,taiga.PageMixin,taiga.FiltersMixin)),module.controller("BitbucketController",BitbucketController),SelectInputText=function(){var link;return link=function($scope,$el){return $el.on("click",".select-input-content",function(){return $el.find("input").select(),$el.find(".help-copy").addClass("visible")})},{link:link}},module.directive("tgSelectInputText",SelectInputText),GithubWebhooksDirective=function($repo,$confirm,$loading){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley({onlyOneErrorElement:!0}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.saveAttribute($scope.github,"github"),promise.then(function(){return $loading.finish(submitButton),$confirm.notify("success")}),promise.then(null,function(data){return $loading.finish(submitButton),form.setErrors(data),data._error_message?$confirm.notify("error",data._error_message):void 0})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgGithubWebhooks",["$tgRepo","$tgConfirm","$tgLoading",GithubWebhooksDirective]),GitlabWebhooksDirective=function($repo,$confirm,$loading){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley({onlyOneErrorElement:!0}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.saveAttribute($scope.gitlab,"gitlab"),promise.then(function(){return $loading.finish(submitButton),$confirm.notify("success"),$scope.$emit("project:modules:reload")}),promise.then(null,function(data){return $loading.finish(submitButton),form.setErrors(data),data._error_message?$confirm.notify("error",data._error_message):void 0})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgGitlabWebhooks",["$tgRepo","$tgConfirm","$tgLoading",GitlabWebhooksDirective]),BitbucketWebhooksDirective=function($repo,$confirm,$loading){var link;return link=function($scope,$el){var form,submit,submitButton;return form=$el.find("form").checksley({onlyOneErrorElement:!0}),submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.saveAttribute($scope.bitbucket,"bitbucket"),promise.then(function(){return $loading.finish(submitButton),$confirm.notify("success"),$scope.$emit("project:modules:reload")}),promise.then(null,function(data){return $loading.finish(submitButton),form.setErrors(data),data._error_message?$confirm.notify("error",data._error_message):void 0})):void 0}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit)},{link:link}},module.directive("tgBitbucketWebhooks",["$tgRepo","$tgConfirm","$tgLoading",BitbucketWebhooksDirective]),ValidOriginIpsDirective=function(){var link;return link=function($scope,$el,$attrs,$ngModel){return $ngModel.$parsers.push(function(value){return value=$.trim(value),""===value?[]:value.split(",")})},{link:link,restrict:"EA",require:"ngModel"}},module.directive("tgValidOriginIps",ValidOriginIpsDirective)}.call(this),function(){var CreateProject,DeleteProjectDirective,bindOnce,debounce,module,taiga,timeout;taiga=this.taiga,bindOnce=this.taiga.bindOnce,timeout=this.taiga.timeout,debounce=this.taiga.debounce,module=angular.module("taigaProject"),CreateProject=function($rootscope,$repo,$confirm,$location,$navurls,$rs,$projectUrl,$loading,lightboxService,$cacheFactory){var link;return link=function($scope,$el){var form,onErrorSubmit,onSuccessSubmit,submit,submitButton;return $scope.data={},$scope.templates=[],form=$el.find("form").checksley({onlyOneErrorElement:!0}),onSuccessSubmit=function(response){return $cacheFactory.get("$http").removeAll(),$loading.finish(submitButton),$rootscope.$broadcast("projects:reload"),$confirm.notify("success","Success"),$location.url($projectUrl.get(response)),lightboxService.close($el)},onErrorSubmit=function(response){var error_field,error_step,i,len,ref,selectors;for($loading.finish(submitButton),form.setErrors(response),selectors=[],ref=_.keys(response),i=0,len=ref.length;len>i;i++)error_field=ref[i],selectors.push("[name="+error_field+"]");return $el.find(".active").removeClass("active"),error_step=$el.find(selectors.join(",")).first().parents(".wizard-step"),error_step.addClass("active"),$el.find(".progress-bar").removeClass().addClass("progress-bar").addClass(error_step.data("step"))},submit=function(){return function(event){var promise;return event.preventDefault(),form.validate()?($loading.start(submitButton),promise=$repo.create("projects",$scope.data),promise.then(onSuccessSubmit,onErrorSubmit)):void 0}}(this),$scope.$on("projects:create",function(){return $scope.data={total_story_points:100,total_milestones:5},$scope.templates.length?$scope.data.creation_template=_.head(_.filter($scope.templates,function(x){return"scrum"===x.slug})).id:$rs.projects.templates().then(function(){return function(result){return $scope.templates=result,$scope.data.creation_template=_.head(_.filter($scope.templates,function(x){return"scrum"===x.slug})).id}}(this)),$el.find(".active").removeClass("active"),$el.find(".create-step1").addClass("active"),lightboxService.open($el),timeout(600,function(){return $el.find(".progress-bar").addClass("step1")})}),$el.on("click",".button-next",function(event){var current,field,i,len,next,ref,step,valid;for(event.preventDefault(),current=$el.find(".active"),valid=!0,ref=form.fields,i=0,len=ref.length;len>i;i++)field=ref[i],current.find("[name="+field.element.attr("name")+"]").length&&(valid=field.validate()!==!1&&valid);return valid?(next=current.next(),current.toggleClass("active"),next.toggleClass("active"),step=next.data("step"),$el.find(".progress-bar").removeClass().addClass("progress-bar").addClass(step)):void 0}),$el.on("click",".button-prev",function(event){var current,prev,step;return event.preventDefault(),current=$el.find(".active"),prev=current.prev(),current.toggleClass("active"),prev.toggleClass("active"),step=prev.data("step"),$el.find(".progress-bar").removeClass().addClass("progress-bar").addClass(step)}),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit),$el.on("click",".close",function(event){return event.preventDefault(),lightboxService.close($el)})},{link:link}},module.directive("tgLbCreateProject",["$rootScope","$tgRepo","$tgConfirm","$location","$tgNavUrls","$tgResources","$projectUrl","$tgLoading","lightboxService","$cacheFactory",CreateProject]),DeleteProjectDirective=function($repo,$rootscope,$auth,$location,$navUrls,$confirm,lightboxService,tgLoader){var link;return link=function($scope,$el){var projectToDelete,submit;return projectToDelete=null,$scope.$on("deletelightbox:new",function(ctx,project){return lightboxService.open($el),projectToDelete=project}),$scope.$on("$destroy",function(){return $el.off()}),submit=function(){var promise;return tgLoader.start(),lightboxService.close($el),promise=$repo.remove(projectToDelete),promise.then(function(){return tgLoader.pageLoaded(),$rootscope.$broadcast("projects:reload"),$location.path($navUrls.resolve("home")),$confirm.notify("success")}),promise.then(null,function(){return $confirm.notify("error"),lightboxService.close($el)})},$el.on("click",".button-red",function(event){return event.preventDefault(),lightboxService.close($el)}),$el.on("click",".button-green",function(event){return event.preventDefault(),submit()})},{link:link}},module.directive("tgLbDeleteProject",["$tgRepo","$rootScope","$tgAuth","$tgLocation","$tgNavUrls","$tgConfirm","lightboxService","tgLoader",DeleteProjectDirective])}.call(this),function(){var ProjectController,ProjectsController,ProjectsListDirective,ProjectsPaginationDirective,bindOnce,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,module=angular.module("taigaProject"),bindOnce=this.taiga.bindOnce,ProjectsController=function(superClass){function ProjectsController(scope,q,rs,rootscope,navUrls,auth,location,appTitle,projectUrl,tgLoader){var promise;this.scope=scope,this.q=q,this.rs=rs,this.rootscope=rootscope,this.navUrls=navUrls,this.auth=auth,this.location=location,this.appTitle=appTitle,this.projectUrl=projectUrl,this.appTitle.set("Projects"),this.auth.isAuthenticated()||this.location.path(this.navUrls.resolve("login")),this.user=this.auth.getUser(),this.projects=[],promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.scope.$emit("projects:loaded",_this.projects)}}(this)),promise.then(null,this.onInitialDataError.bind(this)),promise["finally"](tgLoader.pageLoaded)}return extend(ProjectsController,superClass),ProjectsController.$inject=["$scope","$q","$tgResources","$rootScope","$tgNavUrls","$tgAuth","$tgLocation","$appTitle","$projectUrl","tgLoader"],ProjectsController.prototype.loadInitialData=function(){var ref;return this.rs.projects.listByMember(null!=(ref=this.rootscope.user)?ref.id:void 0).then(function(_this){return function(projects){var i,len,project;for(_this.projects={recents:projects.slice(0,8),all:projects},i=0,len=projects.length;len>i;i++)project=projects[i],project.url=_this.projectUrl.get(project);return projects}}(this))},ProjectsController.prototype.newProject=function(){return this.rootscope.$broadcast("projects:create")},ProjectsController.prototype.logout=function(){return this.auth.logout(),this.location.path(this.navUrls.resolve("login"))},ProjectsController}(taiga.Controller),module.controller("ProjectsController",ProjectsController),ProjectController=function(superClass){function ProjectController(scope,rs,repo,params,q,rootscope,appTitle,location,navUrls){var promise;this.scope=scope,this.rs=rs,this.repo=repo,this.params=params,this.q=q,this.rootscope=rootscope,this.appTitle=appTitle,this.location=location,this.navUrls=navUrls,promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set(_this.scope.project.name),_this.scope.$emit("regenerate:project-pagination")}}(this)),promise.then(null,this.onInitialDataError.bind(this))}return extend(ProjectController,superClass),ProjectController.$inject=["$scope","$tgResources","$tgRepo","$routeParams","$q","$rootScope","$appTitle","$tgLocation","$tgNavUrls"],ProjectController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadPageData()}}(this)).then(function(_this){return function(){return _this.scope.$emit("project:loaded",_this.scope.project)}}(this))},ProjectController.prototype.loadPageData=function(){return this.q.all([this.loadProjectStats(),this.loadProject()])},ProjectController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,project}}(this))},ProjectController.prototype.loadProjectStats=function(){return this.rs.projects.stats(this.scope.projectId).then(function(_this){return function(stats){return _this.scope.stats=stats,stats}}(this))},ProjectController}(taiga.Controller),module.controller("ProjectController",ProjectController),ProjectsPaginationDirective=function(){var link;return link=function($scope,$el){var checkButtonVisibility,container,containerSize,hasNextPage,hasPagination,hasPrevPage,hide,nextBtn,nextPage,pageSize,prevBtn,prevPage,remove,render,visible;return prevBtn=$el.find(".v-pagination-previous"),nextBtn=$el.find(".v-pagination-next"),container=$el.find("ul"),pageSize=0,containerSize=0,render=function(){return pageSize=$el.find(".v-pagination-list").height(),container.find("li").length&&hasPagination()?(hasNextPage()?visible(nextBtn):hide(nextBtn),hasPrevPage()?visible(prevBtn):hide(prevBtn)):remove()},hasPagination=function(){return containerSize=container.height(),containerSize>pageSize},hasPrevPage=function(top){return null==top&&(top=-parseInt(container.css("top"),10)||0),0!==top},hasNextPage=function(top){return containerSize=container.height(),top||(top=-parseInt(container.css("top"),10)||0),containerSize>pageSize&&containerSize>top+pageSize},nextPage=function(callback){var lastLi,maxTop,newTop,top;return top=parseInt(container.css("top"),10),newTop=top-pageSize,lastLi=$el.find(".v-pagination-list li:last-child"),maxTop=-(lastLi.position().top+lastLi.outerHeight()-pageSize),maxTop>newTop&&(newTop=maxTop),container.animate({top:newTop},callback),newTop},prevPage=function(callback){var newTop,top;return top=parseInt(container.css("top"),10),newTop=top+pageSize,newTop>0&&(newTop=0),container.animate({top:newTop},callback),newTop},visible=function(element){return element.css("visibility","visible")},hide=function(element){return element.css("visibility","hidden")},checkButtonVisibility=function(){},remove=function(){return container.css("top",0),hide(prevBtn),hide(nextBtn)},$el.on("click",".v-pagination-previous",function(event){var newTop;return event.preventDefault(),container.is(":animated")?void 0:(visible(nextBtn),newTop=prevPage(),hasPrevPage(newTop)?void 0:hide(prevBtn))}),$el.on("click",".v-pagination-next",function(event){var newTop;return event.preventDefault(),container.is(":animated")?void 0:(visible(prevBtn),newTop=-nextPage(),hasNextPage(newTop)?void 0:hide(nextBtn))}),$scope.$on("regenerate:project-pagination",function(){return remove(),render()}),$(window).on("resize.projects-pagination",render),$scope.$on("$destroy",function(){return $(window).off("resize.projects-pagination")})},{link:link}},module.directive("tgProjectsPagination",["$timeout",ProjectsPaginationDirective]),ProjectsListDirective=function($compile,$template){var link,template;return template=$template.get("project/project-list.html",!0),link=function($scope,$el){var render;return render=function(projects){return $el.html($compile(template({projects:projects}))($scope)),$scope.$emit("regenerate:project-pagination")},$scope.$on("projects:loaded",function(ctx,projects){return null!=projects.all?render(projects.all):void 0})},{link:link}},module.directive("tgProjectsList",["$compile","$tgTemplate",ProjectsListDirective])}.call(this),function(){var BindHtmlDirective,BindOnceAltDirective,BindOnceBindDirective,BindOnceHrefDirective,BindOnceHtmlDirective,BindOnceRefDirective,BindOnceSrcDirective,BindOnceTitleDirective,BindTitleDirective,bindOnce,module;bindOnce=this.taiga.bindOnce,BindOnceBindDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoBind,function(val){return $el.text(val)})},{link:link}},BindOnceHtmlDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoHtml,function(val){return $el.html(val)})},{link:link}},BindOnceRefDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoRef,function(val){return $el.html("#"+val+" ")})},{link:link}},BindOnceSrcDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoSrc,function(val){return $el.attr("src",val)})},{link:link}},BindOnceHrefDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoHref,function(val){return $el.attr("href",val)})},{link:link}},BindOnceAltDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoAlt,function(val){return $el.attr("alt",val)})},{link:link}},BindOnceTitleDirective=function(){var link;return link=function($scope,$el,$attrs){return bindOnce($scope,$attrs.tgBoTitle,function(val){return $el.attr("title",val)})},{link:link}},BindTitleDirective=function(){var link;return link=function($scope,$el,$attrs){return $scope.$watch($attrs.tgTitleHtml,function(val){return null!=val?$el.attr("title",val):void 0})},{link:link}},BindHtmlDirective=function(){var link;return link=function($scope,$el,$attrs){return $scope.$watch($attrs.tgBindHtml,function(val){return null!=val?$el.html(val):void 0})},{link:link}},module=angular.module("taigaBase"),module.directive("tgBoBind",BindOnceBindDirective),module.directive("tgBoHtml",BindOnceHtmlDirective),module.directive("tgBoRef",BindOnceRefDirective),module.directive("tgBoSrc",BindOnceSrcDirective),module.directive("tgBoHref",BindOnceHrefDirective),module.directive("tgBoAlt",BindOnceAltDirective),module.directive("tgBoTitle",BindOnceTitleDirective),module.directive("tgBindTitle",BindTitleDirective),module.directive("tgBindHtml",BindHtmlDirective)}.call(this),function(){var ConfigurationService,module;ConfigurationService=function(){function ConfigurationService(){this.config=window.taigaConfig}return ConfigurationService.prototype.get=function(key,defaultValue){return null==defaultValue&&(defaultValue=null),_.has(this.config,key)?this.config[key]:defaultValue},ConfigurationService}(),module=angular.module("taigaBase"),module.service("$tgConfig",ConfigurationService)}.call(this),function(){var ContribController,module,taigaContribPlugins,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taigaContribPlugins=this.taigaContribPlugins=this.taigaContribPlugins||[],ContribController=function(superClass){function ContribController(rootScope,scope,params,repo,rs,confirm,appTitle){var promise;this.rootScope=rootScope,this.scope=scope,this.params=params,this.repo=repo,this.rs=rs,this.confirm=confirm,this.appTitle=appTitle,this.scope.adminPlugins=_.where(this.rootScope.contribPlugins,{type:"admin"}),this.scope.currentPlugin=_.first(_.where(this.scope.adminPlugins,{slug:this.params.plugin})),this.scope.pluginTemplate="contrib/"+this.scope.currentPlugin.slug,this.scope.projectSlug=this.params.pslug,promise=this.loadInitialData(),promise.then(function(_this){return function(){return _this.appTitle.set(_this.scope.project.name)}}(this)),promise.then(null,function(_this){return function(){return _this.confirm.notify("error")}}(this))}return extend(ContribController,superClass),ContribController.$inject=["$rootScope","$scope","$routeParams","$tgRepo","$tgResources","$tgConfirm","$appTitle"],ContribController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),_this.scope.$broadcast("project:loaded",project),project}}(this))},ContribController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this))},ContribController}(taiga.Controller),module=angular.module("taigaBase"),module.controller("ContribController",ContribController)}.call(this),function(){var FiltersStorageService,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,FiltersStorageService=function(superClass){function FiltersStorageService(storage,params){this.storage=storage,this.params=params}return extend(FiltersStorageService,superClass),FiltersStorageService.$inject=["$tgStorage","$routeParams"],FiltersStorageService.prototype.generateHash=function(components){return null==components&&(components=[]),components=_.map(components,function(x){return JSON.stringify(x)}),hex_sha1(components.join(":"))},FiltersStorageService}(taiga.Service)}.call(this),function(){var HttpService,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,HttpService=function(superClass){function HttpService(http,q,storage){this.http=http,this.q=q,this.storage=storage,HttpService.__super__.constructor.call(this)}return extend(HttpService,superClass),HttpService.$inject=["$http","$q","$tgStorage"],HttpService.prototype.headers=function(){var token;return token=this.storage.get("token"),token?{Authorization:"Bearer "+token}:{}},HttpService.prototype.request=function(options){return options.headers=_.merge({},options.headers||{},this.headers()),_.isPlainObject(options.data)&&(options.data=JSON.stringify(options.data)),this.http(options)},HttpService.prototype.get=function(url,params,options){return options=_.merge({method:"GET",url:url},options),params&&(options.params=params),this.request(options)},HttpService.prototype.post=function(url,data,params,options){return options=_.merge({method:"POST",url:url},options),data&&(options.data=data),params&&(options.params=params),this.request(options)},HttpService.prototype.put=function(url,data,params,options){return options=_.merge({method:"PUT",url:url},options),data&&(options.data=data),params&&(options.params=params),this.request(options)},HttpService.prototype.patch=function(url,data,params,options){return options=_.merge({method:"PATCH",url:url},options),data&&(options.data=data),params&&(options.params=params),this.request(options)},HttpService.prototype["delete"]=function(url,data,params,options){return options=_.merge({method:"DELETE",url:url},options),data&&(options.data=data),params&&(options.params=params),this.request(options)},HttpService}(taiga.Service),module=angular.module("taigaBase"),module.service("$tgHttp",HttpService)}.call(this),function(){var I18nDirective,I18nService,bindOnce,defaults,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,bindOnce=this.taiga.bindOnce,defaults={ns:"app",fallbackLng:"en",async:!1,lng:"en"},I18nService=function(superClass){function I18nService(rootscope,localesEn){this.rootscope=rootscope,this.options=_.clone(defaults,!0),this.options.resStore={en:{app:localesEn}}}return extend(I18nService,superClass),I18nService.prototype.setLanguage=function(language){return i18n.setLng(language),this.rootscope.currentLang=language,this.rootscope.$broadcast("i18n:changeLang",language)},I18nService.prototype.initialize=function(){return i18n.init(this.options),this.rootscope.t=i18n.t},I18nService.prototype.t=function(path,opts){return i18n.t(path,opts)},I18nService}(taiga.Service),I18nDirective=function($rootscope,$i18n){var link;return link=function($scope,$el,$attrs){var i,len,ns,options,opts,ref,results,v,values;for(values=$attrs.tr.split(","),options=$attrs.trOpts||"{}",opts=$scope.$eval(options),results=[],i=0,len=values.length;len>i;i++)v=values[i],-1===v.indexOf(":")?results.push($el.html(_.escape($i18n.t(v,opts)))):(ref=v.split(":"),ns=ref[0],v=ref[1],results.push($el.attr(ns,_.escape($i18n.t(v,opts)))));return results},{link:link,restrict:"A",scope:!1}},module=angular.module("taigaBase"),module.service("$tgI18n",["$rootScope","localesEn",I18nService]),module.directive("tr",["$rootScope","$tgI18n",I18nDirective])}.call(this),function(){var locationFactory,module;locationFactory=function($location,$route){return $location.noreload=function(scope){var lastRoute,un;return lastRoute=$route.current,un=scope.$on("$locationChangeSuccess",function(){return $route.current=lastRoute,un()}),$location},$location.isInCurrentRouteParams=function(name,value){var params;return params=_.merge($route.current.params,$location.search()),params[name]===value},$location},module=angular.module("taigaBase"),module.factory("$tgLocation",["$location","$route","$rootScope",locationFactory])}.call(this),function(){var Model,ModelService,module,provider,taiga,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;l>i;i++)if(i in this&&this[i]===item)return i;return-1},extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;Model=function(){function Model(name,data,dataTypes){this._attrs=data,this._name=name,this._dataTypes=dataTypes,this.setAttrs(data),this.initialize()}return Model.prototype.clone=function(){var instance;return instance=new Model(this._name,this._attrs,this._dataTypes),instance._modifiedAttrs=this._modifiedAttrs,instance._isModified=this._isModified,instance},Model.prototype.applyCasts=function(){var attrName,castMethod,castName,ref,results;ref=this._dataTypes,results=[];for(attrName in ref)castName=ref[attrName],castMethod=service.casts[castName],castMethod&&results.push(this._attrs[attrName]=castMethod(this._attrs[attrName]));return results},Model.prototype.getIdAttrName=function(){return"id"},Model.prototype.getName=function(){return this._name},Model.prototype.getAttrs=function(patch){return null==patch&&(patch=!1),null!=this._attrs.version&&(this._modifiedAttrs.version=this._attrs.version),patch?_.extend({},this._modifiedAttrs):_.extend({},this._attrs,this._modifiedAttrs)},Model.prototype.setAttrs=function(attrs){return this._attrs=attrs,this._modifiedAttrs={},this.applyCasts(),this._isModified=!1},Model.prototype.setAttr=function(name,value){return this._modifiedAttrs[name]=value,this._isModified=!0},Model.prototype.initialize=function(){var getter,self,setter;return self=this,getter=function(name){return function(){return"string"==typeof name&&"__"===name.substr(0,2)?self[name]:indexOf.call(_.keys(self._modifiedAttrs),name)<0?self._attrs[name]:self._modifiedAttrs[name]}},setter=function(name){return function(value){return"string"==typeof name&&"__"===name.substr(0,2)?void(self[name]=value):void(self._attrs[name]!==value?(self._modifiedAttrs[name]=value,self._isModified=!0):delete self._modifiedAttrs[name])}},_.each(this._attrs,function(value,name){var options;return options={get:getter(name),set:setter(name),enumerable:!0,configurable:!0},Object.defineProperty(self,name,options)})},Model.prototype.serialize=function(){var data;return data={data:_.clone(this._attrs),name:this._name},JSON.stringify(data)},Model.prototype.isModified=function(){return this._isModified},Model.prototype.isAttributeModified=function(attribute){return null!=this._modifiedAttrs[attribute]},Model.prototype.markSaved=function(){return this._isModified=!1,this._attrs=this.getAttrs(),this._modifiedAttrs={}},Model.prototype.revert=function(){return this._modifiedAttrs={},this._isModified=!1},Model.desSerialize=function(sdata){var ddata,model;return ddata=JSON.parse(sdata),model=new Model(ddata.url,ddata.data)},Model}(),taiga=this.taiga,ModelService=function(superClass){function ModelService(q,urls,storage,http){this.q=q,this.urls=urls,this.storage=storage,this.http=http,ModelService.__super__.constructor.call(this)}return extend(ModelService,superClass),ModelService.$inject=["$q","$tgUrls","$tgStorage","$tgHttp"],ModelService}(taiga.Service),provider=function(){var service;return service={},service.make_model=function(name,data,cls,dataTypes){return null==cls&&(cls=Model),null==dataTypes&&(dataTypes={}),new cls(name,data,dataTypes)},service.cls=Model,service.casts={"int":function(value){return parseInt(value,10)},"float":function(value){return parseFloat(value,10)}},service},module=angular.module("taigaBase"),module.factory("$tgModel",["$q","$http","$tgUrls","$tgStorage",provider])}.call(this),function(){var NavigationUrlsDirective,NavigationUrlsService,bindOnce,module,taiga,trim,extend=function(child,parent){function ctor(){this.constructor=child
}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,trim=this.taiga.trim,bindOnce=this.taiga.bindOnce,module=angular.module("taigaBase"),NavigationUrlsService=function(superClass){function NavigationUrlsService(){this.urls={}}return extend(NavigationUrlsService,superClass),NavigationUrlsService.prototype.update=function(urls){return this.urls=_.merge({},this.urls,urls||{})},NavigationUrlsService.prototype.formatUrl=function(url,ctx){var replacer;return null==ctx&&(ctx={}),replacer=function(match){return match=trim(match,":"),ctx[match]||"undefined"},url.replace(/(:\w+)/g,replacer)},NavigationUrlsService.prototype.resolve=function(name,ctx){var url;return url=this.urls[name],url?ctx?this.formatUrl(url,ctx):url:""},NavigationUrlsService}(taiga.Service),module.service("$tgNavUrls",NavigationUrlsService),NavigationUrlsDirective=function($navurls,$auth,$q,$location){var bindOnceP,link,parseNav;return bindOnceP=function($scope,attr){var defered;return defered=$q.defer(),bindOnce($scope,attr,function(v){return defered.resolve(v)}),defered.promise},parseNav=function(data,$scope){var name,params,promises,ref,values;return ref=_.map(data.split(":"),trim),name=ref[0],params=ref[1],params=params?_.map(params.split(","),trim):[],values=_.map(params,function(x){return trim(x.split("=")[1])}),promises=_.map(values,function(x){return bindOnceP($scope,x)}),$q.all(promises).then(function(){var i,item,key,len,options,ref1,value;for(options={},i=0,len=params.length;len>i;i++)item=params[i],ref1=_.map(item.split("="),trim),key=ref1[0],value=ref1[1],options[key]=$scope.$eval(value);return[name,options]})},link=function($scope,$el,$attrs){return $el.is("a")&&$el.attr("href","#"),$el.on("mouseenter",function(event){var target;return target=$(event.currentTarget),target.data("fullUrl")?void 0:parseNav($attrs.tgNav,$scope).then(function(result){var fullUrl,name,options,url,user;return name=result[0],options=result[1],user=$auth.getUser(),user&&(options.user=user.username),url=$navurls.resolve(name),fullUrl=$navurls.formatUrl(url,options),target.data("fullUrl",fullUrl),target.is("a")&&target.attr("href",fullUrl),$el.on("click",function(event){if(event.preventDefault(),target=$(event.currentTarget),!target.hasClass("noclick"))switch(fullUrl=target.data("fullUrl"),event.which){case 1:return $location.url(fullUrl),$scope.$apply();case 2:return window.open(fullUrl)}})})}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgNav",["$tgNavUrls","$tgAuth","$q","$tgLocation",NavigationUrlsDirective])}.call(this),function(){var RepositoryService,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,RepositoryService=function(superClass){function RepositoryService(q,model1,storage,http,urls){this.q=q,this.model=model1,this.storage=storage,this.http=http,this.urls=urls,RepositoryService.__super__.constructor.call(this)}return extend(RepositoryService,superClass),RepositoryService.$inject=["$q","$tgModel","$tgStorage","$tgHttp","$tgUrls"],RepositoryService.prototype.resolveUrlForModel=function(model){var idAttrName;return idAttrName=model.getIdAttrName(),this.urls.resolve(model.getName())+"/"+model[idAttrName]},RepositoryService.prototype.resolveUrlForAttributeModel=function(model){return this.urls.resolve(model.getName(),model.parent)},RepositoryService.prototype.create=function(name,data,dataTypes,extraParams){var defered,promise,url;return null==dataTypes&&(dataTypes={}),null==extraParams&&(extraParams={}),defered=this.q.defer(),url=this.urls.resolve(name),promise=this.http.post(url,JSON.stringify(data)),promise.success(function(_this){return function(_data){return defered.resolve(_this.model.make_model(name,_data,null,dataTypes))}}(this)),promise.error(function(){return function(data){return defered.reject(data)}}(this)),defered.promise},RepositoryService.prototype.remove=function(model,params){var defered,promise,url;return null==params&&(params={}),defered=this.q.defer(),url=this.resolveUrlForModel(model),promise=this.http["delete"](url,{},params),promise.success(function(){return defered.resolve(model)}),promise.error(function(){return defered.reject(model)}),defered.promise},RepositoryService.prototype.saveAll=function(models,patch){var promises;return null==patch&&(patch=!0),promises=_.map(models,function(_this){return function(x){return _this.save(x,!0)}}(this)),this.q.all(promises)},RepositoryService.prototype.save=function(model,patch){var data,defered,promise,url;return null==patch&&(patch=!0),defered=this.q.defer(),!model.isModified()&&patch?(defered.resolve(model),defered.promise):(url=this.resolveUrlForModel(model),data=JSON.stringify(model.getAttrs(patch)),promise=patch?this.http.patch(url,data):this.http.put(url,data),promise.success(function(){return function(data){return model._isModified=!1,model._attrs=_.extend(model.getAttrs(),data),model._modifiedAttrs={},model.applyCasts(),defered.resolve(model)}}(this)),promise.error(function(data){return defered.reject(data)}),defered.promise)},RepositoryService.prototype.saveAttribute=function(model,attribute,patch){var data,defered,promise,url;return null==patch&&(patch=!0),defered=this.q.defer(),!model.isModified()&&patch?(defered.resolve(model),defered.promise):(url=this.resolveUrlForAttributeModel(model),data={},data[attribute]=model.getAttrs(),promise=patch?this.http.patch(url,data):this.http.put(url,data),promise.success(function(){return function(data){return model._isModified=!1,model._attrs=_.extend(model.getAttrs(),data),model._modifiedAttrs={},model.applyCasts(),defered.resolve(model)}}(this)),promise.error(function(data){return defered.reject(data)}),defered.promise)},RepositoryService.prototype.refresh=function(model){var defered,promise,url;return defered=this.q.defer(),url=this.resolveUrlForModel(model),promise=this.http.get(url),promise.success(function(data){return model._modifiedAttrs={},model._attrs=data,model._isModified=!1,model.applyCasts(),defered.resolve(model)}),promise.error(function(data){return defered.reject(data)}),defered.promise},RepositoryService.prototype.queryMany=function(name,params,options){var httpOptions,url;return null==options&&(options={}),url=this.urls.resolve(name),httpOptions={headers:{}},options.enablePagination||(httpOptions.headers["x-disable-pagination"]="1"),this.http.get(url,params,httpOptions).then(function(_this){return function(data){return _.map(data.data,function(x){return _this.model.make_model(name,x)})}}(this))},RepositoryService.prototype.queryOneAttribute=function(name,id,attribute,params,options){var httpOptions,url;return null==options&&(options={}),url=this.urls.resolve(name,id),httpOptions={headers:{}},options.enablePagination||(httpOptions.headers["x-disable-pagination"]="1"),this.http.get(url,params,httpOptions).then(function(_this){return function(data){var model;return model=_this.model.make_model(name,data.data[attribute]),model.parent=id,model}}(this))},RepositoryService.prototype.queryOne=function(name,id,params,options){var httpOptions,url;return null==options&&(options={}),url=this.urls.resolve(name),id&&(url=url+"/"+id),httpOptions={headers:{}},options.enablePagination||(httpOptions.headers["x-disable-pagination"]="1"),this.http.get(url,params,httpOptions).then(function(_this){return function(data){return _this.model.make_model(name,data.data)}}(this))},RepositoryService.prototype.queryOneRaw=function(name,id,params,options){var httpOptions,url;return null==options&&(options={}),url=this.urls.resolve(name),id&&(url=url+"/"+id),httpOptions=_.merge({headers:{}},options),options.enablePagination||(httpOptions.headers["x-disable-pagination"]="1"),this.http.get(url,params,httpOptions).then(function(){return function(data){return data.data}}(this))},RepositoryService.prototype.queryPaginated=function(name,params,options){var httpOptions,url;return null==options&&(options={}),url=this.urls.resolve(name),httpOptions=_.merge({headers:{}},options),this.http.get(url,params,httpOptions).then(function(_this){return function(data){var headers,result;return headers=data.headers(),result={},result.models=_.map(data.data,function(x){return _this.model.make_model(name,x)}),result.count=parseInt(headers["x-pagination-count"],10),result.current=parseInt(headers["x-pagination-current"]||1,10),result.paginatedBy=parseInt(headers["x-paginated-by"],10),result}}(this))},RepositoryService.prototype.resolve=function(options){var cache,params;return params={},null!=options.pslug&&(params.project=options.pslug),null!=options.usref&&(params.us=options.usref),null!=options.taskref&&(params.task=options.taskref),null!=options.issueref&&(params.issue=options.issueref),null!=options.sslug&&(params.milestone=options.sslug),null!=options.wikipage&&(params.wikipage=options.wikipage),cache=!(options.wikipage||options.sslug),this.queryOneRaw("resolver",null,params,{cache:cache})},RepositoryService}(taiga.Service),module=angular.module("taigaBase"),module.service("$tgRepo",RepositoryService)}.call(this),function(){var StorageService,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,StorageService=function(superClass){function StorageService(){StorageService.__super__.constructor.call(this)}return extend(StorageService,superClass),StorageService.$inject=["$rootScope"],StorageService.prototype.get=function(key,_default){var serializedValue;return serializedValue=localStorage.getItem(key),null===serializedValue?_default||null:JSON.parse(serializedValue)},StorageService.prototype.set=function(key,val){return _.isObject(key)?_.each(key,function(_this){return function(val,key){return _this.set(key,val)}}(this)):localStorage.setItem(key,JSON.stringify(val))},StorageService.prototype.contains=function(key){var value;return value=this.get(key),null!==value},StorageService.prototype.remove=function(key){return localStorage.removeItem(key)},StorageService.prototype.clear=function(){return localStorage.clear()},StorageService}(taiga.Service),module=angular.module("taigaBase"),module.service("$tgStorage",StorageService)}.call(this),function(){var UrlsService,format,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;format=function(fmt,obj){return obj=_.clone(obj),fmt.replace(/%s/g,function(){return String(obj.shift())})},taiga=this.taiga,UrlsService=function(superClass){function UrlsService(config){this.config=config,this.urls={},this.mainUrl=this.config.get("api")}return extend(UrlsService,superClass),UrlsService.$inject=["$tgConfig"],UrlsService.prototype.update=function(urls){return this.urls=_.merge(this.urls,urls)},UrlsService.prototype.resolve=function(){var args,name,url;if(args=_.toArray(arguments),0===args.length)throw Error("wrong arguments to setUrls");return name=args.slice(0,1)[0],url=format(this.urls[name],args.slice(1)),format("%s/%s",[_.str.rtrim(this.mainUrl,"/"),_.str.ltrim(url,"/")])},UrlsService.prototype.resolveAbsolute=function(){var url;return url=this.resolve.apply(this,arguments),/^https?:\/\//i.test(url)?url:/^\//.test(url)?window.location.protocol+"//"+window.location.host+url:window.location.protocol+"//"+window.location.host+"/"+url},UrlsService}(taiga.Service),module=angular.module("taigaBase"),module.service("$tgUrls",UrlsService)}.call(this),function(){var module,resourceProvider,sizeFormat,taiga;taiga=this.taiga,sizeFormat=this.taiga.sizeFormat,resourceProvider=function($rootScope,$config,$urls,$model,$repo,$auth,$q){var service;return service={},service.list=function(urlName,objectId,projectId){var params;return params={object_id:objectId,project:projectId},$repo.queryMany(urlName,params)},service.create=function(urlName,projectId,objectId,file){var data,defered,maxFileSize,response,uploadComplete,uploadFailed,uploadProgress,xhr;return defered=$q.defer(),void 0===file?(defered.reject(null),defered.promise):(maxFileSize=$config.get("maxUploadFileSize",null),maxFileSize&&file.size>maxFileSize?(response={status:413,data:{_error_message:"'"+file.name+"' ("+sizeFormat(file.size)+") is too heavy for our oompa loompas, try it with a smaller than ("+sizeFormat(maxFileSize)+")"}},defered.reject(response),defered.promise):(uploadProgress=function(){return function(evt){return $rootScope.$apply(function(){return file.status="in-progress",file.size=sizeFormat(evt.total),file.progressMessage="upload "+sizeFormat(evt.loaded)+" of "+sizeFormat(evt.total),file.progressPercent=Math.round(evt.loaded/evt.total*100)+"%"})}}(this),uploadComplete=function(){return function(evt){return $rootScope.$apply(function(){var data,model;file.status="done";try{data=JSON.parse(evt.target.responseText)}catch(_error){data={}}return model=$model.make_model(urlName,data),defered.resolve(model)})}}(this),uploadFailed=function(){return function(){return $rootScope.$apply(function(){return file.status="error",defered.reject("fail")})}}(this),data=new FormData,data.append("project",projectId),data.append("object_id",objectId),data.append("attached_file",file),xhr=new XMLHttpRequest,xhr.upload.addEventListener("progress",uploadProgress,!1),xhr.addEventListener("load",uploadComplete,!1),xhr.addEventListener("error",uploadFailed,!1),xhr.open("POST",$urls.resolve(urlName)),xhr.setRequestHeader("Authorization","Bearer "+$auth.getToken()),xhr.setRequestHeader("Accept","application/json"),xhr.send(data),defered.promise))},function(instance){return instance.attachments=service}},module=angular.module("taigaResources"),module.factory("$tgAttachmentsResourcesProvider",["$rootScope","$tgConfig","$tgUrls","$tgModel","$tgRepo","$tgAuth","$q",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo){var _get,service;return _get=function(objectId,resource){return $repo.queryOne(resource,objectId)},service={userstory:{get:function(objectId){return _get(objectId,"custom-attributes-values/userstory")}},task:{get:function(objectId){return _get(objectId,"custom-attributes-values/task")}},issue:{get:function(objectId){return _get(objectId,"custom-attributes-values/issue")}}},function(instance){return instance.customAttributesValues=service}},module=angular.module("taigaResources"),module.factory("$tgCustomAttributesValuesResourcesProvider",["$tgRepo",resourceProvider])}.call(this),function(){var module,resourceProvider,sizeFormat,taiga;taiga=this.taiga,sizeFormat=this.taiga.sizeFormat,resourceProvider=function($repo){var _list,service;return _list=function(projectId,resource){return $repo.queryMany(resource,{project:projectId})},service={userstory:{list:function(projectId){return _list(projectId,"custom-attributes/userstory")}},task:{list:function(projectId){return _list(projectId,"custom-attributes/task")}},issue:{list:function(projectId){return _list(projectId,"custom-attributes/issue")}}},function(instance){return instance.customAttributes=service}},module=angular.module("taigaResources"),module.factory("$tgCustomAttributesResourcesProvider",["$tgRepo",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo,$http,$urls){var service;return service={},service.get=function(type,objectId){return $repo.queryOneRaw("history/"+type,objectId)},service.deleteComment=function(type,objectId,activityId){var params,url;return url=$urls.resolve("history/"+type),url=url+"/"+objectId+"/delete_comment",params={id:activityId},$http.post(url,null,params).then(function(){return function(data){return data.data}}(this))},service.undeleteComment=function(type,objectId,activityId){var params,url;return url=$urls.resolve("history/"+type),url=url+"/"+objectId+"/undelete_comment",params={id:activityId},$http.post(url,null,params).then(function(){return function(data){return data.data}}(this))},function(instance){return instance.history=service}},module=angular.module("taigaResources"),module.factory("$tgHistoryResourcesProvider",["$tgRepo","$tgHttp","$tgUrls",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo){var service;return service={},service.get=function(token){return $repo.queryOne("invitations",token)},function(instance){return instance.invitations=service}},module=angular.module("taigaResources"),module.factory("$tgInvitationsResourcesProvider",["$tgRepo",resourceProvider])}.call(this),function(){var generateHash,module,resourceProvider,taiga;taiga=this.taiga,generateHash=taiga.generateHash,resourceProvider=function($repo,$http,$urls,$storage,$q){var filtersHashSuffix,hashSuffix,myFiltersHashSuffix,service;return service={},hashSuffix="issues-queryparams",filtersHashSuffix="issues-filters",myFiltersHashSuffix="issues-my-filters",service.get=function(projectId,issueId){var params;return params=service.getQueryParams(projectId),params.project=projectId,$repo.queryOne("issues",issueId,params)},service.getByRef=function(projectId,ref){var params;return params=service.getQueryParams(projectId),params.project=projectId,params.ref=ref,$repo.queryOne("issues","by_ref",params)},service.list=function(projectId,filters,options){var params;return params={project:projectId},params=_.extend({},params,filters||{}),service.storeQueryParams(projectId,params),$repo.queryPaginated("issues",params,options)},service.bulkCreate=function(projectId,data){var params,url;return url=$urls.resolve("bulk-create-issues"),params={project_id:projectId,bulk_issues:data},$http.post(url,params)},service.stats=function(projectId){return $repo.queryOneRaw("projects",projectId+"/issues_stats")},service.filtersData=function(projectId){return $repo.queryOneRaw("projects",projectId+"/issue_filters_data")},service.listValues=function(projectId,type){var params;return params={project:projectId},service.storeQueryParams(projectId,params),$repo.queryMany(type,params)},service.storeQueryParams=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getQueryParams=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},service.storeFilters=function(projectSlug,params){var hash,ns;return ns=projectSlug+":"+filtersHashSuffix,hash=generateHash([projectSlug,ns]),$storage.set(hash,params)},service.getFilters=function(projectSlug){var hash,ns;return ns=projectSlug+":"+filtersHashSuffix,hash=generateHash([projectSlug,ns]),$storage.get(hash)||{}},service.storeMyFilters=function(projectId,myFilters){var deferred,hash,ns,promise,url;return deferred=$q.defer(),url=$urls.resolve("user-storage"),ns=projectId+":"+myFiltersHashSuffix,hash=generateHash([projectId,ns]),_.isEmpty(myFilters)?(promise=$http["delete"](url+"/"+hash,{key:hash,value:myFilters}),promise.then(function(){return deferred.resolve()}),promise.then(null,function(){return deferred.reject()})):(promise=$http.put(url+"/"+hash,{key:hash,value:myFilters}),promise.then(function(){return deferred.resolve()}),promise.then(null,function(){var innerPromise;return innerPromise=$http.post(""+url,{key:hash,value:myFilters}),innerPromise.then(function(){return deferred.resolve()}),innerPromise.then(null,function(){return deferred.reject()})})),deferred.promise},service.getMyFilters=function(projectId){var deferred,hash,ns,promise,url;return deferred=$q.defer(),url=$urls.resolve("user-storage"),ns=projectId+":"+myFiltersHashSuffix,hash=generateHash([projectId,ns]),promise=$http.get(url+"/"+hash),promise.then(function(data){return deferred.resolve(data.data.value)}),promise.then(null,function(){return deferred.resolve({})}),deferred.promise},function(instance){return instance.issues=service}},module=angular.module("taigaResources"),module.factory("$tgIssuesResourcesProvider",["$tgRepo","$tgHttp","$tgUrls","$tgStorage","$q",resourceProvider])}.call(this),function(){var generateHash,module,resourceProvider,taiga;taiga=this.taiga,generateHash=taiga.generateHash,resourceProvider=function($storage){var hashSuffixStatusColumnModes,hashSuffixStatusViewModes,service;return service={},hashSuffixStatusViewModes="kanban-statusviewmodels",hashSuffixStatusColumnModes="kanban-statuscolumnmodels",service.storeStatusViewModes=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffixStatusViewModes,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getStatusViewModes=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffixStatusViewModes,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},service.storeStatusColumnModes=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffixStatusColumnModes,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getStatusColumnModes=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffixStatusColumnModes,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},function(instance){return instance.kanban=service}},module=angular.module("taigaResources"),module.factory("$tgKanbanResourcesProvider",["$tgStorage",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo,$urls,$http){var service;return service={},service.render=function(projectId,content){var params,url;return(null==content||""===content)&&(content=" "),params={project_id:projectId,content:content},url=$urls.resolve("wiki"),$http.post(url+"/render",params).then(function(){return function(data){return data.data}}(this))},function(instance){return instance.mdrender=service}},module=angular.module("taigaResources"),module.factory("$tgMdRenderResourcesProvider",["$tgRepo","$tgUrls","$tgHttp",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo,$http,$urls){var service;return service={},service.get=function(id){return $repo.queryOne("memberships",id)},service.list=function(projectId,filters,enablePagination){var options,params;return null==enablePagination&&(enablePagination=!0),params={project:projectId},params=_.extend({},params,filters||{}),enablePagination?$repo.queryPaginated("memberships",params):$repo.queryMany("memberships",params,options={enablePagination:enablePagination})},service.listByUser=function(userId,filters){var params;return params={user:userId},params=_.extend({},params,filters||{}),$repo.queryPaginated("memberships",params)},service.resendInvitation=function(id){var url;return url=$urls.resolve("memberships"),$http.post(url+"/"+id+"/resend_invitation",{})},service.bulkCreateMemberships=function(projectId,data,invitation_extra_text){var params,url;return url=$urls.resolve("bulk-create-memberships"),params={project_id:projectId,bulk_memberships:data,invitation_extra_text:invitation_extra_text},$http.post(url,params)},function(instance){return instance.memberships=service}},module=angular.module("taigaResources"),module.factory("$tgMembershipsResourcesProvider",["$tgRepo","$tgHttp","$tgUrls",resourceProvider])}.call(this),function(){var module,resourceProvider;resourceProvider=function($repo){var service;return service={},service.list=function(projectId,module){return $repo.queryOneAttribute("project-modules",projectId,module)},function(instance){return instance.modules=service}},module=angular.module("taigaResources"),module.factory("$tgModulesResourcesProvider",["$tgRepo",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo){var service;return service={},service.get=function(id){return $repo.queryOne("notify-policies",id)},service.list=function(filters){var params;return params=_.extend({},params,filters||{}),$repo.queryMany("notify-policies",params)},function(instance){return instance.notifyPolicies=service}},module=angular.module("taigaResources"),module.factory("$tgNotifyPoliciesResourcesProvider",["$tgRepo","$tgHttp","$tgUrls",resourceProvider])}.call(this),function(){var module,resourceProvider,sizeFormat,taiga;taiga=this.taiga,sizeFormat=this.taiga.sizeFormat,resourceProvider=function($config,$repo,$http,$urls,$auth,$q){var service;return service={},service.get=function(projectId){return $repo.queryOne("projects",projectId)},service.getBySlug=function(projectSlug){return $repo.queryOne("projects","by_slug?slug="+projectSlug)},service.list=function(){return $repo.queryMany("projects")},service.listByMember=function(memberId){var params;return params={member:memberId},$repo.queryMany("projects",params)},service.templates=function(){return $repo.queryMany("project-templates")},service.usersList=function(projectId){var params;return params={project:projectId},$repo.queryMany("users",params)},service.rolesList=function(projectId){var params;return params={project:projectId},$repo.queryMany("roles",params)},service.stats=function(projectId){return $repo.queryOneRaw("projects",projectId+"/stats")},service.regenerate_userstories_csv_uuid=function(projectId){var url;return url=$urls.resolve("projects")+"/"+projectId+"/regenerate_userstories_csv_uuid",$http.post(url)},service.regenerate_issues_csv_uuid=function(projectId){var url;return url=$urls.resolve("projects")+"/"+projectId+"/regenerate_issues_csv_uuid",$http.post(url)},service.regenerate_tasks_csv_uuid=function(projectId){var url;return url=$urls.resolve("projects")+"/"+projectId+"/regenerate_tasks_csv_uuid",$http.post(url)},service.leave=function(projectId){var url;return url=$urls.resolve("projects")+"/"+projectId+"/leave",$http.post(url)},service.memberStats=function(projectId){return $repo.queryOneRaw("projects",projectId+"/member_stats")},service.tagsColors=function(projectId){return $repo.queryOne("projects",projectId+"/tags_colors")},service["export"]=function(projectId){var url;return url=$urls.resolve("exporter")+"/"+projectId,$http.get(url)},service["import"]=function(file,statusUpdater){var complete,data,defered,failed,maxFileSize,response,uploadComplete,uploadFailed,uploadProgress,xhr;return defered=$q.defer(),maxFileSize=$config.get("maxUploadFileSize",null),maxFileSize&&file.size>maxFileSize?(response={status:413,data:{_error_message:"'"+file.name+"' ("+sizeFormat(file.size)+") is too heavy for our oompa loompas, try it with a smaller than ("+sizeFormat(maxFileSize)+")"}},defered.reject(response),defered.promise):(uploadProgress=function(){return function(evt){var message,percent;return percent=Math.round(evt.loaded/evt.total*100),message="Uloaded "+sizeFormat(evt.loaded)+" of "+sizeFormat(evt.total),statusUpdater("in-progress",null,message,percent)}}(this),uploadComplete=function(){return function(){return statusUpdater("done","Importing Project","This process can take a while, please keep the window open.")}}(this),uploadFailed=function(){return function(){return statusUpdater("error")}}(this),complete=function(){return function(evt){var ref;response={};try{response.data=JSON.parse(evt.target.responseText)}catch(_error){response.data={}}return response.status=evt.target.status,(201===(ref=response.status)||202===ref)&&defered.resolve(response),defered.reject(response)}}(this),failed=function(){return function(){return defered.reject("fail")}}(this),data=new FormData,data.append("dump",file),xhr=new XMLHttpRequest,xhr.upload.addEventListener("progress",uploadProgress,!1),xhr.upload.addEventListener("load",uploadComplete,!1),xhr.upload.addEventListener("error",uploadFailed,!1),xhr.upload.addEventListener("abort",uploadFailed,!1),xhr.addEventListener("load",complete,!1),xhr.addEventListener("error",failed,!1),xhr.open("POST",$urls.resolve("importer")),xhr.setRequestHeader("Authorization","Bearer "+$auth.getToken()),xhr.setRequestHeader("Accept","application/json"),xhr.send(data),defered.promise)},function(instance){return instance.projects=service}},module=angular.module("taigaResources"),module.factory("$tgProjectsResourcesProvider",["$tgConfig","$tgRepo","$tgHttp","$tgUrls","$tgAuth","$q",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo){var service;return service={},service.get=function(id){return $repo.queryOne("roles",id)},service.list=function(projectId){return $repo.queryMany("roles",{project:projectId})},function(instance){return instance.roles=service}},module=angular.module("taigaResources"),module.factory("$tgRolesResourcesProvider",["$tgRepo","$tgHttp","$tgUrls",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo,$urls,$http){var service;return service={},service["do"]=function(projectId,term){var params,url;return url=$urls.resolve("search"),params={project:projectId,text:term,get_all:!1},$http.get(url,params).then(function(data){return data.data})},function(instance){return instance.search=service}},module=angular.module("taigaResources"),module.factory("$tgSearchResourcesProvider",["$tgRepo","$tgUrls","$tgHttp",resourceProvider])}.call(this),function(){var generateHash,module,resourceProvider,taiga;taiga=this.taiga,generateHash=taiga.generateHash,resourceProvider=function($repo,$model,$storage){var hashSuffixUserstories,service;return service={},hashSuffixUserstories="userstories-queryparams",service.get=function(projectId,sprintId){return $repo.queryOne("milestones",sprintId).then(function(sprint){var uses;return service.storeUserstoriesQueryParams(projectId,{milestone:sprintId}),uses=sprint.user_stories,uses=_.map(uses,function(u){return $model.make_model("userstories",u)}),sprint._attrs.user_stories=uses,sprint})},service.stats=function(projectId,sprintId){return $repo.queryOneRaw("milestones",sprintId+"/stats")},service.list=function(projectId,filters){var params;return params={project:projectId},params=_.extend({},params,filters||{}),$repo.queryMany("milestones",params).then(function(){return function(milestones){var i,len,m,uses;for(i=0,len=milestones.length;len>i;i++)m=milestones[i],uses=m.user_stories,uses=_.map(uses,function(u){return $model.make_model("userstories",u)}),m._attrs.user_stories=uses;return milestones}}(this))},service.storeUserstoriesQueryParams=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffixUserstories,hash=generateHash([projectId,ns]),$storage.set(hash,params)},function(instance){return instance.sprints=service}},module=angular.module("taigaResources"),module.factory("$tgSprintsResourcesProvider",["$tgRepo","$tgModel","$tgStorage",resourceProvider])}.call(this),function(){var generateHash,module,resourceProvider,taiga;taiga=this.taiga,generateHash=taiga.generateHash,resourceProvider=function($repo,$http,$urls,$storage){var hashSuffix,hashSuffixStatusColumnModes,hashSuffixUsRowModes,service;return service={},hashSuffix="tasks-queryparams",hashSuffixStatusColumnModes="tasks-statuscolumnmodels",hashSuffixUsRowModes="tasks-usrowmodels",service.get=function(projectId,taskId){var params;return params=service.getQueryParams(projectId),params.project=projectId,$repo.queryOne("tasks",taskId,params)},service.getByRef=function(projectId,ref){var params;return params=service.getQueryParams(projectId),params.project=projectId,params.ref=ref,$repo.queryOne("tasks","by_ref",params)},service.list=function(projectId,sprintId,userStoryId){var params;return null==sprintId&&(sprintId=null),null==userStoryId&&(userStoryId=null),params={project:projectId},sprintId&&(params.milestone=sprintId),userStoryId&&(params.user_story=userStoryId),service.storeQueryParams(projectId,params),$repo.queryMany("tasks",params)
},service.bulkCreate=function(projectId,sprintId,usId,data){var params,url;return url=$urls.resolve("bulk-create-tasks"),params={project_id:projectId,sprint_id:sprintId,us_id:usId,bulk_tasks:data},$http.post(url,params).then(function(result){return result.data})},service.bulkUpdateTaskTaskboardOrder=function(projectId,data){var params,url;return url=$urls.resolve("bulk-update-task-taskboard-order"),params={project_id:projectId,bulk_tasks:data},$http.post(url,params)},service.listValues=function(projectId,type){var params;return params={project:projectId},$repo.queryMany(type,params)},service.storeQueryParams=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getQueryParams=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},service.storeStatusColumnModes=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffixStatusColumnModes,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getStatusColumnModes=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffixStatusColumnModes,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},service.storeUsRowModes=function(projectId,sprintId,params){var hash,ns;return ns=projectId+":"+hashSuffixUsRowModes,hash=generateHash([projectId,sprintId,ns]),$storage.set(hash,params)},service.getUsRowModes=function(projectId,sprintId){var hash,ns;return ns=projectId+":"+hashSuffixUsRowModes,hash=generateHash([projectId,sprintId,ns]),$storage.get(hash)||{}},function(instance){return instance.tasks=service}},module=angular.module("taigaResources"),module.factory("$tgTasksResourcesProvider",["$tgRepo","$tgHttp","$tgUrls","$tgStorage",resourceProvider])}.call(this),function(){var module,resourceProvider,sizeFormat,taiga;taiga=this.taiga,sizeFormat=this.taiga.sizeFormat,resourceProvider=function($config,$repo,$http,$urls,$q){var service;return service={},service.changeAvatar=function(file){var data,defered,maxFileSize,options,response,url;return maxFileSize=$config.get("maxUploadFileSize",null),maxFileSize&&file.size>maxFileSize?(response={status:413,data:{_error_message:"'"+file.name+"' ("+sizeFormat(file.size)+") is too heavy for our oompa loompas, try it with a smaller than ("+sizeFormat(maxFileSize)+")"}},defered=$q.defer(),defered.reject(response),defered.promise):(data=new FormData,data.append("avatar",file),options={transformRequest:angular.identity,headers:{"Content-Type":void 0}},url=$urls.resolve("users")+"/change_avatar",$http.post(url,data,{},options))},service.removeAvatar=function(){var url;return url=$urls.resolve("users")+"/remove_avatar",$http.post(url)},service.changePassword=function(currentPassword,newPassword){var data,url;return url=$urls.resolve("users")+"/change_password",data={current_password:currentPassword,password:newPassword},$http.post(url,data)},function(instance){return instance.userSettings=service}},module=angular.module("taigaResources"),module.factory("$tgUserSettingsResourcesProvider",["$tgConfig","$tgRepo","$tgHttp","$tgUrls","$q",resourceProvider])}.call(this),function(){var generateHash,module,resourceProvider,taiga;taiga=this.taiga,generateHash=taiga.generateHash,resourceProvider=function($repo,$http,$urls,$storage){var hashSuffix,service;return service={},hashSuffix="userstories-queryparams",service.get=function(projectId,usId){var params;return params=service.getQueryParams(projectId),params.project=projectId,$repo.queryOne("userstories",usId,params)},service.getByRef=function(projectId,ref){var params;return params=service.getQueryParams(projectId),params.project=projectId,params.ref=ref,$repo.queryOne("userstories","by_ref",params)},service.listUnassigned=function(projectId,filters){var params;return params={project:projectId,milestone:"null"},params=_.extend({},params,filters||{}),service.storeQueryParams(projectId,params),$repo.queryMany("userstories",params)},service.listAll=function(projectId,filters){var params;return params={project:projectId},params=_.extend({},params,filters||{}),service.storeQueryParams(projectId,params),$repo.queryMany("userstories",params)},service.bulkCreate=function(projectId,status,bulk){var data,url;return data={project_id:projectId,status_id:status,bulk_stories:bulk},url=$urls.resolve("bulk-create-us"),$http.post(url,data)},service.bulkUpdateBacklogOrder=function(projectId,data){var params,url;return url=$urls.resolve("bulk-update-us-backlog-order"),params={project_id:projectId,bulk_stories:data},$http.post(url,params)},service.bulkUpdateSprintOrder=function(projectId,data){var params,url;return url=$urls.resolve("bulk-update-us-sprint-order"),params={project_id:projectId,bulk_stories:data},$http.post(url,params)},service.bulkUpdateKanbanOrder=function(projectId,data){var params,url;return url=$urls.resolve("bulk-update-us-kanban-order"),params={project_id:projectId,bulk_stories:data},$http.post(url,params)},service.listValues=function(projectId,type){var params;return params={project:projectId},service.storeQueryParams(projectId,params),$repo.queryMany(type,params)},service.storeQueryParams=function(projectId,params){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.set(hash,params)},service.getQueryParams=function(projectId){var hash,ns;return ns=projectId+":"+hashSuffix,hash=generateHash([projectId,ns]),$storage.get(hash)||{}},service.storeShowTags=function(projectId,showTags){var hash;return hash=generateHash([projectId,"showTags"]),$storage.set(hash,showTags)},service.getShowTags=function(projectId){var hash;return hash=generateHash([projectId,"showTags"]),$storage.get(hash)||null},function(instance){return instance.userstories=service}},module=angular.module("taigaResources"),module.factory("$tgUserstoriesResourcesProvider",["$tgRepo","$tgHttp","$tgUrls","$tgStorage",resourceProvider])}.call(this),function(){var module,resourceProvider;resourceProvider=function($repo,$urls,$http){var service;return service={},service.list=function(webhookId){var params;return params={webhook:webhookId},$repo.queryMany("webhooklogs",params)},service.resend=function(webhooklogId){var url;return url=$urls.resolve("webhooklogs-resend",webhooklogId),$http.post(url)},function(instance){return instance.webhooklogs=service}},module=angular.module("taigaResources"),module.factory("$tgWebhookLogsResourcesProvider",["$tgRepo","$tgUrls","$tgHttp",resourceProvider])}.call(this),function(){var module,resourceProvider;resourceProvider=function($repo,$urls,$http){var service;return service={},service.list=function(projectId){var params;return params={project:projectId},$repo.queryMany("webhooks",params)},service.test=function(webhookId){var url;return url=$urls.resolve("webhooks-test",webhookId),$http.post(url)},function(instance){return instance.webhooks=service}},module=angular.module("taigaResources"),module.factory("$tgWebhooksResourcesProvider",["$tgRepo","$tgUrls","$tgHttp",resourceProvider])}.call(this),function(){var module,resourceProvider,taiga;taiga=this.taiga,resourceProvider=function($repo){var service;return service={},service.get=function(wikiId){return $repo.queryOne("wiki",wikiId)},service.getBySlug=function(projectId,slug){return $repo.queryOne("wiki","by_slug?project="+projectId+"&slug="+slug)},service.listLinks=function(projectId){return $repo.queryMany("wiki-links",{project:projectId})},function(instance){return instance.wiki=service}},module=angular.module("taigaResources"),module.factory("$tgWikiResourcesProvider",["$tgRepo","$tgHttp","$tgUrls",resourceProvider])}.call(this),function(){var UserChangePasswordController,UserChangePasswordDirective,debounce,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,debounce=this.taiga.debounce,module=angular.module("taigaUserSettings"),UserChangePasswordController=function(superClass){function UserChangePasswordController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,auth){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.auth=auth,this.scope.sectionName="Change Password",this.scope.project={},this.scope.user=this.auth.getUser(),promise=this.loadInitialData(),promise.then(null,this.onInitialDataError.bind(this))}return extend(UserChangePasswordController,superClass),UserChangePasswordController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$tgAuth"],UserChangePasswordController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},UserChangePasswordController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this))},UserChangePasswordController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("UserChangePasswordController",UserChangePasswordController),UserChangePasswordDirective=function($rs,$confirm,$loading){var link;return link=function($scope,$el){var submit,submitButton;return submit=debounce(2e3,function(){return function(event){var promise;return event.preventDefault(),$scope.newPassword1!==$scope.newPassword2?void $confirm.notify("error","The passwords dosn't match"):($loading.start(submitButton),promise=$rs.userSettings.changePassword($scope.currentPassword,$scope.newPassword1),promise.then(function(){return $loading.finish(submitButton),$confirm.notify("success")}),promise.then(null,function(response){return $loading.finish(submitButton),$confirm.notify("error",response.data._error_message)}))}}(this)),submitButton=$el.find(".submit-button"),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgUserChangePassword",["$tgResources","$tgConfirm","$tgLoading",UserChangePasswordDirective])}.call(this),function(){var DeleteUserDirective,bindOnce,debounce,module,taiga;taiga=this.taiga,bindOnce=this.taiga.bindOnce,debounce=this.taiga.debounce,module=angular.module("taigaUserSettings"),DeleteUserDirective=function($repo,$rootscope,$auth,$location,$navUrls,lightboxService){var link;return link=function($scope,$el){var submit;return $scope.$on("deletelightbox:new",function(){return lightboxService.open($el)}),$scope.$on("$destroy",function(){return $el.off()}),submit=function(){var promise;return promise=$repo.remove($scope.user),promise.then(function(){return lightboxService.close($el),$auth.logout(),$location.path($navUrls.resolve("login"))}),promise.then(null,function(){return console.log("FAIL")})},$el.on("click",".button-red",function(event){return event.preventDefault(),lightboxService.close($el)}),$el.on("click",".button-green",debounce(2e3,function(event){return event.preventDefault(),submit()}))},{link:link,templateUrl:"user/lightbox/lightbox-delete-account.html"}},module.directive("tgLbDeleteUser",["$tgRepo","$rootScope","$tgAuth","$tgLocation","$tgNavUrls","lightboxService",DeleteUserDirective])}.call(this),function(){var TaigaAvatarModelDirective,UserAvatarDirective,UserProfileDirective,UserSettingsController,debounce,mixOf,module,sizeFormat,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,sizeFormat=this.taiga.sizeFormat,module=angular.module("taigaUserSettings"),debounce=this.taiga.debounce,UserSettingsController=function(superClass){function UserSettingsController(scope,rootscope,config,repo,confirm,rs,params,q,location,navUrls,auth){var maxFileSize,promise;this.scope=scope,this.rootscope=rootscope,this.config=config,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.auth=auth,this.scope.sectionName="User Profile",this.scope.project={},this.scope.user=this.auth.getUser(),maxFileSize=this.config.get("maxUploadFileSize",null),maxFileSize&&(this.scope.maxFileSizeMsg="[Max, size: "+sizeFormat(maxFileSize)),promise=this.loadInitialData(),promise.then(null,this.onInitialDataError.bind(this))}return extend(UserSettingsController,superClass),UserSettingsController.$inject=["$scope","$rootScope","$tgConfig","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$tgAuth"],UserSettingsController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},UserSettingsController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this))},UserSettingsController.prototype.openDeleteLightbox=function(){return this.rootscope.$broadcast("deletelightbox:new",this.scope.user)},UserSettingsController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("UserSettingsController",UserSettingsController),UserProfileDirective=function($confirm,$auth,$repo){var link;return link=function($scope,$el){var submit;return submit=debounce(2e3,function(){return function(event){var changeEmail,form,onError,onSuccess;return event.preventDefault(),form=$el.find("form").checksley(),form.validate()?(changeEmail=$scope.user.isAttributeModified("email"),onSuccess=function(data){return $auth.setUser(data),changeEmail?$confirm.success("Check your inbox! We have sent a mail to your account with the instructions to set your new address"):$confirm.notify("success")},onError=function(data){return form.setErrors(data),$confirm.notify("error",data._error_message)},$repo.save($scope.user).then(onSuccess,onError)):void 0}}(this)),$el.on("submit","form",submit),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgUserProfile",["$tgConfirm","$tgAuth","$tgRepo",UserProfileDirective]),UserAvatarDirective=function($auth,$model,$rs,$confirm){var link;return link=function($scope,$el){var onError,onSuccess,showSizeInfo;return showSizeInfo=function(){return $el.find(".size-info").removeClass("hidden")},onSuccess=function(response){var user;return user=$model.make_model("users",response.data),$auth.setUser(user),$scope.user=user,$el.find(".overlay").addClass("hidden"),$confirm.notify("success")},onError=function(response){return 413===response.status&&showSizeInfo(),$el.find(".overlay").addClass("hidden"),$confirm.notify("error",response.data._error_message)},$el.on("click",".js-change-avatar",function(){return $el.find("#avatar-field").click()}),$el.on("change","#avatar-field",function(){return $scope.avatarAttachment?($el.find(".overlay").removeClass("hidden"),$rs.userSettings.changeAvatar($scope.avatarAttachment).then(onSuccess,onError)):void 0}),$el.on("click","a.use-gravatar",function(){return $el.find(".overlay").removeClass("hidden"),$rs.userSettings.removeAvatar().then(onSuccess,onError)}),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgUserAvatar",["$tgAuth","$tgModel","$tgResources","$tgConfirm",UserAvatarDirective]),TaigaAvatarModelDirective=function($parse){var link;return link=function($scope,$el,$attrs){var model,modelSetter;return model=$parse($attrs.tgAvatarModel),modelSetter=model.assign,$el.bind("change",function(){return $scope.$apply(function(){return modelSetter($scope,$el[0].files[0])})})},{link:link}},module.directive("tgAvatarModel",["$parse",TaigaAvatarModelDirective])}.call(this),function(){var UserSettingsNavigationDirective,module;UserSettingsNavigationDirective=function(){var link;return link=function($scope,$el,$attrs){var section;return section=$attrs.tgUserSettingsNavigation,$el.find(".active").removeClass("active"),$el.find("#usersettingsmenu-"+section+" a").addClass("active"),$scope.$on("$destroy",function(){return $el.off()})},{link:link}},module=angular.module("taigaUserSettings"),module.directive("tgUserSettingsNavigation",UserSettingsNavigationDirective)}.call(this),function(){var UserNotificationsController,UserNotificationsDirective,UserNotificationsListDirective,bindOnce,mixOf,module,taiga,extend=function(child,parent){function ctor(){this.constructor=child}for(var key in parent)hasProp.call(parent,key)&&(child[key]=parent[key]);return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},hasProp={}.hasOwnProperty;taiga=this.taiga,mixOf=this.taiga.mixOf,bindOnce=this.taiga.bindOnce,module=angular.module("taigaUserSettings"),UserNotificationsController=function(superClass){function UserNotificationsController(scope,rootscope,repo,confirm,rs,params,q,location,navUrls,auth){var promise;this.scope=scope,this.rootscope=rootscope,this.repo=repo,this.confirm=confirm,this.rs=rs,this.params=params,this.q=q,this.location=location,this.navUrls=navUrls,this.auth=auth,this.scope.sectionName="Email Notifications",this.scope.project={},this.scope.user=this.auth.getUser(),promise=this.loadInitialData(),promise.then(null,this.onInitialDataError.bind(this))}return extend(UserNotificationsController,superClass),UserNotificationsController.$inject=["$scope","$rootScope","$tgRepo","$tgConfirm","$tgResources","$routeParams","$q","$tgLocation","$tgNavUrls","$tgAuth"],UserNotificationsController.prototype.loadProject=function(){return this.rs.projects.get(this.scope.projectId).then(function(_this){return function(project){return _this.scope.project=project,_this.scope.$emit("project:loaded",project),project}}(this))},UserNotificationsController.prototype.loadNotifyPolicies=function(){return this.rs.notifyPolicies.list().then(function(_this){return function(notifyPolicies){return _this.scope.notifyPolicies=notifyPolicies,notifyPolicies}}(this))},UserNotificationsController.prototype.loadInitialData=function(){var promise;return promise=this.repo.resolve({pslug:this.params.pslug}).then(function(_this){return function(data){return _this.scope.projectId=data.project,data}}(this)),promise.then(function(_this){return function(){return _this.loadProject()}}(this)).then(function(_this){return function(){return _this.loadNotifyPolicies()}}(this))},UserNotificationsController}(mixOf(taiga.Controller,taiga.PageMixin)),module.controller("UserNotificationsController",UserNotificationsController),UserNotificationsDirective=function(){var link;return link=function($scope,$el){return $scope.$on("$destroy",function(){return $el.off()})},{link:link}},module.directive("tgUserNotifications",UserNotificationsDirective),UserNotificationsListDirective=function($repo,$confirm){var link,template;return template=_.template('<% _.each(notifyPolicies, function (notifyPolicy, index) { %>\n\n
<%- notifyPolicy.project_name %>
\n
\n
\n checked="checked"<% } %>/>\n All \n \n \n
\n
\n checked="checked"<% } %> />\n Involved \n \n \n
\n
\n checked="checked"<% } %> />\n None \n \n \n
\n<% }) %>'),link=function($scope,$el,$attrs){var render;return render=function(){return $el.off(),$el.html(template({notifyPolicies:$scope.notifyPolicies})),$el.on("change","input[type=radio]",function(event){var onError,onSuccess,policy,policyIndex,prev_level,target;return target=angular.element(event.currentTarget),policyIndex=target.parents(".policy-table-row").data("index"),policy=$scope.notifyPolicies[policyIndex],prev_level=policy.notify_level,policy.notify_level=parseInt(target.val(),10),onSuccess=function(){return $confirm.notify("success")},onError=function(){return $confirm.notify("error"),target.parents(".policy-table-row").find("input[value="+prev_level+"]").prop("checked",!0)},$repo.save(policy).then(onSuccess,onError)})},$scope.$on("$destroy",function(){return $el.off()}),bindOnce($scope,$attrs.ngModel,render)},{link:link}},module.directive("tgUserNotificationsList",["$tgRepo","$tgConfirm",UserNotificationsListDirective])}.call(this),function(){var module;module=angular.module("taigaPlugins",["ngRoute"])}.call(this),function(){var configure,module,taiga;taiga=this.taiga,module=angular.module("taigaPlugins"),configure=function($routeProvider){return $routeProvider.when("/humans.html",{templateUrl:"/plugins/humanshtml/templates/humans.html"})},module.config(["$routeProvider",configure])}.call(this),function(){var TermsNoticeDirective,module,taiga,template;taiga=this.taiga,module=angular.module("taigaPlugins"),template=_.template('\n By clicking "Sign up", you agree to our \n terms of service \n and \n privacy policy. \n
'),TermsNoticeDirective=function($config){var privacyPolicyUrl,templateFn,termsOfServiceUrl;return privacyPolicyUrl=$config.get("privacyPolicyUrl"),termsOfServiceUrl=$config.get("termsOfServiceUrl"),templateFn=function(){var ctx;return privacyPolicyUrl&&termsOfServiceUrl?(ctx={termsUrl:termsOfServiceUrl,privacyUrl:privacyPolicyUrl},template(ctx)):""},{scope:{},restrict:"AE",template:templateFn}},module.directive("tgTermsNotice",["$tgConfig",TermsNoticeDirective])}.call(this),angular.module("taigaBase").value("localesEn",{checksley:{defaultMessage:"This value seems to be invalid.","type-email":"This value should be a valid email.","type-url":"This value should be a valid url.","type-urlstrict":"This value should be a valid url.","type-number":"This value should be a valid number.","type-digits":"This value should be digits.","type-dateIso":"This value should be a valid date (YYYY-MM-DD).","type-alphanum":"This value should be alphanumeric.","type-phone":"This value should be a valid phone number.",notnull:"This value should not be null.",notblank:"This value should not be blank.",required:"This value is required.",regexp:"This value seems to be invalid.",min:"This value should be greater than or equal to %s.",max:"This value should be lower than or equal to %s.",range:"This value should be between %s and %s.",minlength:"This value is too short. It should have %s characters or more.",maxlength:"This value is too long. It should have %s characters or less.",rangelength:"This value length is invalid. It should be between %s and %s characters long.",mincheck:"You must select at least %s choices.",maxcheck:"You must select %s choices or less.",rangecheck:"You must select between %s and %s choices.",equalto:"This value should be the same."},common:{subject:"Subject",save:"Save",blocked:"Blocked",cancel:"Cancel",status:"Status","new-bulk":"New bulk insert","one-item-line":"One item per line..."},pagination:{next:"Next",prev:"Previous"},"markdown-editor":{"heading-1":"First Level Heading","heading-2":"Second Level Heading","heading-3":"Third Level Heading",bold:"Bold",italic:"Italic",strike:"Strike","bulleted-list":"Bulleted List","numeric-list":"Numeric List",picture:"Picture",link:"Link",quotes:"Quotes","code-block":"Code Block / Code",preview:"Preview",help:"Help",placeholder:"Your title here...","link-placeholder":"Your text to link here..."},us:{"title-new":"New User Story","team-requirement":"Team Requirement","client-requirement":"Client Requirement"}});
//# sourceMappingURL=app.js.map