]> source.dussan.org Git - gitea.git/commitdiff
able edit issue labels/milestone/assignee
authorUnknwon <u@gogs.io>
Fri, 14 Aug 2015 16:42:43 +0000 (00:42 +0800)
committerUnknwon <u@gogs.io>
Fri, 14 Aug 2015 16:42:43 +0000 (00:42 +0800)
12 files changed:
cmd/web.go
gogs.go
models/issue.go
modules/middleware/context.go
modules/middleware/repo.go
public/css/gogs.min.css
public/js/gogs.js
public/less/_base.less
public/less/_repository.less
routers/repo/issue.go
templates/.VERSION
templates/repo/issue/view_content.tmpl

index 857fd1e2334c01b6e2f7c63a85a9682c0f47e4db..a091c5c69d9c5bee3e564a4bcf75eb9a6d8324d6 100644 (file)
@@ -457,9 +457,9 @@ func runWeb(ctx *cli.Context) {
                                m.Post("", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
                                m.Post("/label", repo.UpdateIssueLabel)
                                m.Post("/milestone", repo.UpdateIssueMilestone)
-                               m.Post("/assignee", repo.UpdateAssignee)
+                               m.Post("/assignee", repo.UpdateIssueAssignee)
                                m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
-                       })
+                       }, reqRepoAdmin)
                })
                m.Group("/labels", func() {
                        m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
diff --git a/gogs.go b/gogs.go
index 038a172d7baa020d5cbb85f2e9c0b050243a9442..d197e32dab7370430f7cdcfb134edf488ae764fb 100644 (file)
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
        "github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.6.4.0814 Beta"
+const APP_VER = "0.6.5.0815 Beta"
 
 func init() {
        runtime.GOMAXPROCS(runtime.NumCPU())
index 7f16f936a3325d44661c7a9a1b650fcaf8bbe49e..712dd6bb2d8484efe12fa4e0bb8cd75e3c391cf3 100644 (file)
@@ -123,13 +123,23 @@ func (i *Issue) HasLabel(labelID int64) bool {
        return i.hasLabel(x, labelID)
 }
 
-func (i *Issue) addLabel(e Engine, labelID int64) error {
-       return newIssueLabel(e, i.ID, labelID)
+func (i *Issue) addLabel(e *xorm.Session, label *Label) error {
+       return newIssueLabel(e, i, label)
 }
 
 // AddLabel adds new label to issue by given ID.
-func (i *Issue) AddLabel(labelID int64) error {
-       return i.addLabel(x, labelID)
+func (i *Issue) AddLabel(label *Label) (err error) {
+       sess := x.NewSession()
+       defer sessionRelease(sess)
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if err = i.addLabel(sess, label); err != nil {
+               return err
+       }
+
+       return sess.Commit()
 }
 
 func (i *Issue) getLabels(e Engine) (err error) {
@@ -149,13 +159,43 @@ func (i *Issue) GetLabels() error {
        return i.getLabels(x)
 }
 
-func (i *Issue) removeLabel(e Engine, labelID int64) error {
-       return deleteIssueLabel(e, i.ID, labelID)
+func (i *Issue) removeLabel(e *xorm.Session, label *Label) error {
+       return deleteIssueLabel(e, i, label)
 }
 
 // RemoveLabel removes a label from issue by given ID.
-func (i *Issue) RemoveLabel(labelID int64) error {
-       return i.removeLabel(x, labelID)
+func (i *Issue) RemoveLabel(label *Label) (err error) {
+       sess := x.NewSession()
+       defer sessionRelease(sess)
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if err = i.removeLabel(sess, label); err != nil {
+               return err
+       }
+
+       return sess.Commit()
+}
+
+func (i *Issue) ClearLabels() (err error) {
+       sess := x.NewSession()
+       defer sessionRelease(sess)
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if err = i.getLabels(sess); err != nil {
+               return err
+       }
+
+       for idx := range i.Labels {
+               if err = i.removeLabel(sess, i.Labels[idx]); err != nil {
+                       return err
+               }
+       }
+
+       return sess.Commit()
 }
 
 func (i *Issue) GetAssignee() (err error) {
@@ -257,10 +297,20 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
                return err
        }
 
+       var label *Label
        for _, id := range labelIDs {
-               if err = issue.addLabel(sess, id); err != nil {
+               if id == 0 {
+                       continue
+               }
+
+               label, err = getLabelByID(sess, id)
+               if err != nil {
+                       return err
+               }
+               if err = issue.addLabel(sess, label); err != nil {
                        return fmt.Errorf("addLabel: %v", err)
                }
+
        }
 
        if issue.MilestoneID > 0 {
@@ -662,28 +712,30 @@ func UpdateIssueUsersByStatus(issueID int64, isClosed bool) error {
        return updateIssueUsersByStatus(x, issueID, isClosed)
 }
 
-func updateIssueUserByAssignee(e *xorm.Session, issueID, assigneeID int64) (err error) {
-       if _, err = e.Exec("UPDATE `issue_user` SET is_assigned=? WHERE issue_id=?", false, issueID); err != nil {
+func updateIssueUserByAssignee(e *xorm.Session, issue *Issue) (err error) {
+       if _, err = e.Exec("UPDATE `issue_user` SET is_assigned=? WHERE issue_id=?", false, issue.ID); err != nil {
                return err
        }
 
        // Assignee ID equals to 0 means clear assignee.
-       if assigneeID == 0 {
-               return nil
+       if issue.AssigneeID > 0 {
+               if _, err = e.Exec("UPDATE `issue_user` SET is_assigned=? WHERE uid=? AND issue_id=?", true, issue.AssigneeID, issue.ID); err != nil {
+                       return err
+               }
        }
-       _, err = e.Exec("UPDATE `issue_user` SET is_assigned=? WHERE uid=? AND issue_id=?", true, assigneeID, issueID)
-       return err
+
+       return updateIssue(e, issue)
 }
 
 // UpdateIssueUserByAssignee updates issue-user relation for assignee.
-func UpdateIssueUserByAssignee(issueID, assigneeID int64) (err error) {
+func UpdateIssueUserByAssignee(issue *Issue) (err error) {
        sess := x.NewSession()
        defer sessionRelease(sess)
        if err = sess.Begin(); err != nil {
                return err
        }
 
-       if err = updateIssueUserByAssignee(sess, issueID, assigneeID); err != nil {
+       if err = updateIssueUserByAssignee(sess, issue); err != nil {
                return err
        }
 
@@ -855,21 +907,34 @@ func HasIssueLabel(issueID, labelID int64) bool {
        return hasIssueLabel(x, issueID, labelID)
 }
 
-func newIssueLabel(e Engine, issueID, labelID int64) error {
-       if issueID == 0 || labelID == 0 {
-               return nil
+func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
+       if _, err = e.Insert(&IssueLabel{
+               IssueID: issue.ID,
+               LabelID: label.ID,
+       }); err != nil {
+               return err
        }
 
-       _, err := e.Insert(&IssueLabel{
-               IssueID: issueID,
-               LabelID: labelID,
-       })
-       return err
+       label.NumIssues++
+       if issue.IsClosed {
+               label.NumClosedIssues++
+       }
+       return updateLabel(e, label)
 }
 
 // NewIssueLabel creates a new issue-label relation.
-func NewIssueLabel(issueID, labelID int64) error {
-       return newIssueLabel(x, issueID, labelID)
+func NewIssueLabel(issue *Issue, label *Label) (err error) {
+       sess := x.NewSession()
+       defer sessionRelease(sess)
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if err = newIssueLabel(sess, issue, label); err != nil {
+               return err
+       }
+
+       return sess.Commit()
 }
 
 func getIssueLabels(e Engine, issueID int64) ([]*IssueLabel, error) {
@@ -882,17 +947,34 @@ func GetIssueLabels(issueID int64) ([]*IssueLabel, error) {
        return getIssueLabels(x, issueID)
 }
 
-func deleteIssueLabel(e Engine, issueID, labelID int64) error {
-       _, err := e.Delete(&IssueLabel{
-               IssueID: issueID,
-               LabelID: labelID,
-       })
-       return err
+func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
+       if _, err = e.Delete(&IssueLabel{
+               IssueID: issue.ID,
+               LabelID: label.ID,
+       }); err != nil {
+               return err
+       }
+
+       label.NumIssues--
+       if issue.IsClosed {
+               label.NumClosedIssues--
+       }
+       return updateLabel(e, label)
 }
 
 // DeleteIssueLabel deletes issue-label relation.
-func DeleteIssueLabel(issueID, labelID int64) error {
-       return deleteIssueLabel(x, issueID, labelID)
+func DeleteIssueLabel(issue *Issue, label *Label) (err error) {
+       sess := x.NewSession()
+       defer sessionRelease(sess)
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if err = deleteIssueLabel(sess, issue, label); err != nil {
+               return err
+       }
+
+       return sess.Commit()
 }
 
 //    _____  .__.__                   __
@@ -966,7 +1048,7 @@ func NewMilestone(m *Milestone) (err error) {
 
 func getMilestoneByID(e Engine, id int64) (*Milestone, error) {
        m := &Milestone{ID: id}
-       has, err := x.Get(m)
+       has, err := e.Get(m)
        if err != nil {
                return nil, err
        } else if !has {
@@ -1127,7 +1209,7 @@ func changeMilestoneAssign(e *xorm.Session, oldMid int64, issue *Issue) error {
        }
 
        if issue.MilestoneID > 0 {
-               m, err := GetMilestoneByID(issue.MilestoneID)
+               m, err := getMilestoneByID(e, issue.MilestoneID)
                if err != nil {
                        return err
                }
@@ -1148,7 +1230,7 @@ func changeMilestoneAssign(e *xorm.Session, oldMid int64, issue *Issue) error {
                }
        }
 
-       return nil
+       return updateIssue(e, issue)
 }
 
 // ChangeMilestoneAssign changes assignment of milestone for issue.
@@ -1162,7 +1244,6 @@ func ChangeMilestoneAssign(oldMid int64, issue *Issue) (err error) {
        if err = changeMilestoneAssign(sess, oldMid, issue); err != nil {
                return err
        }
-
        return sess.Commit()
 }
 
index d4bc8f03512fbe3df17e7701a3276f7fda0dbe0d..9870b415414e9be0726e7402d7f676b8efc05a8d 100644 (file)
@@ -72,9 +72,14 @@ type RepoContext struct {
        Mirror       *models.Mirror
 }
 
-// Return if the current user has write access for this repository
+// IsOwner returns true if current user is the owner of repository.
 func (r RepoContext) IsOwner() bool {
-       return r.AccessMode >= models.ACCESS_MODE_WRITE
+       return r.AccessMode >= models.ACCESS_MODE_OWNER
+}
+
+// IsAdmin returns true if current user has admin or higher access of repository.
+func (r RepoContext) IsAdmin() bool {
+       return r.AccessMode >= models.ACCESS_MODE_ADMIN
 }
 
 // Return if the current user has read access for this repository
index c4c53c03a2442913de55ebfc48c76ece47ba8df8..d3995d29791ffbd49c937155f45c61032b44bea2 100644 (file)
@@ -324,8 +324,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
                ctx.Data["Title"] = u.Name + "/" + repo.Name
                ctx.Data["Repository"] = repo
                ctx.Data["Owner"] = ctx.Repo.Repository.Owner
-               ctx.Data["IsRepositoryOwner"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_WRITE
-               ctx.Data["IsRepositoryAdmin"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_ADMIN
+               ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
+               ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
 
                ctx.Data["DisableSSH"] = setting.DisableSSH
                ctx.Repo.CloneLink, err = repo.CloneLink()
@@ -388,7 +388,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 
 func RequireRepoAdmin() macaron.Handler {
        return func(ctx *Context) {
-               if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN {
+               if !ctx.Repo.IsAdmin() {
                        if !ctx.IsSigned {
                                ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
                                ctx.Redirect(setting.AppSubUrl + "/user/login")
index 43e9ae625446a0eb43d424607c892425cfd78eca..475f935748e82dd8a2157944231227501c08c590 100644 (file)
@@ -1 +1 @@
-@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('embedded-opentype'),url(../fonts/octicons.woff?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('woff'),url(../fonts/octicons.ttf?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('truetype'),url(../fonts/octicons.svg?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6#octicons)format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-alignment-align:before{content:'\f08a'}.octicon-alignment-aligned-to:before{content:'\f08e'}.octicon-alignment-unalign:before{content:'\f08b'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beer:before{content:'\f069'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hourglass:before{content:'\f09e'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-jump-down:before{content:'\f072'}.octicon-jump-left:before{content:'\f0a5'}.octicon-jump-right:before{content:'\f0a6'}.octicon-jump-up:before{content:'\f073'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gist-private:before,.octicon-git-fork-private:before,.octicon-lock:before,.octicon-mirror-private:before{content:'\f06a'}.octicon-logo-github:before{content:'\f092'}.octicon-mail:before{content:'\f03b'}.octicon-mail-read:before{content:'\f03c'}.octicon-mail-reply:before{content:'\f051'}.octicon-mark-github:before{content:'\f00a'}.octicon-markdown:before{content:'\f0c9'}.octicon-megaphone:before{content:'\f077'}.octicon-mention:before{content:'\f0be'}.octicon-microscope:before{content:'\f089'}.octicon-milestone:before{content:'\f075'}.octicon-mirror-public:before,.octicon-mirror:before{content:'\f024'}.octicon-mortar-board:before{content:'\f0d7'}.octicon-move-down:before{content:'\f0a8'}.octicon-move-left:before{content:'\f074'}.octicon-move-right:before{content:'\f0a9'}.octicon-move-up:before{content:'\f0a7'}.octicon-mute:before{content:'\f080'}.octicon-no-newline:before{content:'\f09c'}.octicon-octoface:before{content:'\f008'}.octicon-organization:before{content:'\f037'}.octicon-package:before{content:'\f0c4'}.octicon-paintcan:before{content:'\f0d1'}.octicon-pencil:before{content:'\f058'}.octicon-person-add:before,.octicon-person-follow:before,.octicon-person:before{content:'\f018'}.octicon-pin:before{content:'\f041'}.octicon-playback-fast-forward:before{content:'\f0bd'}.octicon-playback-pause:before{content:'\f0bb'}.octicon-playback-play:before{content:'\f0bf'}.octicon-playback-rewind:before{content:'\f0bc'}.octicon-plug:before{content:'\f0d4'}.octicon-file-add:before,.octicon-file-directory-create:before,.octicon-gist-new:before,.octicon-plus:before,.octicon-repo-create:before{content:'\f05d'}.octicon-podium:before{content:'\f0af'}.octicon-primitive-dot:before{content:'\f052'}.octicon-primitive-square:before{content:'\f053'}.octicon-pulse:before{content:'\f085'}.octicon-puzzle:before{content:'\f0c0'}.octicon-question:before{content:'\f02c'}.octicon-quote:before{content:'\f063'}.octicon-radio-tower:before{content:'\f030'}.octicon-repo-delete:before,.octicon-repo:before{content:'\f001'}.octicon-repo-clone:before{content:'\f04c'}.octicon-repo-force-push:before{content:'\f04a'}.octicon-gist-fork:before,.octicon-repo-forked:before{content:'\f002'}.octicon-repo-pull:before{content:'\f006'}.octicon-repo-push:before{content:'\f005'}.octicon-rocket:before{content:'\f033'}.octicon-rss:before{content:'\f034'}.octicon-ruby:before{content:'\f047'}.octicon-screen-full:before{content:'\f066'}.octicon-screen-normal:before{content:'\f067'}.octicon-search-save:before,.octicon-search:before{content:'\f02e'}.octicon-server:before{content:'\f097'}.octicon-settings:before{content:'\f07c'}.octicon-log-in:before,.octicon-sign-in:before{content:'\f036'}.octicon-log-out:before,.octicon-sign-out:before{content:'\f032'}.octicon-split:before{content:'\f0c6'}.octicon-squirrel:before{content:'\f0b2'}.octicon-star-add:before,.octicon-star-delete:before,.octicon-star:before{content:'\f02a'}.octicon-steps:before{content:'\f0c7'}.octicon-stop:before{content:'\f08f'}.octicon-repo-sync:before,.octicon-sync:before{content:'\f087'}.octicon-tag-add:before,.octicon-tag-remove:before,.octicon-tag:before{content:'\f015'}.octicon-telescope:before{content:'\f088'}.octicon-terminal:before{content:'\f0c8'}.octicon-three-bars:before{content:'\f05e'}.octicon-thumbsdown:before{content:'\f0db'}.octicon-thumbsup:before{content:'\f0da'}.octicon-tools:before{content:'\f031'}.octicon-trashcan:before{content:'\f0d0'}.octicon-triangle-down:before{content:'\f05b'}.octicon-triangle-left:before{content:'\f044'}.octicon-triangle-right:before{content:'\f05a'}.octicon-triangle-up:before{content:'\f0aa'}.octicon-unfold:before{content:'\f039'}.octicon-unmute:before{content:'\f0ba'}.octicon-versions:before{content:'\f064'}.octicon-remove-close:before,.octicon-x:before{content:'\f081'}.octicon-zap:before{content:'\26A1'}body{font-family:'Helvetica Neue',Arial,Helvetica,sans-serif,'ๅพฎ่ฝฏ้›…้ป‘';background-color:#FAFAFA}img{border-radius:3px}.full.height{padding:0;margin:0 0 -80px 0;min-height:100%}.following.bar{z-index:900;left:0;width:100%}.following.bar.light{background-color:#fff;border-bottom:1px solid #DDD;box-shadow:0 2px 3px rgba(0,0,0,.04)}.following.bar .column .menu{margin-top:0}.following.bar .top.menu a.item.brand{padding-left:0}.following.bar .brand .ui.mini.image{width:30px}.following.bar .top.menu .dropdown.item.active,.following.bar .top.menu .dropdown.item:hover,.following.bar .top.menu a.item:hover{background-color:transparent}.following.bar .top.menu a.item:hover{color:rgba(0,0,0,.45)}.following.bar .top.menu .menu{z-index:900}.following.bar .head.link.item{padding-right:0!important}.following.bar .head.link.item .dropdown.icon,.following.bar .head.link.item .menu .octicon{margin-right:5px}.following.bar .avatar>.ui.image{margin-right:0}.following.bar .searchbox{background-color:#f4f4f4!important}.following.bar .searchbox:focus{background-color:#e9e9e9!important}.following.bar .octicon{width:16px;text-align:center}.ui.left{float:left}.ui.right{float:right}.ui .text.red{color:#d95c5c!important}.ui .text.grey{color:#767676!important}.ui .text.grey a{color:#444!important}.ui .text.grey a:hover{color:#000!important}.ui .text.right{text-align:right}.ui .text.small{font-size:.75em}.ui .message{text-align:center}.ui .header>i+.content{padding-left:.75rem;vertical-align:middle}footer{margin-top:40px!important;height:40px;background-color:#fff;border-top:1px solid #d6d6d6;clear:both;width:100%;color:#888}footer .container{padding-top:10px}footer .container .fa{width:16px;text-align:center;color:#428bca}footer .container .ui.language.dropdown{z-index:10000}footer .container .links>*{border-left:1px solid #d6d6d6;padding-left:8px;margin-left:5px}footer .container .links>:first-child{border-left:none}.hide{display:none}.center{text-align:center}.img-1{width:2px!important;height:2px!important}.img-2{width:4px!important;height:4px!important}.img-3{width:6px!important;height:6px!important}.img-4{width:8px!important;height:8px!important}.img-5{width:10px!important;height:10px!important}.img-6{width:12px!important;height:12px!important}.img-7{width:14px!important;height:14px!important}.img-8{width:16px!important;height:16px!important}.img-9{width:18px!important;height:18px!important}.img-10{width:20px!important;height:20px!important}.img-11{width:22px!important;height:22px!important}.img-12{width:24px!important;height:24px!important}.img-13{width:26px!important;height:26px!important}.img-14{width:28px!important;height:28px!important}.img-15{width:30px!important;height:30px!important}.img-16{width:32px!important;height:32px!important}.mega-octicon.icon,.octicon.icon{font-family:octicons}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.markdown{overflow:hidden;font-family:"Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown>:first-child{margin-top:0!important}.markdown>:last-child{margin-bottom:0!important}.markdown a:not([href]){color:inherit;text-decoration:none}.markdown .absent{color:#c00}.markdown .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown .anchor:focus{outline:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown h1 .octicon-link,.markdown h2 .octicon-link,.markdown h3 .octicon-link,.markdown h4 .octicon-link,.markdown h5 .octicon-link,.markdown h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown h1:hover .anchor,.markdown h2:hover .anchor,.markdown h3:hover .anchor,.markdown h4:hover .anchor,.markdown h5:hover .anchor,.markdown h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown h1:hover .anchor .octicon-link,.markdown h2:hover .anchor .octicon-link,.markdown h3:hover .anchor .octicon-link,.markdown h4:hover .anchor .octicon-link,.markdown h5:hover .anchor .octicon-link,.markdown h6:hover .anchor .octicon-link{display:inline-block}.markdown h1 code,.markdown h1 tt,.markdown h2 code,.markdown h2 tt,.markdown h3 code,.markdown h3 tt,.markdown h4 code,.markdown h4 tt,.markdown h5 code,.markdown h5 tt,.markdown h6 code,.markdown h6 tt{font-size:inherit}.markdown h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}.markdown h1 .anchor{line-height:1}.markdown h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}.markdown h2 .anchor{line-height:1}.markdown h3{font-size:1.5em;line-height:1.43}.markdown h3 .anchor{line-height:1.2}.markdown h4{font-size:1.25em}.markdown h4 .anchor{line-height:1.2}.markdown h5{font-size:1em}.markdown h5 .anchor{line-height:1.1}.markdown h6{font-size:1em;color:#777}.markdown h6 .anchor{line-height:1.1}.markdown blockquote,.markdown dl,.markdown ol,.markdown p,.markdown pre,.markdown table,.markdown ul{margin-top:0;margin-bottom:16px}.markdown hr{height:4px;padding:0;margin:16px 0;background-color:#e7e7e7;border:0 none}.markdown ol,.markdown ul{padding-left:2em}.markdown ol.no-list,.markdown ul.no-list{padding:0;list-style-type:none}.markdown ol ol,.markdown ol ul,.markdown ul ol,.markdown ul ul{margin-top:0;margin-bottom:0}.markdown ol ol,.markdown ul ol{list-style-type:lower-roman}.markdown li>p{margin-top:16px}.markdown dl{padding:0}.markdown dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown dl dd{padding:0 16px;margin-bottom:16px}.markdown blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown blockquote>:first-child{margin-top:0}.markdown blockquote>:last-child{margin-bottom:0}.markdown table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown table th{font-weight:700}.markdown table td,.markdown table th{padding:6px 13px!important;border:1px solid #ddd}.markdown table tr{background-color:#fff;border-top:1px solid #ccc}.markdown table tr:nth-child(2n){background-color:#f8f8f8}.markdown img{max-width:100%;box-sizing:border-box}.markdown .emoji{max-width:none}.markdown span.frame{display:block;overflow:hidden}.markdown span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid #ddd}.markdown span.frame span img{display:block;float:left}.markdown span.frame span span{display:block;padding:5px 0 0;clear:both;color:#333}.markdown span.align-center{display:block;overflow:hidden;clear:both}.markdown span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown span.align-center span img{margin:0 auto;text-align:center}.markdown span.align-right{display:block;overflow:hidden;clear:both}.markdown span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown span.align-right span img{margin:0;text-align:right}.markdown span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown span.float-left span{margin:13px 0 0}.markdown span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown code,.markdown tt{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown code:after,.markdown code:before,.markdown tt:after,.markdown tt:before{letter-spacing:-.2em;content:"\00a0"}.markdown code br,.markdown tt br{display:none}.markdown del code{text-decoration:inherit}.markdown pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown .highlight{margin-bottom:16px}.markdown .highlight pre,.markdown pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.markdown .highlight pre{margin-bottom:0;word-break:normal}.markdown pre{word-wrap:normal}.markdown pre code,.markdown pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown pre code:after,.markdown pre code:before,.markdown pre tt:after,.markdown pre tt:before{content:normal}.markdown kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown .csv-data td,.markdown .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown .csv-data .blob-num{padding:10px 8px 9px;text-align:right;background:#fff;border:0}.markdown .csv-data tr{border-top:0}.markdown .csv-data th{font-weight:700;background:#f8f8f8;border-top:0}.pln{color:#333}@media screen{.str{color:#d14}.kwd{color:#333}.com{color:#998;font-style:italic}.typ{color:#458}.lit{color:#458}.pun{color:#333}.opn{color:#333}.clo{color:#333}.tag{color:navy}.atn{color:teal}.atv{color:#d14}.dec{color:#333}.var{color:teal}.fun{color:#900}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:700}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:700}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006;font-weight:700}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}.home{padding-bottom:120px}.home .logo{max-width:250px}.home .hero h1,.home .hero h2{font-family:'PT Sans Narrow',sans-serif}.home .hero h1{font-size:7em}.home .hero h2{font-size:4em}.home .hero .octicon{color:#d9453d;font-size:60px;margin-right:10px}.home .hero.header{font-size:24px}.home p.large{font-size:20px}.home .stackable{padding-top:30px}.home a{color:#d9453d}.install{padding-top:45px;padding-bottom:120px}.install form label{text-align:right;width:40%!important}.install form input{width:35%!important}.install form .field{text-align:left}.install form .field .help{margin-left:41%}.install form .field.optional .title{margin-left:38%}.install .ui .checkbox{margin-left:40%!important}.install .ui .checkbox label{width:auto!important}.form .help{color:#999;padding-top:.6em;padding-bottom:.6em;display:inline-block}.ui.attached.header{background:#f0f0f0}.ui.attached.header .right{margin-top:-5px}.repository.new.fork form{margin:auto;width:800px!important}.repository.new.fork form .ui.message{text-align:center}.repository.new.fork form .header{padding-left:280px!important}.repository.new.fork form .inline.field>label{text-align:right;width:250px!important;word-wrap:break-word}.repository.new.fork form .help{margin-left:260px!important}.repository.new.fork form .dropdown .dropdown.icon{margin-top:-7px!important}.repository.new.fork form .dropdown .text{margin-right:0!important}.repository.new.fork form .dropdown .text i{margin-right:0!important}.repository.new.fork form input,.repository.new.fork form textarea{width:50%!important}.repository{padding-top:15px;padding-bottom:120px}.repository .head .column{padding-top:5px!important;padding-bottom:5px!important}.repository .head .ui.compact.menu{margin-left:1rem}.repository .head .ui.header{margin-top:0}.repository .head .mega-octicon{width:30px;font-size:30px}.repository .head .ui.huge.breadcrumb{font-weight:300;font-size:1.7rem}.repository .head .fork-flag{margin-left:38px;display:block;font-size:11px;line-height:10px;white-space:nowrap}.repository .metas .menu{max-height:300px;overflow-x:auto}.repository .metas .ui.list .ui.avatar.image{border-radius:0}.repository .metas .ui.list .hide{display:none!important}.repository .metas .ui.list .label.color{padding:0 8px;margin-right:5px}.repository .metas .ui.list a{padding-top:5px;padding-right:10px}.repository .metas .ui.list a .text{color:#444}.repository .metas .ui.list a .text:hover{color:#000}.repository .filter.menu .label.color{margin-left:15px;padding:0 8px}.repository .filter.menu .octicon{float:left;margin-left:-5px;margin-right:-7px}.repository .filter.menu .menu{max-height:300px;overflow-x:auto;right:0!important;left:auto!important}.repository .filter.menu .menu .clickable .name{padding-left:15px!important}.repository .page.buttons{padding-top:15px}.repository .issue.list{list-style:none;padding-top:15px}.repository .issue.list>.item{padding-top:15px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .issue.list>.item .title{color:#444;font-size:15px;font-weight:700;margin:0 6px}.repository .issue.list>.item .title:hover{color:#000}.repository .issue.list>.item .comment{padding-right:10px;color:#666}.repository .issue.list>.item .desc{padding-top:5px;color:#999}.repository .issue.list>.item .desc a.milestone{padding-left:5px;color:#999!important}.repository .issue.list>.item .desc a.milestone:hover{color:#000!important}.repository .issue.list>.item .desc .assignee{margin-top:-10px;margin-right:5px}.repository.new.issue .comment.form .comment .avatar{width:3em}.repository.new.issue .comment.form .content{margin-left:4em}.repository.new.issue .comment.form .content .markdown{font-size:14px}.repository.new.issue .comment.form .metas{min-width:220px}.repository.new.issue .comment.form .metas .filter.menu{max-height:300px;overflow-x:auto}.repository.view.issue .title{padding-bottom:0!important}.repository.view.issue .title h1{font-weight:300;font-size:3rem;margin-bottom:5px}.repository.view.issue .title .index{font-weight:300;color:#aaa;letter-spacing:-1px}.repository.view.issue .title .label{margin-right:10px}.repository.view.issue .comment-list:before{display:block;content:"";position:absolute;margin-top:12px;margin-bottom:14px;top:0;bottom:0;left:96px;width:2px;background-color:#f3f3f3;z-index:-1}.repository.view.issue .comment-list .comment .avatar{width:3em}.repository.view.issue .comment-list .comment .tag{color:#767676;margin-top:3px;padding:2px 5px;font-size:12px;border:1px solid rgba(0,0,0,.1);border-radius:3px}.repository.view.issue .comment-list .comment .content{margin-left:4em}.repository.view.issue .comment-list .comment .content .header{font-weight:400;padding:auto 15px;color:#767676;background-color:#f7f7f7;border-bottom:1px solid #eee;border-top-left-radius:3px;border-top-right-radius:3px}.repository.view.issue .comment-list .comment .content .header .text{max-width:78%;padding-top:10px;padding-bottom:10px}.repository.view.issue .comment-list .comment .content .markdown{font-size:14px}.repository.view.issue .comment-list .comment .content .no-content{color:#767676;font-style:italic}.repository.view.issue .comment-list .comment .content>.bottom.segment{background:#f3f4f5}.repository.view.issue .comment-list .comment .content>.bottom.segment .ui.image{max-height:150px}.repository.view.issue .comment-list .comment .ui.form .field:first-child{clear:none}.repository.view.issue .comment-list .comment .ui.form .tab.segment{border:none;padding:0;padding-top:10px}.repository.view.issue .comment-list .comment .ui.form textarea{height:200px}.repository.view.issue .comment-list .event{position:relative;margin:15px 0 15px 79px;padding-left:25px}.repository.view.issue .comment-list .event .octicon{width:30px;float:left;margin-left:-36px;text-align:center}.repository.view.issue .comment-list .event .octicon.octicon-circle-slash{font-size:30px;color:#bd2c00}.repository.view.issue .comment-list .event .octicon.octicon-primitive-dot{font-size:35px;color:#6cc644}.repository.view.issue .ui.segment.metas{margin-top:-3px}.repository .comment.form .ui.comments{margin-top:-12px;max-width:100%}.repository .comment.form .content .field:first-child{clear:none}.repository .comment.form .content .tab.segment{border:none;padding:0;padding-top:10px}.repository .comment.form .content textarea{height:200px}.repository .label.list{list-style:none;padding-top:15px}.repository .label.list .item{padding-top:10px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .label.list .item a{font-size:15px;padding-top:5px;padding-right:10px;color:#666}.repository .label.list .item a:hover{color:#000}.repository .label.list .item a.open-issues{margin-right:30px}.repository .milestone.list{list-style:none;padding-top:15px}.repository .milestone.list>.item{padding-top:10px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .milestone.list>.item>a{padding-top:5px;padding-right:10px;color:#000}.repository .milestone.list>.item>a:hover{color:#4078c0}.repository .milestone.list>.item .ui.progress{width:40%;padding:0;border:0;margin:0}.repository .milestone.list>.item .ui.progress .bar{height:20px}.repository .milestone.list>.item .meta{color:#999;padding-top:5px}.repository .milestone.list>.item .meta .issue-stats .octicon{padding-left:5px}.repository .milestone.list>.item .meta .overdue{color:red}.repository .milestone.list>.item .operate{margin-top:-15px}.repository .milestone.list>.item .operate>a{font-size:15px;padding-top:5px;padding-right:10px;color:#666}.repository .milestone.list>.item .operate>a:hover{color:#000}.repository .milestone.list>.item .content{padding-top:10px}.repository.new.milestone textarea{height:200px}.repository.new.milestone #deadline{width:150px}.repository.compare.pull .choose.branch .octicon{padding-right:10px}.repository .filter.dropdown .menu{margin-top:1px!important}.repository .filter.dropdown .menu .items{max-height:300px;overflow-y:auto}.repository .filter.dropdown .menu .items .item{position:relative;cursor:pointer;display:block;border:none;height:auto;border-top:none;line-height:1em;color:rgba(0,0,0,.8);padding:.71428571em 1.14285714em!important;font-size:1rem;text-transform:none;font-weight:400;box-shadow:none;-webkit-touch-callout:none}.repository .filter.dropdown .menu .items .item.active{font-weight:700}.repository .filter.dropdown .menu .items .item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.8);z-index:13}.ui.comments .dropzone{width:100%;margin-bottom:10px;border:2px dashed #0087F7;box-shadow:none!important}.ui.comments .dropzone .dz-error-message{top:140px}.settings .key.list .item:not(:first-child){border-top:1px solid #eaeaea}.settings .key.list .ssh-key-state-indicator{float:left;color:gray;padding-left:10px;padding-top:10px}.settings .key.list .ssh-key-state-indicator.active{color:#6cc644}.settings .key.list .meta{padding-top:5px}.settings .key.list .print{color:#767676}.settings .key.list .activity{color:#666}.ui.vertical.menu .header.item{font-size:1.1em;background:#f0f0f0}.edit-label.modal .form .column,.new-label.segment .form .column{padding-right:0}.edit-label.modal .form .buttons,.new-label.segment .form .buttons{margin-left:auto;padding-top:15px}.edit-label.modal .form .color.picker.column,.new-label.segment .form .color.picker.column{width:auto}.edit-label.modal .form .color.picker.column .color-picker,.new-label.segment .form .color.picker.column .color-picker{height:35px;width:auto;padding-left:30px}.edit-label.modal .form .minicolors-swatch.minicolors-sprite,.new-label.segment .form .minicolors-swatch.minicolors-sprite{top:10px;left:10px;width:15px;height:15px}.edit-label.modal .form .precolors,.new-label.segment .form .precolors{padding-left:0;padding-right:0;margin:3px 10px auto 10px;width:120px}.edit-label.modal .form .precolors .color,.new-label.segment .form .precolors .color{float:left;width:15px;height:15px}
\ No newline at end of file
+@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('embedded-opentype'),url(../fonts/octicons.woff?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('woff'),url(../fonts/octicons.ttf?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('truetype'),url(../fonts/octicons.svg?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6#octicons)format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-alignment-align:before{content:'\f08a'}.octicon-alignment-aligned-to:before{content:'\f08e'}.octicon-alignment-unalign:before{content:'\f08b'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beer:before{content:'\f069'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hourglass:before{content:'\f09e'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-jump-down:before{content:'\f072'}.octicon-jump-left:before{content:'\f0a5'}.octicon-jump-right:before{content:'\f0a6'}.octicon-jump-up:before{content:'\f073'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gist-private:before,.octicon-git-fork-private:before,.octicon-lock:before,.octicon-mirror-private:before{content:'\f06a'}.octicon-logo-github:before{content:'\f092'}.octicon-mail:before{content:'\f03b'}.octicon-mail-read:before{content:'\f03c'}.octicon-mail-reply:before{content:'\f051'}.octicon-mark-github:before{content:'\f00a'}.octicon-markdown:before{content:'\f0c9'}.octicon-megaphone:before{content:'\f077'}.octicon-mention:before{content:'\f0be'}.octicon-microscope:before{content:'\f089'}.octicon-milestone:before{content:'\f075'}.octicon-mirror-public:before,.octicon-mirror:before{content:'\f024'}.octicon-mortar-board:before{content:'\f0d7'}.octicon-move-down:before{content:'\f0a8'}.octicon-move-left:before{content:'\f074'}.octicon-move-right:before{content:'\f0a9'}.octicon-move-up:before{content:'\f0a7'}.octicon-mute:before{content:'\f080'}.octicon-no-newline:before{content:'\f09c'}.octicon-octoface:before{content:'\f008'}.octicon-organization:before{content:'\f037'}.octicon-package:before{content:'\f0c4'}.octicon-paintcan:before{content:'\f0d1'}.octicon-pencil:before{content:'\f058'}.octicon-person-add:before,.octicon-person-follow:before,.octicon-person:before{content:'\f018'}.octicon-pin:before{content:'\f041'}.octicon-playback-fast-forward:before{content:'\f0bd'}.octicon-playback-pause:before{content:'\f0bb'}.octicon-playback-play:before{content:'\f0bf'}.octicon-playback-rewind:before{content:'\f0bc'}.octicon-plug:before{content:'\f0d4'}.octicon-file-add:before,.octicon-file-directory-create:before,.octicon-gist-new:before,.octicon-plus:before,.octicon-repo-create:before{content:'\f05d'}.octicon-podium:before{content:'\f0af'}.octicon-primitive-dot:before{content:'\f052'}.octicon-primitive-square:before{content:'\f053'}.octicon-pulse:before{content:'\f085'}.octicon-puzzle:before{content:'\f0c0'}.octicon-question:before{content:'\f02c'}.octicon-quote:before{content:'\f063'}.octicon-radio-tower:before{content:'\f030'}.octicon-repo-delete:before,.octicon-repo:before{content:'\f001'}.octicon-repo-clone:before{content:'\f04c'}.octicon-repo-force-push:before{content:'\f04a'}.octicon-gist-fork:before,.octicon-repo-forked:before{content:'\f002'}.octicon-repo-pull:before{content:'\f006'}.octicon-repo-push:before{content:'\f005'}.octicon-rocket:before{content:'\f033'}.octicon-rss:before{content:'\f034'}.octicon-ruby:before{content:'\f047'}.octicon-screen-full:before{content:'\f066'}.octicon-screen-normal:before{content:'\f067'}.octicon-search-save:before,.octicon-search:before{content:'\f02e'}.octicon-server:before{content:'\f097'}.octicon-settings:before{content:'\f07c'}.octicon-log-in:before,.octicon-sign-in:before{content:'\f036'}.octicon-log-out:before,.octicon-sign-out:before{content:'\f032'}.octicon-split:before{content:'\f0c6'}.octicon-squirrel:before{content:'\f0b2'}.octicon-star-add:before,.octicon-star-delete:before,.octicon-star:before{content:'\f02a'}.octicon-steps:before{content:'\f0c7'}.octicon-stop:before{content:'\f08f'}.octicon-repo-sync:before,.octicon-sync:before{content:'\f087'}.octicon-tag-add:before,.octicon-tag-remove:before,.octicon-tag:before{content:'\f015'}.octicon-telescope:before{content:'\f088'}.octicon-terminal:before{content:'\f0c8'}.octicon-three-bars:before{content:'\f05e'}.octicon-thumbsdown:before{content:'\f0db'}.octicon-thumbsup:before{content:'\f0da'}.octicon-tools:before{content:'\f031'}.octicon-trashcan:before{content:'\f0d0'}.octicon-triangle-down:before{content:'\f05b'}.octicon-triangle-left:before{content:'\f044'}.octicon-triangle-right:before{content:'\f05a'}.octicon-triangle-up:before{content:'\f0aa'}.octicon-unfold:before{content:'\f039'}.octicon-unmute:before{content:'\f0ba'}.octicon-versions:before{content:'\f064'}.octicon-remove-close:before,.octicon-x:before{content:'\f081'}.octicon-zap:before{content:'\26A1'}body{font-family:'Helvetica Neue',Arial,Helvetica,sans-serif,'ๅพฎ่ฝฏ้›…้ป‘';background-color:#FAFAFA}img{border-radius:3px}.full.height{padding:0;margin:0 0 -80px 0;min-height:100%}.following.bar{z-index:900;left:0;width:100%}.following.bar.light{background-color:#fff;border-bottom:1px solid #DDD;box-shadow:0 2px 3px rgba(0,0,0,.04)}.following.bar .column .menu{margin-top:0}.following.bar .top.menu a.item.brand{padding-left:0}.following.bar .brand .ui.mini.image{width:30px}.following.bar .top.menu .dropdown.item.active,.following.bar .top.menu .dropdown.item:hover,.following.bar .top.menu a.item:hover{background-color:transparent}.following.bar .top.menu a.item:hover{color:rgba(0,0,0,.45)}.following.bar .top.menu .menu{z-index:900}.following.bar .head.link.item{padding-right:0!important}.following.bar .head.link.item .dropdown.icon,.following.bar .head.link.item .menu .octicon{margin-right:5px}.following.bar .avatar>.ui.image{margin-right:0}.following.bar .searchbox{background-color:#f4f4f4!important}.following.bar .searchbox:focus{background-color:#e9e9e9!important}.following.bar .octicon{width:16px;text-align:center}.ui.left{float:left}.ui.right{float:right}.ui .text.red{color:#d95c5c!important}.ui .text.grey{color:#767676!important}.ui .text.grey a{color:#444!important}.ui .text.grey a:hover{color:#000!important}.ui .text.right{text-align:right}.ui .text.small{font-size:.75em}.ui .message{text-align:center}.ui .header>i+.content{padding-left:.75rem;vertical-align:middle}.ui .avatar.image{border-radius:3px}footer{margin-top:40px!important;height:40px;background-color:#fff;border-top:1px solid #d6d6d6;clear:both;width:100%;color:#888}footer .container{padding-top:10px}footer .container .fa{width:16px;text-align:center;color:#428bca}footer .container .ui.language.dropdown{z-index:10000}footer .container .links>*{border-left:1px solid #d6d6d6;padding-left:8px;margin-left:5px}footer .container .links>:first-child{border-left:none}.hide{display:none}.center{text-align:center}.img-1{width:2px!important;height:2px!important}.img-2{width:4px!important;height:4px!important}.img-3{width:6px!important;height:6px!important}.img-4{width:8px!important;height:8px!important}.img-5{width:10px!important;height:10px!important}.img-6{width:12px!important;height:12px!important}.img-7{width:14px!important;height:14px!important}.img-8{width:16px!important;height:16px!important}.img-9{width:18px!important;height:18px!important}.img-10{width:20px!important;height:20px!important}.img-11{width:22px!important;height:22px!important}.img-12{width:24px!important;height:24px!important}.img-13{width:26px!important;height:26px!important}.img-14{width:28px!important;height:28px!important}.img-15{width:30px!important;height:30px!important}.img-16{width:32px!important;height:32px!important}.mega-octicon.icon,.octicon.icon{font-family:octicons}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.markdown{overflow:hidden;font-family:"Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown>:first-child{margin-top:0!important}.markdown>:last-child{margin-bottom:0!important}.markdown a:not([href]){color:inherit;text-decoration:none}.markdown .absent{color:#c00}.markdown .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown .anchor:focus{outline:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown h1 .octicon-link,.markdown h2 .octicon-link,.markdown h3 .octicon-link,.markdown h4 .octicon-link,.markdown h5 .octicon-link,.markdown h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown h1:hover .anchor,.markdown h2:hover .anchor,.markdown h3:hover .anchor,.markdown h4:hover .anchor,.markdown h5:hover .anchor,.markdown h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown h1:hover .anchor .octicon-link,.markdown h2:hover .anchor .octicon-link,.markdown h3:hover .anchor .octicon-link,.markdown h4:hover .anchor .octicon-link,.markdown h5:hover .anchor .octicon-link,.markdown h6:hover .anchor .octicon-link{display:inline-block}.markdown h1 code,.markdown h1 tt,.markdown h2 code,.markdown h2 tt,.markdown h3 code,.markdown h3 tt,.markdown h4 code,.markdown h4 tt,.markdown h5 code,.markdown h5 tt,.markdown h6 code,.markdown h6 tt{font-size:inherit}.markdown h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}.markdown h1 .anchor{line-height:1}.markdown h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}.markdown h2 .anchor{line-height:1}.markdown h3{font-size:1.5em;line-height:1.43}.markdown h3 .anchor{line-height:1.2}.markdown h4{font-size:1.25em}.markdown h4 .anchor{line-height:1.2}.markdown h5{font-size:1em}.markdown h5 .anchor{line-height:1.1}.markdown h6{font-size:1em;color:#777}.markdown h6 .anchor{line-height:1.1}.markdown blockquote,.markdown dl,.markdown ol,.markdown p,.markdown pre,.markdown table,.markdown ul{margin-top:0;margin-bottom:16px}.markdown hr{height:4px;padding:0;margin:16px 0;background-color:#e7e7e7;border:0 none}.markdown ol,.markdown ul{padding-left:2em}.markdown ol.no-list,.markdown ul.no-list{padding:0;list-style-type:none}.markdown ol ol,.markdown ol ul,.markdown ul ol,.markdown ul ul{margin-top:0;margin-bottom:0}.markdown ol ol,.markdown ul ol{list-style-type:lower-roman}.markdown li>p{margin-top:16px}.markdown dl{padding:0}.markdown dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown dl dd{padding:0 16px;margin-bottom:16px}.markdown blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown blockquote>:first-child{margin-top:0}.markdown blockquote>:last-child{margin-bottom:0}.markdown table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown table th{font-weight:700}.markdown table td,.markdown table th{padding:6px 13px!important;border:1px solid #ddd}.markdown table tr{background-color:#fff;border-top:1px solid #ccc}.markdown table tr:nth-child(2n){background-color:#f8f8f8}.markdown img{max-width:100%;box-sizing:border-box}.markdown .emoji{max-width:none}.markdown span.frame{display:block;overflow:hidden}.markdown span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid #ddd}.markdown span.frame span img{display:block;float:left}.markdown span.frame span span{display:block;padding:5px 0 0;clear:both;color:#333}.markdown span.align-center{display:block;overflow:hidden;clear:both}.markdown span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown span.align-center span img{margin:0 auto;text-align:center}.markdown span.align-right{display:block;overflow:hidden;clear:both}.markdown span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown span.align-right span img{margin:0;text-align:right}.markdown span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown span.float-left span{margin:13px 0 0}.markdown span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown code,.markdown tt{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown code:after,.markdown code:before,.markdown tt:after,.markdown tt:before{letter-spacing:-.2em;content:"\00a0"}.markdown code br,.markdown tt br{display:none}.markdown del code{text-decoration:inherit}.markdown pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown .highlight{margin-bottom:16px}.markdown .highlight pre,.markdown pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.markdown .highlight pre{margin-bottom:0;word-break:normal}.markdown pre{word-wrap:normal}.markdown pre code,.markdown pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown pre code:after,.markdown pre code:before,.markdown pre tt:after,.markdown pre tt:before{content:normal}.markdown kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown .csv-data td,.markdown .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown .csv-data .blob-num{padding:10px 8px 9px;text-align:right;background:#fff;border:0}.markdown .csv-data tr{border-top:0}.markdown .csv-data th{font-weight:700;background:#f8f8f8;border-top:0}.pln{color:#333}@media screen{.str{color:#d14}.kwd{color:#333}.com{color:#998;font-style:italic}.typ{color:#458}.lit{color:#458}.pun{color:#333}.opn{color:#333}.clo{color:#333}.tag{color:navy}.atn{color:teal}.atv{color:#d14}.dec{color:#333}.var{color:teal}.fun{color:#900}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:700}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:700}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006;font-weight:700}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}.home{padding-bottom:120px}.home .logo{max-width:250px}.home .hero h1,.home .hero h2{font-family:'PT Sans Narrow',sans-serif}.home .hero h1{font-size:7em}.home .hero h2{font-size:4em}.home .hero .octicon{color:#d9453d;font-size:60px;margin-right:10px}.home .hero.header{font-size:24px}.home p.large{font-size:20px}.home .stackable{padding-top:30px}.home a{color:#d9453d}.install{padding-top:45px;padding-bottom:120px}.install form label{text-align:right;width:40%!important}.install form input{width:35%!important}.install form .field{text-align:left}.install form .field .help{margin-left:41%}.install form .field.optional .title{margin-left:38%}.install .ui .checkbox{margin-left:40%!important}.install .ui .checkbox label{width:auto!important}.form .help{color:#999;padding-top:.6em;padding-bottom:.6em;display:inline-block}.ui.attached.header{background:#f0f0f0}.ui.attached.header .right{margin-top:-5px}.repository.new.fork form{margin:auto;width:800px!important}.repository.new.fork form .ui.message{text-align:center}.repository.new.fork form .header{padding-left:280px!important}.repository.new.fork form .inline.field>label{text-align:right;width:250px!important;word-wrap:break-word}.repository.new.fork form .help{margin-left:260px!important}.repository.new.fork form .dropdown .dropdown.icon{margin-top:-7px!important}.repository.new.fork form .dropdown .text{margin-right:0!important}.repository.new.fork form .dropdown .text i{margin-right:0!important}.repository.new.fork form input,.repository.new.fork form textarea{width:50%!important}.repository{padding-top:15px;padding-bottom:120px}.repository .head .column{padding-top:5px!important;padding-bottom:5px!important}.repository .head .ui.compact.menu{margin-left:1rem}.repository .head .ui.header{margin-top:0}.repository .head .mega-octicon{width:30px;font-size:30px}.repository .head .ui.huge.breadcrumb{font-weight:300;font-size:1.7rem}.repository .head .fork-flag{margin-left:38px;display:block;font-size:11px;line-height:10px;white-space:nowrap}.repository .metas .menu{max-height:300px;overflow-x:auto}.repository .metas .ui.list .hide{display:none!important}.repository .metas .ui.list .label.color{padding:0 8px;margin-right:5px}.repository .metas .ui.list a{padding-top:5px;padding-right:10px}.repository .metas .ui.list a .text{color:#444}.repository .metas .ui.list a .text:hover{color:#000}.repository .filter.menu .label.color{margin-left:15px;padding:0 8px}.repository .filter.menu .octicon{float:left;margin-left:-5px;margin-right:-7px}.repository .filter.menu .menu{max-height:300px;overflow-x:auto;right:0!important;left:auto!important}.repository .filter.menu .menu .clickable .name{padding-left:15px!important}.repository .page.buttons{padding-top:15px}.repository .issue.list{list-style:none;padding-top:15px}.repository .issue.list>.item{padding-top:15px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .issue.list>.item .title{color:#444;font-size:15px;font-weight:700;margin:0 6px}.repository .issue.list>.item .title:hover{color:#000}.repository .issue.list>.item .comment{padding-right:10px;color:#666}.repository .issue.list>.item .desc{padding-top:5px;color:#999}.repository .issue.list>.item .desc a.milestone{padding-left:5px;color:#999!important}.repository .issue.list>.item .desc a.milestone:hover{color:#000!important}.repository .issue.list>.item .desc .assignee{margin-top:-5px;margin-right:5px}.repository.new.issue .comment.form .comment .avatar{width:3em}.repository.new.issue .comment.form .content{margin-left:4em}.repository.new.issue .comment.form .content .markdown{font-size:14px}.repository.new.issue .comment.form .metas{min-width:220px}.repository.new.issue .comment.form .metas .filter.menu{max-height:300px;overflow-x:auto}.repository.view.issue .title{padding-bottom:0!important}.repository.view.issue .title h1{font-weight:300;font-size:3rem;margin-bottom:5px}.repository.view.issue .title .index{font-weight:300;color:#aaa;letter-spacing:-1px}.repository.view.issue .title .label{margin-right:10px}.repository.view.issue .comment-list:before{display:block;content:"";position:absolute;margin-top:12px;margin-bottom:14px;top:0;bottom:0;left:96px;width:2px;background-color:#f3f3f3;z-index:-1}.repository.view.issue .comment-list .comment .avatar{width:3em}.repository.view.issue .comment-list .comment .tag{color:#767676;margin-top:3px;padding:2px 5px;font-size:12px;border:1px solid rgba(0,0,0,.1);border-radius:3px}.repository.view.issue .comment-list .comment .content{margin-left:4em}.repository.view.issue .comment-list .comment .content .header{font-weight:400;padding:auto 15px;color:#767676;background-color:#f7f7f7;border-bottom:1px solid #eee;border-top-left-radius:3px;border-top-right-radius:3px}.repository.view.issue .comment-list .comment .content .header .text{max-width:78%;padding-top:10px;padding-bottom:10px}.repository.view.issue .comment-list .comment .content .markdown{font-size:14px}.repository.view.issue .comment-list .comment .content .no-content{color:#767676;font-style:italic}.repository.view.issue .comment-list .comment .content>.bottom.segment{background:#f3f4f5}.repository.view.issue .comment-list .comment .content>.bottom.segment .ui.image{max-height:150px}.repository.view.issue .comment-list .comment .ui.form .field:first-child{clear:none}.repository.view.issue .comment-list .comment .ui.form .tab.segment{border:none;padding:0;padding-top:10px}.repository.view.issue .comment-list .comment .ui.form textarea{height:200px}.repository.view.issue .comment-list .event{position:relative;margin:15px 0 15px 79px;padding-left:25px}.repository.view.issue .comment-list .event .octicon{width:30px;float:left;margin-left:-36px;text-align:center}.repository.view.issue .comment-list .event .octicon.octicon-circle-slash{font-size:30px;color:#bd2c00}.repository.view.issue .comment-list .event .octicon.octicon-primitive-dot{font-size:35px;color:#6cc644}.repository.view.issue .ui.segment.metas{margin-top:-3px}.repository .comment.form .ui.comments{margin-top:-12px;max-width:100%}.repository .comment.form .content .field:first-child{clear:none}.repository .comment.form .content .tab.segment{border:none;padding:0;padding-top:10px}.repository .comment.form .content textarea{height:200px}.repository .label.list{list-style:none;padding-top:15px}.repository .label.list .item{padding-top:10px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .label.list .item a{font-size:15px;padding-top:5px;padding-right:10px;color:#666}.repository .label.list .item a:hover{color:#000}.repository .label.list .item a.open-issues{margin-right:30px}.repository .milestone.list{list-style:none;padding-top:15px}.repository .milestone.list>.item{padding-top:10px;padding-bottom:10px;border-bottom:1px dashed #AAA}.repository .milestone.list>.item>a{padding-top:5px;padding-right:10px;color:#000}.repository .milestone.list>.item>a:hover{color:#4078c0}.repository .milestone.list>.item .ui.progress{width:40%;padding:0;border:0;margin:0}.repository .milestone.list>.item .ui.progress .bar{height:20px}.repository .milestone.list>.item .meta{color:#999;padding-top:5px}.repository .milestone.list>.item .meta .issue-stats .octicon{padding-left:5px}.repository .milestone.list>.item .meta .overdue{color:red}.repository .milestone.list>.item .operate{margin-top:-15px}.repository .milestone.list>.item .operate>a{font-size:15px;padding-top:5px;padding-right:10px;color:#666}.repository .milestone.list>.item .operate>a:hover{color:#000}.repository .milestone.list>.item .content{padding-top:10px}.repository.new.milestone textarea{height:200px}.repository.new.milestone #deadline{width:150px}.repository.compare.pull .choose.branch .octicon{padding-right:10px}.repository .filter.dropdown .menu{margin-top:1px!important}.repository .filter.dropdown .menu .items{max-height:300px;overflow-y:auto}.repository .filter.dropdown .menu .items .item{position:relative;cursor:pointer;display:block;border:none;height:auto;border-top:none;line-height:1em;color:rgba(0,0,0,.8);padding:.71428571em 1.14285714em!important;font-size:1rem;text-transform:none;font-weight:400;box-shadow:none;-webkit-touch-callout:none}.repository .filter.dropdown .menu .items .item.active{font-weight:700}.repository .filter.dropdown .menu .items .item:hover{background:rgba(0,0,0,.05);color:rgba(0,0,0,.8);z-index:13}.ui.comments .dropzone{width:100%;margin-bottom:10px;border:2px dashed #0087F7;box-shadow:none!important}.ui.comments .dropzone .dz-error-message{top:140px}.settings .key.list .item:not(:first-child){border-top:1px solid #eaeaea}.settings .key.list .ssh-key-state-indicator{float:left;color:gray;padding-left:10px;padding-top:10px}.settings .key.list .ssh-key-state-indicator.active{color:#6cc644}.settings .key.list .meta{padding-top:5px}.settings .key.list .print{color:#767676}.settings .key.list .activity{color:#666}.ui.vertical.menu .header.item{font-size:1.1em;background:#f0f0f0}.edit-label.modal .form .column,.new-label.segment .form .column{padding-right:0}.edit-label.modal .form .buttons,.new-label.segment .form .buttons{margin-left:auto;padding-top:15px}.edit-label.modal .form .color.picker.column,.new-label.segment .form .color.picker.column{width:auto}.edit-label.modal .form .color.picker.column .color-picker,.new-label.segment .form .color.picker.column .color-picker{height:35px;width:auto;padding-left:30px}.edit-label.modal .form .minicolors-swatch.minicolors-sprite,.new-label.segment .form .minicolors-swatch.minicolors-sprite{top:10px;left:10px;width:15px;height:15px}.edit-label.modal .form .precolors,.new-label.segment .form .precolors{padding-left:0;padding-right:0;margin:3px 10px auto 10px;width:120px}.edit-label.modal .form .precolors .color,.new-label.segment .form .precolors .color{float:left;width:15px;height:15px}
\ No newline at end of file
index 53908a2eb2318e5f72d4bab0009e89c69d777eae..4bae588d19da8c9a56095b3d8058da46fc28e845 100644 (file)
@@ -26,13 +26,30 @@ function initCommentForm() {
     // Labels
     var $list = $('.ui.labels.list');
     var $no_select = $list.find('.no-select');
-    $('.select-label .menu .item:not(.no-select)').click(function () {
+    var $label_menu = $('.select-label .menu');
+    var has_label_update_action = $label_menu.data('action') == 'update';
+
+    function updateIssueMeta(url, action, id) {
+        $.post(url, {
+            "_csrf": csrf,
+            "action": action,
+            "id": id
+        });
+    }
+
+    $label_menu.find('.item:not(.no-select)').click(function () {
         if ($(this).hasClass('checked')) {
             $(this).removeClass('checked')
             $(this).find('.octicon').removeClass('octicon-check')
+            if (has_label_update_action) {
+                updateIssueMeta($label_menu.data('update-url'), "detach", $(this).data('id'));
+            }
         } else {
             $(this).addClass('checked')
             $(this).find('.octicon').addClass('octicon-check')
+            if (has_label_update_action) {
+                updateIssueMeta($label_menu.data('update-url'), "attach", $(this).data('id'));
+            }
         }
 
         var label_ids = "";
@@ -52,7 +69,11 @@ function initCommentForm() {
         $($(this).parent().data('id')).val(label_ids);
         return false;
     });
-    $('.select-label .menu .no-select.item').click(function () {
+    $label_menu.find('.no-select.item').click(function () {
+        if (has_label_update_action) {
+            updateIssueMeta($label_menu.data('update-url'), "clear", '');
+        }
+
         $(this).parent().find('.item').each(function () {
             $(this).removeClass('checked');
             $(this).find('.octicon').removeClass('octicon-check');
@@ -68,12 +89,17 @@ function initCommentForm() {
     function selectItem(select_id, input_id) {
         var $menu = $(select_id + ' .menu');
         var $list = $('.ui' + select_id + '.list')
+        var has_update_action = $menu.data('action') == 'update';
+
         $menu.find('.item:not(.no-select)').click(function () {
             $(this).parent().find('.item').each(function () {
                 $(this).removeClass('selected active')
             });
 
             $(this).addClass('selected active');
+            if (has_update_action) {
+                updateIssueMeta($menu.data('update-url'), '', $(this).data('id'));
+            }
             switch (input_id) {
                 case '#milestone_id':
                     $list.find('.selected').html('<a class="item" href=' + $(this).data('href') + '>' +
@@ -92,6 +118,11 @@ function initCommentForm() {
                 $(this).removeClass('selected active')
             });
 
+
+            if (has_update_action) {
+                updateIssueMeta($menu.data('update-url'), '', '');
+            }
+
             $list.find('.selected').html('');
             $list.find('.no-select').removeClass('hide');
             $(input_id).val('');
@@ -235,6 +266,14 @@ function initRepository() {
 $(document).ready(function () {
     csrf = $('meta[name=_csrf]').attr("content");
 
+    // Show exact time
+    $('.time-since').each(function () {
+        $(this).addClass('poping up').
+            attr('data-content', $(this).attr('title')).
+            attr('data-variation', 'inverted tiny').
+            attr('title', '');
+    });
+
     // Semantic UI modules.
     $('.dropdown').dropdown();
     $('.jump.dropdown').dropdown({
index f95cfdbcec20d132154b2d7c479a1e8752bada05..8f80e0d4926d987baf5d0b29a0e7176ccc1c04c1 100644 (file)
@@ -99,6 +99,10 @@ img {
                padding-left: 0.75rem;
                vertical-align: middle;
        }
+
+       .avatar.image {
+               border-radius: 3px;
+       }
 }
 
 footer {
index 08c8e44d2d377fea5abb368e56c35a3552236b65..22ad278a1725a66b3ddc683057c112bc787a30b1 100644 (file)
@@ -38,9 +38,6 @@
            overflow-x: auto;
                }
                .ui.list {
-                       .ui.avatar.image {
-                               border-radius: 0;
-                       }
                        .hide {
                                display: none!important;
                        }
                                        }
                                }
                                .assignee {
-                                       margin-top: -10px;
+                                       margin-top: -5px;
                                        margin-right: 5px;
                                }
                        }
index c4903a929f630de4d02a3c6d2f1320e1895853fa..d992cecc530a83f8c73f32aeed3c1d5a71b02f78 100644 (file)
@@ -184,7 +184,7 @@ func NewIssue(ctx *middleware.Context) {
        ctx.Data["RequireDropzone"] = true
        renderAttachmentSettings(ctx)
 
-       if ctx.User.IsAdmin {
+       if ctx.Repo.IsAdmin() {
                var (
                        repo = ctx.Repo.Repository
                        err  error
@@ -229,7 +229,7 @@ func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
                assigneeID  int64
                attachments []string
        )
-       if ctx.User.IsAdmin {
+       if ctx.Repo.IsAdmin() {
                // Check labels.
                labelIDs = base.StringsToInt64s(strings.Split(form.LabelIDs, ","))
                labelIDMark := base.Int64sToMap(labelIDs)
@@ -399,17 +399,6 @@ func UploadIssueAttachment(ctx *middleware.Context) {
        })
 }
 
-func checkLabels(labels, allLabels []*models.Label) {
-       for _, l := range labels {
-               for _, l2 := range allLabels {
-                       if l.ID == l2.ID {
-                               l2.IsChecked = true
-                               break
-                       }
-               }
-       }
-}
-
 func ViewIssue(ctx *middleware.Context) {
        ctx.Data["PageIsIssueList"] = true
        ctx.Data["RequireDropzone"] = true
@@ -432,11 +421,52 @@ func ViewIssue(ctx *middleware.Context) {
        }
        issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
 
+       repo := ctx.Repo.Repository
+
        // Metas.
+       // Check labels.
        if err = issue.GetLabels(); err != nil {
                ctx.Handle(500, "GetLabels", err)
                return
        }
+       labelIDMark := make(map[int64]bool)
+       for i := range issue.Labels {
+               labelIDMark[issue.Labels[i].ID] = true
+       }
+       labels, err := models.GetLabelsByRepoID(repo.ID)
+       if err != nil {
+               ctx.Handle(500, "GetLabelsByRepoID: %v", err)
+               return
+       }
+       hasSelected := false
+       for i := range labels {
+               if labelIDMark[labels[i].ID] {
+                       labels[i].IsChecked = true
+                       hasSelected = true
+               }
+       }
+       ctx.Data["HasSelectedLabel"] = hasSelected
+       ctx.Data["Labels"] = labels
+
+       // Check milestone and assignee.
+       if ctx.Repo.IsAdmin() {
+               ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
+               if err != nil {
+                       ctx.Handle(500, "GetMilestones: %v", err)
+                       return
+               }
+               ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
+               if err != nil {
+                       ctx.Handle(500, "GetMilestones: %v", err)
+                       return
+               }
+
+               ctx.Data["Assignees"], err = repo.GetAssignees()
+               if err != nil {
+                       ctx.Handle(500, "GetAssignees: %v", err)
+                       return
+               }
+       }
 
        if ctx.IsSigned {
                // Update issue-user.
@@ -444,39 +474,9 @@ func ViewIssue(ctx *middleware.Context) {
                        ctx.Handle(500, "ReadBy", err)
                        return
                }
-
-               if ctx.User.IsAdmin {
-                       // labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID)
-                       // if err != nil {
-                       //      ctx.Handle(500, "GetLabels.2", err)
-                       //      return
-                       // }
-                       // checkLabels(issue.Labels, labels)
-                       // ctx.Data["Labels"] = labels
-
-                       // // Get all milestones.
-                       // ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
-                       // if err != nil {
-                       //      ctx.Handle(500, "GetMilestones.1: %v", err)
-                       //      return
-                       // }
-                       // ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
-                       // if err != nil {
-                       //      ctx.Handle(500, "GetMilestones.2: %v", err)
-                       //      return
-                       // }
-
-                       // // Get all collaborators.
-                       // ctx.Data["Collaborators"], err = ctx.Repo.Repository.GetCollaborators()
-                       // if err != nil {
-                       //      ctx.Handle(500, "GetCollaborators", err)
-                       //      return
-                       // }
-               }
        }
 
        var (
-               repo    = ctx.Repo.Repository
                tag     models.CommentTag
                ok      bool
                marked  = make(map[int64]models.CommentTag)
@@ -555,112 +555,68 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
        })
 }
 
-func UpdateIssueLabel(ctx *middleware.Context) {
-       if !ctx.Repo.IsOwner() {
-               ctx.Error(403)
-               return
-       }
-
-       idx := com.StrTo(ctx.Params(":index")).MustInt64()
-       if idx <= 0 {
-               ctx.Error(404)
-               return
-       }
-
-       issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, idx)
+func getActionIssue(ctx *middleware.Context) *models.Issue {
+       issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
        if err != nil {
                if models.IsErrIssueNotExist(err) {
-                       ctx.Handle(404, "issue.UpdateIssueLabel(GetIssueByIndex)", err)
+                       ctx.Error(404, "GetIssueByIndex")
                } else {
-                       ctx.Handle(500, "issue.UpdateIssueLabel(GetIssueByIndex)", err)
+                       ctx.Handle(500, "GetIssueByIndex", err)
                }
-               return
+               return nil
        }
+       return issue
+}
 
-       isAttach := ctx.Query("action") == "attach"
-       labelStrId := ctx.Query("id")
-       labelID := com.StrTo(labelStrId).MustInt64()
-       label, err := models.GetLabelByID(labelID)
-       if err != nil {
-               if models.IsErrLabelNotExist(err) {
-                       ctx.Handle(404, "issue.UpdateIssueLabel(GetLabelById)", err)
-               } else {
-                       ctx.Handle(500, "issue.UpdateIssueLabel(GetLabelById)", err)
-               }
+func UpdateIssueLabel(ctx *middleware.Context) {
+       issue := getActionIssue(ctx)
+       if ctx.Written() {
                return
        }
 
-       isNeedUpdate := false
-       if isAttach {
-               if !issue.HasLabel(labelID) {
-                       if err = issue.AddLabel(labelID); err != nil {
-                               ctx.Handle(500, "AddLabel", err)
-                               return
-                       }
-                       isNeedUpdate = true
+       if ctx.Query("action") == "clear" {
+               if err := issue.ClearLabels(); err != nil {
+                       ctx.Handle(500, "ClearLabels", err)
+                       return
                }
        } else {
-               if issue.HasLabel(labelID) {
-                       if err = issue.RemoveLabel(labelID); err != nil {
-                               ctx.Handle(500, "RemoveLabel", err)
-                               return
+               isAttach := ctx.Query("action") == "attach"
+               label, err := models.GetLabelByID(ctx.QueryInt64("id"))
+               if err != nil {
+                       if models.IsErrLabelNotExist(err) {
+                               ctx.Error(404, "GetLabelByID")
+                       } else {
+                               ctx.Handle(500, "GetLabelByID", err)
                        }
-                       isNeedUpdate = true
-               }
-       }
-
-       if isNeedUpdate {
-               if err = models.UpdateIssue(issue); err != nil {
-                       ctx.Handle(500, "issue.UpdateIssueLabel(UpdateIssue)", err)
                        return
                }
 
-               if isAttach {
-                       label.NumIssues++
-                       if issue.IsClosed {
-                               label.NumClosedIssues++
+               if isAttach && !issue.HasLabel(label.ID) {
+                       if err = issue.AddLabel(label); err != nil {
+                               ctx.Handle(500, "AddLabel", err)
+                               return
                        }
-               } else {
-                       label.NumIssues--
-                       if issue.IsClosed {
-                               label.NumClosedIssues--
+               } else if !isAttach && issue.HasLabel(label.ID) {
+                       if err = issue.RemoveLabel(label); err != nil {
+                               ctx.Handle(500, "RemoveLabel", err)
+                               return
                        }
                }
-
-               if err = models.UpdateLabel(label); err != nil {
-                       ctx.Handle(500, "issue.UpdateIssueLabel(UpdateLabel)", err)
-                       return
-               }
        }
+
        ctx.JSON(200, map[string]interface{}{
                "ok": true,
        })
 }
 
 func UpdateIssueMilestone(ctx *middleware.Context) {
-       if !ctx.Repo.IsOwner() {
-               ctx.Error(403)
-               return
-       }
-
-       issueId := com.StrTo(ctx.Query("issue")).MustInt64()
-       if issueId == 0 {
-               ctx.Error(404)
-               return
-       }
-
-       issue, err := models.GetIssueByID(issueId)
-       if err != nil {
-               if models.IsErrIssueNotExist(err) {
-                       ctx.Handle(404, "issue.UpdateIssueMilestone(GetIssueByID)", err)
-               } else {
-                       ctx.Handle(500, "issue.UpdateIssueMilestone(GetIssueByID)", err)
-               }
+       issue := getActionIssue(ctx)
+       if ctx.Written() {
                return
        }
 
        oldMid := issue.MilestoneID
-       mid := com.StrTo(ctx.Query("milestoneid")).MustInt64()
+       mid := ctx.QueryInt64("id")
        if oldMid == mid {
                ctx.JSON(200, map[string]interface{}{
                        "ok": true,
@@ -670,11 +626,8 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
 
        // Not check for invalid milestone id and give responsibility to owners.
        issue.MilestoneID = mid
-       if err = models.ChangeMilestoneAssign(oldMid, issue); err != nil {
-               ctx.Handle(500, "issue.UpdateIssueMilestone(ChangeMilestoneAssign)", err)
-               return
-       } else if err = models.UpdateIssue(issue); err != nil {
-               ctx.Handle(500, "issue.UpdateIssueMilestone(UpdateIssue)", err)
+       if err := models.ChangeMilestoneAssign(oldMid, issue); err != nil {
+               ctx.Handle(500, "ChangeMilestoneAssign", err)
                return
        }
 
@@ -683,36 +636,24 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
        })
 }
 
-func UpdateAssignee(ctx *middleware.Context) {
-       if !ctx.Repo.IsOwner() {
-               ctx.Error(403)
+func UpdateIssueAssignee(ctx *middleware.Context) {
+       issue := getActionIssue(ctx)
+       if ctx.Written() {
                return
        }
 
-       issueId := com.StrTo(ctx.Query("issue")).MustInt64()
-       if issueId == 0 {
-               ctx.Error(404)
-               return
-       }
-
-       issue, err := models.GetIssueByID(issueId)
-       if err != nil {
-               if models.IsErrIssueNotExist(err) {
-                       ctx.Handle(404, "GetIssueByID", err)
-               } else {
-                       ctx.Handle(500, "GetIssueByID", err)
-               }
+       aid := ctx.QueryInt64("id")
+       if issue.AssigneeID == aid {
+               ctx.JSON(200, map[string]interface{}{
+                       "ok": true,
+               })
                return
        }
 
-       aid := com.StrTo(ctx.Query("assigneeid")).MustInt64()
        // Not check for invalid assignee id and give responsibility to owners.
        issue.AssigneeID = aid
-       if err = models.UpdateIssueUserByAssignee(issue.ID, aid); err != nil {
-               ctx.Handle(500, "UpdateIssueUserPairByAssignee: %v", err)
-               return
-       } else if err = models.UpdateIssue(issue); err != nil {
-               ctx.Handle(500, "UpdateIssue", err)
+       if err := models.UpdateIssueUserByAssignee(issue); err != nil {
+               ctx.Handle(500, "UpdateIssueUserByAssignee: %v", err)
                return
        }
 
index 6824b8df908bf5e9707b7dc18b6b3767b39eae6d..2b9aa5b037745f912dd7e8eb425fd7b1f153d424 100644 (file)
@@ -1 +1 @@
-0.6.4.0814 Beta
\ No newline at end of file
+0.6.5.0815 Beta
\ No newline at end of file
index e6e4e1a720f0cdac37b70013cedefce3b2cc5bbb..d3680275913f743f26e74f284ca950f83ec53a97 100644 (file)
@@ -13,7 +13,7 @@
                {{end}}
                {{ $createdStr:= TimeSince .Issue.Created $.Lang }}
                <span class="time-desc">
-                       {{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.Name|Str2html}}
+                       {{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.Name | Safe}}
                        ยท
                        {{$.i18n.Tr "repo.issues.num_comments" .Issue.NumComments}}
                </span>
 
        <div class="four wide column">
                <div class="ui segment metas">
-                       <input id="label_ids" name="label_ids" type="hidden" value="{{.label_ids}}">
-                       <div class="ui {{if not .Labels}}disabled{{end}} jump select-label dropdown">
+                       <div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} jump select-label dropdown">
                                <span class="text">
                                        <strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong>
                                        <span class="octicon octicon-gear"></span>
                                </span>
-        <div class="filter menu" data-id="#label_ids">
+        <div class="filter menu" data-action="update" data-update-url="{{$.RepoLink}}/issues/{{$.Issue.Index}}/label">
                <div class="no-select item">{{.i18n.Tr "repo.issues.new.clear_labels"}}</div>
                {{range .Labels}}
                <a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" data-id-selector="#label_{{.ID}}"><span class="octicon {{if .IsChecked}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
                                </div>
                        </div>
                        <div class="ui labels list">
-                               {{if not .Issue.Labels}}
                                <span class="no-select item {{if .HasSelectedLabel}}hide{{end}}">{{.i18n.Tr "repo.issues.new.no_label"}}</span>
-                               {{else}}
-       {{range .Issue.Labels}}
-       <a class="item" id="label_{{.ID}}" href="{{$.RepoLink}}/issues?labels={{.ID}}"><span class="label color" style="background-color: {{.Color}}"></span> <span class="text">{{.Name}}</span></a>
-        {{end}}
+       {{range .Labels}}
+       <a class="{{if not .IsChecked}}hide{{end}} item" id="label_{{.ID}}" href="{{$.RepoLink}}/issues?labels={{.ID}}"><span class="label color" style="background-color: {{.Color}}"></span> <span class="text">{{.Name}}</span></a>
         {{end}}
                        </div>
 
                        <div class="ui divider"></div>
 
-                       <input id="milestone_id" name="milestone_id" type="hidden" value="{{.milestone_id}}">
-                       <div class="ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} jump select-milestone dropdown">
+                       <div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} jump select-milestone dropdown">
                                <span class="text">
                                        <strong>{{.i18n.Tr "repo.issues.new.milestone"}}</strong>
                                        <span class="octicon octicon-gear"></span>
                                </span>
-        <div class="menu">
+        <div class="menu" data-action="update" data-update-url="{{$.RepoLink}}/issues/{{$.Issue.Index}}/milestone">
                <div class="no-select item">{{.i18n.Tr "repo.issues.new.clear_milestone"}}</div>
                {{if .OpenMilestones}}
                <div class="divider"></div>
                        <div class="ui divider"></div>
 
                        <input id="assignee_id" name="assignee_id" type="hidden" value="{{.assignee_id}}">
-                       <div class="ui {{if not .Assignees}}disabled{{end}} jump select-assignee dropdown">
+                       <div class="ui {{if not .IsRepositoryAdmin}}disabled{{end}} jump select-assignee dropdown">
                                <span class="text">
                                        <strong>{{.i18n.Tr "repo.issues.new.assignee"}}</strong>
                                        <span class="octicon octicon-gear"></span>
                                </span>
-        <div class="menu">
+        <div class="menu" data-action="update" data-update-url="{{$.RepoLink}}/issues/{{$.Issue.Index}}/assignee">
                <div class="no-select item">{{.i18n.Tr "repo.issues.new.clear_assignee"}}</div>
                {{range .Assignees}}
                <div class="item" data-id="{{.Id}}" data-href="{{.HomeLink}}" data-avatar="{{.AvatarLink}}"><img src="{{.AvatarLink}}"> {{.Name}}</div>