diff --git a/cmd/serve.go b/cmd/serve.go index 559d6df13..ef9b451d3 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -17,11 +17,11 @@ import ( git "github.com/gogits/git-module" gouuid "github.com/satori/go.uuid" "github.com/urfave/cli" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/httplib" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -42,7 +42,15 @@ var CmdServ = cli.Command{ func setup(logPath string) { setting.NewContext() setting.NewService() - log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) + log.New(log.FILE, log.FileConfig{ + Filename: filepath.Join(setting.LogRootPath, logPath), + FileRotationConfig: log.FileRotationConfig{ + Rotate: true, + Daily: true, + MaxDays: 3, + }, + }) + log.Delete(log.CONSOLE) // Remove primary logger models.LoadConfigs() @@ -95,11 +103,10 @@ func fail(userMessage, logMessage string, args ...interface{}) { if !setting.ProdMode { fmt.Fprintf(os.Stderr, logMessage+"\n", args...) } - log.GitLogger.Fatal(3, logMessage, args...) - return + log.Fatal(3, logMessage, args...) } - log.GitLogger.Close() + log.Shutdown() os.Exit(1) } @@ -107,12 +114,12 @@ func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string, task, err := models.GetUpdateTaskByUUID(uuid) if err != nil { if models.IsErrUpdateTaskNotExist(err) { - log.GitLogger.Trace("No update task is presented: %s", uuid) + log.Trace("No update task is presented: %s", uuid) return } - log.GitLogger.Fatal(2, "GetUpdateTaskByUUID: %v", err) + log.Fatal(2, "GetUpdateTaskByUUID: %v", err) } else if err = models.DeleteUpdateTaskByUUID(uuid); err != nil { - log.GitLogger.Fatal(2, "DeleteUpdateTaskByUUID: %v", err) + log.Fatal(2, "DeleteUpdateTaskByUUID: %v", err) } if isWiki { @@ -128,13 +135,13 @@ func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string, RepoUserName: repoUser.Name, RepoName: reponame, }); err != nil { - log.GitLogger.Error(2, "Update: %v", err) + log.Error(2, "Update: %v", err) } // Ask for running deliver hook and test pull request tasks. reqURL := setting.LocalURL + repoUser.Name + "/" + reponame + "/tasks/trigger?branch=" + strings.TrimPrefix(task.RefName, git.BRANCH_PREFIX) + "&secret=" + base.EncodeMD5(repoUser.Salt) + "&pusher=" + com.ToStr(user.ID) - log.GitLogger.Trace("Trigger task: %s", reqURL) + log.Trace("Trigger task: %s", reqURL) resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true, @@ -142,10 +149,10 @@ func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string, if err == nil { resp.Body.Close() if resp.StatusCode/100 != 2 { - log.GitLogger.Error(2, "Fail to trigger task: not 2xx response code") + log.Error(2, "Fail to trigger task: not 2xx response code") } } else { - log.GitLogger.Error(2, "Fail to trigger task: %v", err) + log.Error(2, "Fail to trigger task: %v", err) } } diff --git a/cmd/update.go b/cmd/update.go index bebc10160..da7f30931 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -8,9 +8,9 @@ import ( "os" "github.com/urfave/cli" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -32,15 +32,15 @@ func runUpdate(c *cli.Context) error { setup("update.log") if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { - log.GitLogger.Trace("SSH_ORIGINAL_COMMAND is empty") + log.Trace("SSH_ORIGINAL_COMMAND is empty") return nil } args := c.Args() if len(args) != 3 { - log.GitLogger.Fatal(2, "Arguments received are not equal to three") + log.Fatal(2, "Arguments received are not equal to three") } else if len(args[0]) == 0 { - log.GitLogger.Fatal(2, "First argument 'refName' is empty, shouldn't use") + log.Fatal(2, "First argument 'refName' is empty, shouldn't use") } task := models.UpdateTask{ @@ -51,7 +51,7 @@ func runUpdate(c *cli.Context) error { } if err := models.AddUpdateTask(&task); err != nil { - log.GitLogger.Fatal(2, "AddUpdateTask: %v", err) + log.Fatal(2, "AddUpdateTask: %v", err) } return nil diff --git a/cmd/web.go b/cmd/web.go index f1960bb8a..fa3383764 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -26,6 +26,7 @@ import ( "github.com/go-xorm/xorm" "github.com/mcuadros/go-version" "github.com/urfave/cli" + log "gopkg.in/clog.v1" "gopkg.in/ini.v1" "gopkg.in/macaron.v1" @@ -36,7 +37,6 @@ import ( "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/bindata" "github.com/gogits/gogs/modules/context" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/mailer" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/template" diff --git a/conf/app.ini b/conf/app.ini index 10cfc5089..15f674bbb 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -300,12 +300,12 @@ FORMAT = [log] ROOT_PATH = -; Either "console", "file", "conn", "smtp" or "database", default is "console" +; Can be "console" and "file", default is "console" ; Use comma to separate multiple modes, e.g. "console, file" MODE = console ; Buffer length of channel, keep it as it is if you don't know what it is. -BUFFER_LEN = 10000 -; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace" +BUFFER_LEN = 100 +; Either "Trace", "Info", "Warn", "Error", "Fatal", default is "Trace" LEVEL = Trace ; For "console" mode only @@ -315,50 +315,17 @@ LEVEL = ; For "file" mode only [log.file] LEVEL = -; This enables automated log rotate(switch of following options), default is true +; This enables automated log rotate (switch of following options) LOG_ROTATE = true -; Max line number of single file, default is 1000000 -MAX_LINES = 1000000 +; Segment log daily +DAILY_ROTATE = true ; Max size shift of single file, default is 28 means 1 << 28, 256MB MAX_SIZE_SHIFT = 28 -; Segment log daily, default is true -DAILY_ROTATE = true -; Expired days of log file(delete after max days), default is 7 +; Max line number of single file +MAX_LINES = 1000000 +; Expired days of log file (delete after max days) MAX_DAYS = 7 -; For "conn" mode only -[log.conn] -LEVEL = -; Reconnect host for every single message, default is false -RECONNECT_ON_MSG = false -; Try to reconnect when connection is lost, default is false -RECONNECT = false -; Either "tcp", "unix" or "udp", default is "tcp" -PROTOCOL = tcp -; Host address -ADDR = - -; For "smtp" mode only -[log.smtp] -LEVEL = -; Name displayed in mail title, default is "Diagnostic message from server" -SUBJECT = Diagnostic message from server -; Mail server -HOST = -; Mailer user name and password -USER = -PASSWD = -; Receivers, can be one or more, e.g. 1@example.com,2@example.com -RECEIVERS = - -; For "database" mode only -[log.database] -LEVEL = -; Either "mysql" or "postgres" -DRIVER = -; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8 -CONN = - [cron] ; Enable running cron tasks periodically. ENABLED = true diff --git a/gogs.go b/gogs.go index c353390bd..42ddaaefa 100644 --- a/gogs.go +++ b/gogs.go @@ -16,7 +16,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.9.138.0209" +const APP_VER = "0.9.139.0209" func init() { setting.AppVer = APP_VER diff --git a/models/access.go b/models/access.go index b3be9b5bb..43a51775e 100644 --- a/models/access.go +++ b/models/access.go @@ -7,7 +7,7 @@ package models import ( "fmt" - "github.com/gogits/gogs/modules/log" + log "gopkg.in/clog.v1" ) type AccessMode int diff --git a/models/action.go b/models/action.go index 7ce48217c..0f828b99b 100644 --- a/models/action.go +++ b/models/action.go @@ -15,12 +15,12 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/git-module" api "github.com/gogits/go-gogs-client" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/admin.go b/models/admin.go index c9a13eb5d..4e4aba726 100644 --- a/models/admin.go +++ b/models/admin.go @@ -13,9 +13,9 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/git_diff.go b/models/git_diff.go index 107f630ff..c470e4a2c 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -20,11 +20,11 @@ import ( "github.com/sergi/go-diff/diffmatchpatch" "golang.org/x/net/html/charset" "golang.org/x/text/transform" + log "gopkg.in/clog.v1" "github.com/gogits/git-module" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/template/highlight" diff --git a/models/issue.go b/models/issue.go index bf4d86e0c..cc3e4ad02 100644 --- a/models/issue.go +++ b/models/issue.go @@ -18,9 +18,9 @@ import ( "github.com/go-xorm/xorm" api "github.com/gogits/go-gogs-client" gouuid "github.com/satori/go.uuid" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/issue_comment.go b/models/issue_comment.go index 13a977076..e166efd9f 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -11,10 +11,10 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" api "github.com/gogits/go-gogs-client" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/markdown" ) diff --git a/models/issue_mail.go b/models/issue_mail.go index bdaec71b2..f46291237 100644 --- a/models/issue_mail.go +++ b/models/issue_mail.go @@ -8,8 +8,8 @@ import ( "fmt" "github.com/Unknwon/com" + log "gopkg.in/clog.v1" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/mailer" "github.com/gogits/gogs/modules/markdown" "github.com/gogits/gogs/modules/setting" diff --git a/models/login_source.go b/models/login_source.go index 0cb882407..8a30ad228 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -18,10 +18,10 @@ import ( "github.com/go-macaron/binding" "github.com/go-xorm/core" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/auth/ldap" "github.com/gogits/gogs/modules/auth/pam" - "github.com/gogits/gogs/modules/log" ) type LoginType int diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index e2b8bfb2b..71a14960c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -18,10 +18,10 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" gouuid "github.com/satori/go.uuid" + log "gopkg.in/clog.v1" "gopkg.in/ini.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/org.go b/models/org.go index 71d141e0d..543a517f5 100644 --- a/models/org.go +++ b/models/org.go @@ -11,9 +11,9 @@ import ( "strings" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" ) var ( diff --git a/models/pull.go b/models/pull.go index 7aaffe43f..97ca54448 100644 --- a/models/pull.go +++ b/models/pull.go @@ -13,11 +13,11 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "github.com/gogits/git-module" api "github.com/gogits/go-gogs-client" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/sync" diff --git a/models/repo.go b/models/repo.go index 034192ab9..cc0acb849 100644 --- a/models/repo.go +++ b/models/repo.go @@ -23,13 +23,13 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" "github.com/mcuadros/go-version" + log "gopkg.in/clog.v1" "gopkg.in/ini.v1" git "github.com/gogits/git-module" api "github.com/gogits/go-gogs-client" "github.com/gogits/gogs/modules/bindata" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/markdown" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" diff --git a/models/repo_editor.go b/models/repo_editor.go index dfdb864a1..966502049 100644 --- a/models/repo_editor.go +++ b/models/repo_editor.go @@ -17,10 +17,10 @@ import ( "github.com/Unknwon/com" gouuid "github.com/satori/go.uuid" + log "gopkg.in/clog.v1" git "github.com/gogits/git-module" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/repo_mirror.go b/models/repo_mirror.go index c20397c2c..722d769fa 100644 --- a/models/repo_mirror.go +++ b/models/repo_mirror.go @@ -11,11 +11,11 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + log "gopkg.in/clog.v1" "gopkg.in/ini.v1" "github.com/gogits/git-module" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/sync" diff --git a/models/ssh_key.go b/models/ssh_key.go index 26351b60f..3c9708485 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -21,9 +21,9 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" "golang.org/x/crypto/ssh" + log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/update.go b/models/update.go index 5a17822aa..18d6c9dca 100644 --- a/models/update.go +++ b/models/update.go @@ -10,9 +10,9 @@ import ( "os/exec" "strings" - git "github.com/gogits/git-module" + log "gopkg.in/clog.v1" - "github.com/gogits/gogs/modules/log" + git "github.com/gogits/git-module" ) type UpdateTask struct { @@ -101,7 +101,7 @@ func PushUpdate(opts PushUpdateOptions) (err error) { } if isDelRef { - log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %s", + log.Trace("Reference '%s' has been deleted from '%s/%s' by %s", opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName) return nil } diff --git a/models/user.go b/models/user.go index e69a67985..4b44a5137 100644 --- a/models/user.go +++ b/models/user.go @@ -25,13 +25,13 @@ import ( "github.com/go-xorm/xorm" "github.com/nfnt/resize" "golang.org/x/crypto/pbkdf2" + log "gopkg.in/clog.v1" "github.com/gogits/git-module" api "github.com/gogits/go-gogs-client" "github.com/gogits/gogs/modules/avatar" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/markdown" "github.com/gogits/gogs/modules/setting" ) diff --git a/models/webhook.go b/models/webhook.go index 8ce924dfc..babb15ded 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -14,11 +14,11 @@ import ( "github.com/go-xorm/xorm" gouuid "github.com/satori/go.uuid" + log "gopkg.in/clog.v1" api "github.com/gogits/go-gogs-client" "github.com/gogits/gogs/modules/httplib" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/sync" ) diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 3265b326c..e36ec9f1b 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -13,11 +13,11 @@ import ( "github.com/go-macaron/binding" "github.com/go-macaron/session" gouuid "github.com/satori/go.uuid" + log "gopkg.in/clog.v1" "gopkg.in/macaron.v1" "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index f6feb07a4..78cd66a45 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -11,9 +11,8 @@ import ( "fmt" "strings" + log "gopkg.in/clog.v1" "gopkg.in/ldap.v2" - - "github.com/gogits/gogs/modules/log" ) type SecurityProtocol int @@ -50,7 +49,7 @@ func (ls *Source) sanitizedUserQuery(username string) (string, bool) { // See http://tools.ietf.org/search/rfc4515 badCharacters := "\x00()*\\" if strings.ContainsAny(username, badCharacters) { - log.Debug("'%s' contains invalid query characters. Aborting.", username) + log.Trace("Username contains invalid query characters: %s", username) return "", false } @@ -61,7 +60,7 @@ func (ls *Source) sanitizedUserDN(username string) (string, bool) { // See http://tools.ietf.org/search/rfc4514: "special characters" badCharacters := "\x00()*\\,='\"#+;<>" if strings.ContainsAny(username, badCharacters) || strings.HasPrefix(username, " ") || strings.HasSuffix(username, " ") { - log.Debug("'%s' contains invalid DN characters. Aborting.", username) + log.Trace("Username contains invalid query characters: %s", username) return "", false } @@ -73,12 +72,12 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { if ls.BindDN != "" && ls.BindPassword != "" { err := l.Bind(ls.BindDN, ls.BindPassword) if err != nil { - log.Debug("Failed to bind as BindDN[%s]: %v", ls.BindDN, err) + log.Trace("Failed to bind as BindDN '%s': %v", ls.BindDN, err) return "", false } - log.Trace("Bound as BindDN %s", ls.BindDN) + log.Trace("Bound as BindDN: %s", ls.BindDN) } else { - log.Trace("Proceeding with anonymous LDAP search.") + log.Trace("Proceeding with anonymous LDAP search") } // A search for the user. @@ -87,7 +86,7 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { return "", false } - log.Trace("Searching for DN using filter %s and base %s", userFilter, ls.UserBase) + log.Trace("Searching for DN using filter '%s' and base '%s'", userFilter, ls.UserBase) search := ldap.NewSearchRequest( ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, []string{}, nil) @@ -95,10 +94,10 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { // Ensure we found a user sr, err := l.Search(search) if err != nil || len(sr.Entries) < 1 { - log.Debug("Failed search using filter[%s]: %v", userFilter, err) + log.Trace("Failed search using filter '%s': %v", userFilter, err) return "", false } else if len(sr.Entries) > 1 { - log.Debug("Filter '%s' returned more than one user.", userFilter) + log.Trace("Filter '%s' returned more than one user", userFilter) return "", false } @@ -112,7 +111,7 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) { } func dial(ls *Source) (*ldap.Conn, error) { - log.Trace("Dialing LDAP with security protocol (%v) without verifying: %v", ls.SecurityProtocol, ls.SkipVerify) + log.Trace("Dialing LDAP with security protocol '%v' without verifying: %v", ls.SecurityProtocol, ls.SkipVerify) tlsCfg := &tls.Config{ ServerName: ls.Host, @@ -141,7 +140,7 @@ func bindUser(l *ldap.Conn, userDN, passwd string) error { log.Trace("Binding with userDN: %s", userDN) err := l.Bind(userDN, passwd) if err != nil { - log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err) + log.Trace("LDAP authentication failed for '%s': %v", userDN, err) return err } log.Trace("Bound successfully with userDN: %s", userDN) @@ -152,12 +151,12 @@ func bindUser(l *ldap.Conn, userDN, passwd string) error { func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) { // See https://tools.ietf.org/search/rfc4513#section-5.1.2 if len(passwd) == 0 { - log.Debug("Auth. failed for %s, password cannot be empty") + log.Trace("authentication failed for '%s' with empty password") return "", "", "", "", false, false } l, err := dial(ls) if err != nil { - log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err) + log.Error(4, "LDAP connect failed for '%s': %v", ls.Host, err) ls.Enabled = false return "", "", "", "", false, false } @@ -173,7 +172,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str return "", "", "", "", false, false } } else { - log.Trace("LDAP will use BindDN.") + log.Trace("LDAP will use BindDN") var found bool userDN, found = ls.findUserDN(l, name) @@ -195,7 +194,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str return "", "", "", "", false, false } - log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, userDN) + log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter '%s' and base '%s'", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, userDN) search := ldap.NewSearchRequest( userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}, @@ -203,13 +202,13 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str sr, err := l.Search(search) if err != nil { - log.Error(4, "LDAP Search failed unexpectedly! (%v)", err) + log.Error(4, "LDAP search failed: %v", err) return "", "", "", "", false, false } else if len(sr.Entries) < 1 { if directBind { - log.Error(4, "User filter inhibited user login.") + log.Error(4, "User filter inhibited user login") } else { - log.Error(4, "LDAP Search failed unexpectedly! (0 entries)") + log.Error(4, "LDAP search failed: 0 entries") } return "", "", "", "", false, false @@ -222,7 +221,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str isAdmin := false if len(ls.AdminFilter) > 0 { - log.Trace("Checking admin with filter %s and base %s", ls.AdminFilter, userDN) + log.Trace("Checking admin with filter '%s' and base '%s'", ls.AdminFilter, userDN) search = ldap.NewSearchRequest( userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ls.AdminFilter, []string{ls.AttributeName}, @@ -230,9 +229,9 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str sr, err = l.Search(search) if err != nil { - log.Error(4, "LDAP Admin Search failed unexpectedly! (%v)", err) + log.Error(4, "LDAP admin search failed: %v", err) } else if len(sr.Entries) < 1 { - log.Error(4, "LDAP Admin Search failed") + log.Error(4, "LDAP admin search failed: 0 entries") } else { isAdmin = true } diff --git a/modules/base/tool.go b/modules/base/tool.go index 8324fed4b..97b605c0c 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -22,10 +22,10 @@ import ( "github.com/Unknwon/com" "github.com/Unknwon/i18n" + log "gopkg.in/clog.v1" "github.com/gogits/chardet" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -52,17 +52,17 @@ func ShortSha(sha1 string) string { func DetectEncoding(content []byte) (string, error) { if utf8.Valid(content) { - log.Debug("Detected encoding: utf-8 (fast)") + log.Trace("Detected encoding: utf-8 (fast)") return "UTF-8", nil } result, err := chardet.NewTextDetector().DetectBest(content) if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 { - log.Debug("Using default AnsiCharset: %s", setting.Repository.AnsiCharset) + log.Trace("Using default AnsiCharset: %s", setting.Repository.AnsiCharset) return setting.Repository.AnsiCharset, err } - log.Debug("Detected encoding: %s", result.Charset) + log.Trace("Detected encoding: %s", result.Charset) return result.Charset, err } diff --git a/modules/bindata/bindata.go b/modules/bindata/bindata.go index d5e528a39..bec1196a0 100644 --- a/modules/bindata/bindata.go +++ b/modules/bindata/bindata.go @@ -291,7 +291,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _confAppIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x7b\x6f\x8f\x23\x49\x9a\xd7\xfb\xf8\x14\x31\xb5\x2c\xd3\x8d\xd2\x76\x55\x75\x77\x4d\x4d\xd5\x7a\x19\xb7\x9d\x76\xe5\xb5\xff\x4d\x66\xba\x7b\x7a\x5a\xa5\xec\xa8\xcc\xb0\x1d\x5b\x99\x11\x39\x19\x91\x55\xed\x11\x3a\xed\x8a\x17\xfc\x91\x10\x2f\x80\x43\x48\x27\xc4\xbe\x80\x93\x0e\x0e\xee\x04\x48\xbb\xb0\xc0\x8b\xe1\xde\xf7\x7c\x87\x63\x8e\x43\xa0\xfb\x0a\xe8\x79\x22\xd3\x4e\x57\xd7\x14\xb3\x12\xa7\x96\xda\x76\x66\xc4\x13\xf1\xfc\xff\x3d\x4f\x44\xfd\x88\x7e\xf4\xd1\x47\x74\xea\xbe\x74\x7d\x8a\xff\x4d\x66\x03\x6f\xf8\x9a\x86\x17\x5e\x40\x87\xde\xd8\x85\xf7\xc4\x8e\x9a\x8f\xdd\x5e\xe0\xd2\x49\xef\x85\x4b\xfb\x17\xbd\xe9\xc8\x0d\xe8\x6c\x4a\xfb\x33\xdf\x77\x83\xf9\x6c\x3a\xf0\xa6\x23\xda\x5f\x04\xe1\x6c\x42\xfb\xb3\xe9\xd0\x1b\xdd\xa5\xe0\x0d\xe9\xeb\xd9\x82\xf6\x7c\x97\xce\x7b\xfd\x17\xbd\x11\xcc\x98\xfb\xb3\x97\xde\xc0\xf5\x9d\xbd\x05\x66\xaf\x80\xf2\xfc\x35\x9d\x0d\xa9\x17\x22\x0d\x72\x4e\x7b\x79\x4e\x25\xcb\x38\x35\x6b\x66\xa8\x5e\xab\x5b\x4d\x95\xa4\xfc\x86\x17\x1b\x9a\xb3\x15\xa7\x46\x98\x94\x93\xde\x7c\x1e\x4d\x7b\x13\x97\x76\xe9\x48\xad\xf4\x19\x1d\x29\x3a\x12\x86\x06\xbc\xb8\x11\x31\x27\xe7\x34\x5c\x73\x4b\x49\x2d\xa9\x59\x73\xaa\x37\xda\xf0\x8c\x96\x9a\x17\x96\x78\x51\x4a\x8d\x93\x89\xbf\x98\x46\x8b\xc0\xf5\x69\x97\xae\x84\x21\xe7\xd4\x15\x66\xcd\x0b\x7a\x90\xf0\x9b\x03\x87\x1e\xe4\x85\x4a\x0e\xa8\x2a\xe8\x81\xe1\xda\x1c\xe0\xf8\xc9\x6c\x00\x8b\x27\xfc\x86\x90\x37\x05\xcf\x95\x16\x46\x15\x9b\x4b\x72\x4e\x7d\xa5\x0c\xcd\x99\x59\xd3\xa5\x2a\xa8\x36\xaa\x10\x72\x45\xb7\x63\x04\xd7\x1f\x6b\x9a\x30\xc3\x1c\x9a\xf0\x25\x2b\x53\x43\x85\xa6\x07\xbf\xdb\xf9\x09\x6c\x0e\xf6\xfc\xd3\xce\x4a\xad\x74\xab\x39\xe5\x80\xf8\xb3\x59\x48\xbb\x15\x67\x3a\x2e\x44\x6e\xa8\xd9\xe4\x9c\x6a\x5e\xdc\xf0\x82\xea\x32\xcf\x55\x61\xb4\x43\xb5\xca\xb8\x11\x19\xd7\x34\x56\x65\x9a\xd0\x2b\x4e\x0f\xf4\xfa\x80\x04\x7d\xdf\x9b\x87\x51\xf8\x7a\x0e\x5b\xbf\x62\x7a\x4d\xce\xe9\xa0\xda\x42\x6f\x1a\x78\x34\x5e\xb3\x42\x73\x83\x1b\x67\x92\x96\xb2\xe0\xb1\x5a\x49\xf1\x35\x4f\xea\x77\x04\x06\x46\xfd\x8b\x9e\x1f\xb8\x76\x3f\x43\x55\xc4\xbc\x52\x91\xe4\xb7\x3b\x4e\x37\xd4\x28\x58\x3c\x2f\xc4\x0d\x33\x9c\x0c\x67\x7e\xdf\x8d\xe6\xbe\xf7\xb2\x17\xc2\x0e\x96\x2c\xd5\xa0\xaa\x51\xaa\xae\x58\x4a\x33\xf6\x4e\x64\x65\x46\xe3\x82\x33\x23\x94\xa4\xa9\xc8\x84\x01\xfd\x35\x28\xe6\xbc\x40\x1d\x3a\xb4\x75\x44\x33\xce\xa4\xa6\x52\xd9\x91\x64\xd2\xfb\x22\xea\xfb\x6e\x2f\xf4\x66\xd3\x68\xec\x4d\xbc\x90\x76\x69\xeb\x88\x9c\xd3\x89\x28\x0a\xd0\xc5\x46\xc6\xf4\xab\x92\x97\x9c\xa6\x5c\xae\xcc\xda\xa1\x42\xc2\x72\x9a\x53\xb1\xa4\xd9\x6e\x14\x68\x4c\x1b\x56\x18\x4d\xd7\x4c\xae\x84\x5c\x91\x89\xe7\xfb\x33\x3f\xfa\x7c\xe1\x2e\xdc\x68\xec\x4e\x47\xe1\x05\xed\xd2\xa3\xc3\xc3\x43\x72\x4e\xe7\xcc\xc4\x6b\x0a\xe6\xf1\x00\xfd\xbc\x4c\x53\x5a\xf0\xaf\x4a\x18\x96\x6f\x67\xdc\xb3\xd6\x7c\x31\x1e\x47\xbe\xfb\xf9\xc2\x0d\xc2\xef\x5b\xb1\xe0\x4b\x5e\x14\x3c\xa1\x63\x11\x73\xa9\xb9\x06\x69\xe7\x29\x8b\x39\x65\x06\x4d\xde\xa8\xbc\xb6\xfe\x54\x68\x30\xec\x29\x38\x44\x56\x6a\x43\x33\x5c\x7e\x29\xd2\xca\x4b\x84\xa4\xb1\x92\xcb\x4e\x6a\x89\x81\xb5\xc7\xa5\x36\x2a\xeb\x34\x1f\x93\xb9\xef\x0e\x5d\xdf\x77\x07\xd1\xd8\xeb\xbb\xd3\xc0\x0d\x68\x97\xf6\x72\x16\xaf\x79\xbd\x0f\x7a\xdc\x3e\x74\x40\xf6\xd5\x6f\xb0\x31\xa1\xd9\x55\xca\x29\xbb\x12\xa9\x30\x68\x16\x42\x1a\x5e\xb0\xd8\xd0\x5b\x61\xd6\x7b\xce\x41\xaf\x36\xf4\x22\x0c\xe7\x34\x2f\x94\x51\xb1\x4a\xc9\xc0\x0b\x7a\xcf\xc7\x6e\x04\x4f\xa3\x11\x6a\xb5\x36\x1d\x57\xde\x25\x9c\x89\x55\xc1\x0c\x6f\xda\xcc\xd5\x86\xa6\x2a\x66\x29\x3a\x25\x71\xa7\x48\x6c\x3c\xeb\xf7\xc6\xd1\xbc\x17\x5e\x44\x13\x6f\xe4\xa3\xd1\x6c\x09\x37\x5d\xba\xcd\x13\xf8\x04\xcf\x1e\x0b\x8d\xf6\x88\x62\xe3\xef\x0c\x97\x5a\x28\xa9\xb7\xc1\x0a\x9c\x6d\xcd\x6e\x40\xdc\x92\xd3\xdb\x82\xe5\x1a\x04\x0b\x0a\xe8\xab\x84\x57\x56\x68\xe9\xb5\xc9\x39\x0d\x78\xce\x70\xb3\x0d\x5a\x28\x0f\x46\x63\x95\x65\xac\x4d\x43\xb5\xa3\x85\xcb\xda\x01\xaa\x34\xbb\x39\x0e\xfd\x19\x68\x34\x2f\x4d\x3d\x8f\x8c\xbd\xa9\x1b\xbd\xf2\x7b\xf3\xc8\xfd\x22\x74\xa7\x81\x37\x9b\x82\xa2\xda\xe6\x9d\x71\xda\x59\xe2\xb4\x33\x56\x5c\x27\xea\x56\xc2\x2f\xfb\x71\x9d\x38\xe4\x9c\xbe\x64\xa9\x48\x2c\x7f\x99\x4a\x78\xc5\x1a\xf2\xc4\x68\x5e\xf0\x1b\xc1\x6f\x69\x6f\xee\x51\xa6\xb5\x8a\x05\x33\x3c\xb1\x3b\x36\x6b\x9e\x39\x54\x97\xf1\x9a\x32\x4d\x59\x2e\x3a\x37\x47\x9d\x7a\x95\x3d\x5e\x6f\x58\x5a\x5a\x2d\xe3\x5e\x75\x1b\x4c\x19\xe9\x1a\x76\x05\xe2\x02\xf9\xe0\xea\xf4\x56\xc9\x8f\x6d\x16\x00\xf7\x01\x31\xee\x4b\x9e\x26\x8a\x6b\x18\x82\xd6\x0c\xc6\xf9\xd2\x73\x5f\xa1\x7a\x21\x31\x61\x90\x06\xbe\xeb\x7d\xec\xeb\xb5\xcc\x53\xc5\x92\xcb\x9d\x15\x35\x4c\x06\xd7\xb1\x03\x74\xbb\x32\x99\x01\xed\x52\x53\x94\xdc\xba\xfb\x1a\x8c\xcd\xf0\x2c\x57\x05\x2b\x44\xba\xc1\x40\xbf\x9d\x43\x1f\xd5\xa1\x1d\x13\xc1\x8a\x1b\x4d\xe3\x94\x33\xc9\x13\xe0\x1c\xd2\x0e\xb2\x8a\x41\x13\x9d\xff\x31\x09\xdd\xc9\x1c\x0d\x12\xf2\x0a\x33\xac\x63\xb2\xbc\x53\xd1\x83\x30\x0b\x5b\x82\x80\x5f\x29\x85\x15\x9c\xb2\x34\x55\xb7\x3c\xa9\xe2\xac\x1d\xcb\x13\x87\xf2\xf6\xaa\x4d\x45\xc6\x56\xbc\xf3\xb3\x9c\xaf\xfe\x96\xfd\x9a\xcb\x55\x9b\x8e\x39\x28\x93\x67\xb9\xd9\x54\xf1\x13\x89\x50\x26\x2b\xae\x61\x09\xd2\x1b\x8f\x67\xaf\xdc\x01\xe6\x8a\x00\xa3\xfc\xa4\x8a\xce\x5a\x7c\x8d\x39\x95\xb3\x3a\x7e\x08\x49\x27\xcf\x89\x15\x78\xef\x8b\x28\xf0\xbe\x84\xe0\xfe\xa4\x31\x47\x96\xd9\x15\x2f\x6a\xcf\xd1\x36\x88\xe3\x66\x31\x66\xc3\x54\x50\xd3\x33\x42\xde\x94\x02\x14\x32\xdd\x4e\xd8\x8b\x0c\x5b\xbe\xc1\x24\x78\x02\x2b\x2b\x09\xf6\x90\xa7\x20\x7b\xc0\x07\xc4\xfd\x62\x3e\x9e\xf9\x6e\x34\x47\xf0\x11\x4d\x17\x13\xda\xa5\xc7\x87\x7b\x44\x85\xd6\xe5\xf7\x93\x43\x32\x5e\x10\x2c\xee\x10\x39\xda\x27\xb2\x4d\x57\x2a\xcb\x84\xd1\x77\x88\xb0\xd8\x88\x1b\x08\x49\x4b\xce\x13\x32\x74\xdd\x01\x0a\xa7\x3f\x9b\x4c\xbc\xb0\x22\xf8\xcc\x3a\x5c\x89\xf2\x3c\x00\x0f\xe2\xad\x58\xa5\xaa\x38\xa0\x19\x37\x8c\x1a\xb6\x72\x20\xd9\xa1\xc9\xf4\x64\x52\x28\x91\xd0\x9f\x76\xe9\xb3\x36\xec\xa4\x27\xa9\x90\x37\xe8\xaf\x38\x89\xa6\xe2\x9a\xd3\x03\xa9\x24\xb7\x60\x25\xb1\x51\xf7\x80\xde\x8a\x34\xb5\x3e\x0c\x2e\x54\x1b\xa6\x36\x9b\x14\x6c\x79\x02\xa2\x13\x72\xa9\xce\xe8\xda\x98\x5c\x9f\x75\x3a\x09\xbf\xe1\xa9\xca\x79\xa1\xdb\x2b\xa5\x56\x29\x6f\xc7\x2a\xeb\xdc\xf2\xab\x4e\x99\x27\xcc\x70\xdd\x39\x3e\x3c\x7a\xda\x39\x3a\xea\x04\x16\x74\xb4\x96\xaa\x68\x35\x18\x68\x09\xd9\xea\xaf\x0b\x95\xf1\xd6\x93\x4f\xf1\x65\xb5\x7d\x12\x5e\xb8\x13\x37\xea\xcf\xc6\x33\x3f\x9a\xb8\x61\x2f\x0a\x7b\x23\xda\xa5\x6f\x7f\xb4\x5c\x3e\x7b\xf2\xf4\xc9\x5b\x6b\x35\xd6\xca\x84\xa4\x57\x1b\xc3\xf5\xce\x70\xac\x9d\x27\x42\xe7\x29\xdb\xf0\x64\xe7\x65\x42\xd3\xd3\xc9\xf3\xc7\x68\x4e\x03\x2f\x98\x8f\x7b\xaf\x6d\x08\xa8\xac\xf1\xf4\xc9\xe9\xe9\xc9\xe1\x29\x1a\x58\x9b\x25\x99\x90\xfb\x66\x06\x90\xe2\x61\x83\x00\x80\xb8\x6f\x0f\xcf\x0e\x3f\xb4\xd4\x07\x49\xf8\xee\x7c\xf6\x20\x09\xa9\x8c\x88\xff\x1f\x86\x39\x9d\x85\x5e\xff\xae\x79\x3f\xdb\x23\xa3\x8a\x15\x93\xe2\x6b\x0b\xa2\x1e\xa2\x35\xf3\x47\x1f\xec\x07\x25\x04\xe2\xb8\xc7\x0f\x7f\x4b\xee\x8e\xc0\xa1\xeb\xd8\xdb\x88\xb3\x6b\x56\x24\x36\xad\x5d\x15\x9c\x5d\xef\xe2\x79\x9d\x9b\x2f\x7a\x3e\x00\x8c\xa9\x1b\x3d\xf7\xdd\xde\x8b\x46\xbe\xaf\x33\xb0\xc5\x26\x74\xe1\x8f\x5b\x41\x0c\x76\x77\x4f\x50\x64\x1a\x16\xb9\xd6\xf4\x76\xcd\x25\x2d\xb8\x4c\x38\x22\xf1\x49\x9d\x0d\xce\x11\xe7\xf2\x77\x2c\xcb\x53\x0e\xd0\xdf\xc9\xd8\x4a\x72\x43\x6c\x8d\x13\x2d\xfc\x71\x14\xf4\xc1\x60\x6d\x08\xfc\x21\xe9\xff\x8a\x57\x2b\xf1\xa4\x03\x89\xcc\xee\xa3\xb1\xe4\x0f\xca\xf9\x96\x44\x9d\xf0\x3b\xaa\x91\xf2\x98\xde\xa6\xb3\x7b\x12\x3f\xda\xfc\x7e\xce\xff\xbe\x74\x4f\xc8\x1b\x5b\x39\x5c\x92\xb9\x3f\x0b\x67\xfd\xd9\x98\x76\x31\x04\x90\xc1\x6c\xd2\xf3\x00\x0d\x21\x6c\x5a\x2b\x6d\xb0\xfa\x00\x81\xd0\x2e\xfd\xf1\xa3\x7a\xfc\x63\x08\x16\x3f\x7e\x64\x87\x3f\xd6\x67\x3f\x7e\x84\x10\x6d\x3e\xf3\xc3\xc7\xba\x43\xf0\x47\x6f\x30\x80\xc2\xea\xb0\x8d\xff\xc8\x76\x00\xa4\x88\x0a\xc9\xf2\x22\x13\x1a\x99\x03\x7d\x94\x52\xbc\xa3\x5a\xc5\xd7\xdc\x90\xc5\xd4\xfb\x22\x0a\x66\xfd\x17\x6e\x18\xcd\x5d\x7f\xe2\x05\x81\x85\x69\x27\x27\x27\xa0\x10\x44\x75\x8f\x06\x93\x2f\x1f\x83\x29\xe0\x74\x4c\xad\xb7\xaa\xb8\x06\x87\x7e\x54\x03\x92\x20\xb8\xa0\x36\x76\x3d\xa6\x2c\x8e\xb9\xd6\x60\x09\xb7\xfc\x0a\xab\x27\x11\x73\x80\x28\x9e\xa4\x99\xd2\x86\xc6\x0c\xd0\xf4\x46\x95\x34\x51\xe0\x93\x54\x72\x9b\x63\x63\xc0\xe7\xfb\x51\x14\xd1\x0c\x4c\xee\xa5\x86\x17\x14\xea\x15\x99\x6e\x00\xae\x6c\x54\x59\xe0\xba\x55\x7d\x26\x01\xd1\x08\x8d\x04\xb1\x20\x05\xd8\xcd\xb4\xc5\xba\xf0\xb2\x4d\x2c\x26\x7d\x48\xd4\x5b\x91\x7e\x28\xed\x1d\xcc\x86\x45\x97\x9c\x99\xb2\xe0\xd6\xf6\x61\x49\x76\xc3\x44\x0a\xaf\xb7\x70\x1a\x86\xed\x3c\xeb\xd5\x9a\x63\xd1\x5b\x6a\x4e\xaf\x4a\x91\x1a\x21\x9b\xbb\x57\xc0\x80\x69\x93\x20\xec\xf9\x21\x4c\x8d\x02\xd7\x7f\x89\x35\x73\x4d\x61\xa0\x32\x26\x64\x55\xbe\x63\xa0\xe6\xef\x72\xa5\x6d\x98\x00\x52\x71\x0a\xc1\x62\xe1\x8f\x09\xcc\xdf\x1a\xd9\xce\x80\xc0\x18\x54\x61\x6a\xbc\xf0\x03\x88\x54\x96\x74\x7c\x0c\xc1\x8a\x1b\xd0\xbb\x2d\x2d\x96\x50\x07\xdd\xc3\x07\x14\x42\x5c\x6a\xaa\x24\xce\x1f\x7b\x41\xe8\x4e\xa3\x8b\x59\x10\x36\x8c\x74\x7f\x1b\x3f\x98\x4a\xb5\x99\x1f\x3f\xaa\x77\x86\x1c\xed\xda\x01\x6a\x89\x34\x12\x51\xf0\x18\x50\xe6\x5e\xfd\xff\xf1\xef\x76\xda\x5a\xaf\x3f\x76\xe8\x55\x69\xd0\xf8\x6c\xc6\x56\xa8\x91\x8f\x3b\x6b\x95\xf1\xce\x4a\x18\x3b\xaa\x8d\xeb\xa2\xa5\x58\xc4\x88\xea\xaf\xe8\xa2\xa9\x42\x11\xcd\xb7\x00\x75\x53\xc7\x12\x30\x07\x2c\x53\xf3\xf2\x2a\x15\xf1\x35\xbd\xe6\x1b\x5a\xa2\x37\x68\xbd\x6e\x5d\xf3\xcd\x8a\x4b\xa8\x04\x1a\x5b\xab\x5a\x27\x3b\x5a\x5b\x0e\xec\x36\x5e\xb8\xaf\xa3\x10\x2a\xd5\xed\x56\x6a\x7c\xdc\x20\xb9\xc7\xeb\xee\xf9\xc7\x94\xc9\x84\xa6\x1c\x02\x28\x4f\x53\xba\x14\x32\xa1\x50\xde\xdc\xae\x45\xbc\xc6\xec\x02\xdc\xb0\x34\xdd\xae\x35\x02\x51\x5b\x98\xbc\xa3\x83\xee\x9b\x88\x18\x98\xbe\xad\x4c\x19\x3d\x96\xc7\xd7\x34\x13\x12\xa1\x1a\xf0\x8a\xc8\x02\x03\x6e\xac\x8a\x82\xeb\x5c\xc9\x04\xb8\x47\xd8\x3b\xf1\xa6\xde\x64\x31\x41\x8e\x00\x39\x44\xfd\x0b\xb7\xdf\xcc\x3f\xb5\x8b\xf5\x07\x53\x00\xef\x00\xc1\xea\xfe\x10\x54\x2c\x64\x36\x1c\x62\xde\xaa\xda\x43\x76\x5a\xed\x70\xfe\x6c\x11\xba\x7e\x34\x9e\x8d\x9a\xcd\x0f\x2e\x39\xe6\x03\x6d\x78\xae\xcf\xc8\x39\xfd\x6b\xb4\x8d\xfd\x1f\x1a\xf3\xc2\xd0\x56\xcc\xba\x50\x75\xd0\x56\x52\x16\x98\xd2\xbb\xa7\x9f\x9c\x1c\xae\x0f\xb3\x43\x4d\x5b\x10\x9b\xbb\xd9\x06\x3e\xda\x55\x22\x03\xac\x46\xce\xc9\x39\x9d\x15\x74\x59\xa8\x8c\x32\xda\xce\x97\xef\xea\xac\x05\x70\x8d\x27\xf6\x0d\x84\xa1\x57\x42\x26\xea\xd6\x2e\x26\x96\x56\x80\xb6\x94\x79\x94\x28\x72\x8e\xb1\x63\xa9\x8a\x15\x37\x20\x4f\x3b\x1f\x27\x56\x5d\x1d\x10\xea\x63\xbb\x6d\x95\x73\xa9\x75\x4a\xf3\xeb\x58\x1f\x1d\xd3\x96\x90\x48\x15\x57\x6f\x81\x4e\xed\x2f\x9e\xd1\x96\x54\xd7\x7c\xa3\x7f\xd8\xac\x6b\xbe\xa9\x27\xc1\x0b\x0d\x5f\x12\xae\x49\xdf\xf5\x43\x04\x79\xb4\x5b\xf7\x2a\x10\xc0\x76\xea\x65\x08\xa8\xf1\xbe\x01\x15\x45\x72\x4e\x17\x39\xd4\x22\x29\xe0\x5d\x6c\x95\xf0\x2c\x4f\x81\x29\x30\x4a\x6d\x98\x11\xb1\x95\x1b\x76\x0e\xf6\x9c\x02\x45\x00\x66\x7e\xbb\xe6\x05\xaf\x2a\x3a\x4d\xf9\x3b\x1e\x97\x86\x27\x10\x28\x43\xaf\x7f\xd7\x45\x9b\x45\x21\x64\xab\x5e\x9e\x63\xad\x87\x0d\xcd\x41\x2f\xec\x35\x0b\x40\xdb\x0f\x4d\x41\x27\xd8\x0e\xc3\x5d\x8e\xbe\xf4\xe6\x75\xaf\xaf\xc6\x4b\xf8\xac\x01\x92\x98\x35\x69\xec\x97\x2e\x31\x72\xcb\x56\xaa\x56\x2b\x9e\x58\xa0\xeb\xd0\x98\x49\x6c\x0b\x42\x54\xb1\xd5\x42\x55\x44\x1d\x90\x71\x0f\x1b\xbd\x00\xe5\x40\x70\x30\x82\x90\x37\x20\xb8\xcb\x6d\xbd\x82\x5b\xc7\x34\xda\xea\x2b\x69\x0a\x95\xb6\x7a\x80\xba\x5a\xb3\x42\xac\x84\xa4\x6b\xce\x12\x5e\xec\xf9\x3c\xa6\x3d\x45\xf3\x82\x6b\x2e\x0d\xe9\xf5\xfb\x6e\x10\x44\xfd\xd9\x34\xf4\x67\xe3\x08\xeb\xcd\x68\xe6\x7b\x23\x4c\x09\xc4\xca\x0a\x20\xe2\x16\xcd\xa5\x2b\x55\x08\xb3\xce\x34\x2a\xc7\xac\xb9\x28\xf6\x1c\xdb\x76\xdc\xe8\x23\x08\x97\xad\x23\x58\x2b\xa9\xdb\x4e\xe8\xdc\x8f\xc9\x1b\xad\xd7\xed\x6a\x4a\x74\xcd\x37\x11\xc4\x02\x7d\x49\xdc\xc1\xf1\xb3\x67\x47\x9f\x22\x90\x3e\x21\x6e\x7f\x10\xf4\x28\xad\x7e\xf9\xf8\x1d\x7f\x1d\x3e\x3d\x25\x83\xed\xcf\xa3\xc3\xe3\xa7\x84\xbc\x01\x3d\x5d\x31\xcd\x2f\x1b\x6d\xe3\x6c\xa3\xbf\x4a\xb1\x71\xac\xb4\x59\x15\x5c\x5b\x09\xeb\xaf\x52\x61\xf8\x93\x03\x07\xa3\x3b\x68\x20\x56\x52\xf2\x18\xe5\x12\x8a\xc1\x73\x1b\x96\x26\x9b\xe0\xf3\x71\xa3\xf9\xf5\xbc\x6e\xd8\x22\x59\x52\xa5\xaa\xa3\xe3\x4f\x30\x59\x1d\x9d\x3d\x79\x72\x78\x42\xaa\x5e\x38\x84\x0d\x52\xb5\xb2\x0b\xa5\x0c\x99\xf7\x82\xe0\xd5\xa0\x6e\xd3\xee\xed\x48\xa6\x1b\x87\xf2\xba\xd3\x5d\xd5\x8a\x0e\x3d\x28\xf8\x57\xa5\x28\x2a\xab\xb8\xe1\x85\x58\x6e\x5a\xcb\x32\x4d\x0f\x48\x10\x8c\xb7\x7d\x6f\x3b\xbe\x26\x5b\xb3\x86\xaa\x39\x30\x22\xb9\x3a\xc0\xca\x95\xb2\x2b\xad\xd2\xd2\xec\x5c\x45\x22\xf3\xd8\xf1\x00\xf0\x53\xa1\x2f\xd2\x6c\x7b\x00\x13\xed\xe4\x8a\x90\x37\x55\xa1\x06\x40\x35\x2e\x0b\x61\x36\x97\xc4\x9b\x06\x61\x6f\x3c\x8e\xc6\xb3\xbd\xb8\xfc\xd1\x47\xf6\xc0\xc2\x9e\x6b\x84\x33\xfa\xc2\x75\xe7\xf4\xf5\x6c\xe1\x53\x14\x07\xb8\x16\x0d\x7a\x43\xf7\xa3\x8f\x48\xe0\xf6\x7d\x37\x84\x18\x4f\xbb\xf4\xa3\x1f\x7d\x36\x1c\xb8\xaf\x7c\xf7\x95\xff\xd7\xff\xc6\x23\xf0\xb8\xd2\x28\x70\x16\x01\x25\x43\xc6\x11\x01\x24\x6c\xa3\xc9\x78\x36\xf2\xa6\x91\xef\x4e\xdc\xc9\x73\xd7\x8f\x06\xbd\xd7\x00\xaf\x3f\x21\xfd\xd9\xec\x85\xe7\xe2\x01\x42\x43\x0b\x11\xbb\xe5\x1a\x5c\xa7\x7a\xbd\x9d\xd7\x1c\x83\xcd\xe1\x44\x58\x41\xfa\xfc\x86\x17\x1a\xe2\xaa\x7a\xb7\xa1\xac\x34\x6b\x2e\x4d\xed\xfb\xd6\xa1\xb6\x07\x1a\x78\x8a\x01\x3f\x88\xef\xbe\x74\xfd\xc0\x8d\xe6\xfe\xec\x8b\xd7\x51\x6f\x11\x5e\xb8\xd3\xd0\xeb\xdb\x1e\x78\x65\x09\x5f\xb4\x5e\xb9\xcf\xe1\x55\x0b\x1e\x54\xb8\x5f\xc4\xfc\x92\xf4\xfa\xa1\xf7\x12\xca\xf1\x81\x1b\x8d\xe1\xdb\xc4\x9b\x2e\x42\x6c\xc6\x1c\x9d\x1e\x12\xdf\x0d\x00\x78\xa3\x0d\x7d\xef\xa0\x73\xba\xc0\xdd\xd4\x18\x59\xc9\xa5\x28\x32\xca\x5b\x19\x13\x29\x46\x8a\x82\xaf\x84\x36\x36\x79\x11\xdf\x1d\x01\x5a\xf2\x23\x77\xd2\xf3\xc6\x11\x9e\x23\xf9\x93\x3d\x18\xc9\x6d\xb4\xb0\x7d\x29\x3b\x99\x17\x68\x5a\x68\x10\x35\xb6\x61\x71\xac\x4a\x69\x01\xf7\x2e\xc7\x22\xf9\x3b\xed\xdc\x6a\x8b\xd8\xf8\xd6\x62\x85\x59\xdb\x28\x8a\x4d\x47\x26\x37\x66\x2d\xe4\xaa\x4d\x7c\xf7\xf3\x85\xe7\xbb\x51\xe0\x8d\xa6\xde\x34\x7a\xe9\xb9\xaf\x1a\x14\x26\xc0\x0d\x14\xe8\xcb\x4a\x27\x75\xf0\x85\x82\x7c\xf8\x3a\x02\x6e\x9a\xc3\x21\x83\x26\xdc\x30\x91\xee\xfa\x2a\x2b\x61\xd6\xe5\x15\x36\x53\x56\x6a\x25\x8c\x46\x5b\xef\xd8\x76\x54\xe7\xe8\xe4\x59\x4d\xf3\x21\xad\x6e\x17\xf9\xbe\xb1\xb3\xef\x13\x42\x55\x7e\xc7\x2c\x37\xf1\x9a\x51\xec\x1d\x59\xf3\xfa\x40\x4b\x15\xed\x7e\x6f\x1e\xf6\x2f\x7a\x75\xe3\x93\xbc\xb9\xe5\x57\x6b\xa5\xae\x21\xda\x5d\x28\x75\x4d\x0d\xd3\xd7\x0f\x9c\x78\x54\xc3\xa1\x38\x56\xf7\x9d\x73\xdc\x7f\xb4\x31\xe0\xa9\x00\x94\x6d\x44\xc6\x01\x00\x08\x49\x35\x8f\x95\x4c\x34\x19\xb8\x60\x81\x7e\x14\x7a\x13\x77\xb6\x08\xab\x26\x1a\xe6\x1e\x2a\x24\x86\x09\xde\x80\x32\xc0\x4a\xf0\xc2\x9b\x47\xe1\x38\x88\x5e\xba\xbe\x37\x7c\xdd\x90\xc7\xae\xbb\xb1\x16\x1a\x81\xb3\x90\x4b\x55\x64\x56\x26\x42\xda\x1e\x27\x36\x37\xee\x36\x02\xc9\x1b\xb0\x6e\xa8\x9d\x77\xbd\xe1\x9a\xec\xf3\x72\xb9\x44\x50\x81\xf9\x48\x2d\xb1\x6c\x94\x3c\x75\xe8\x35\xe7\x39\x94\x88\x4c\xc3\xff\x42\x57\x65\x22\x4d\xb0\xcf\x7d\x2d\xd5\x2d\xbd\x5d\x33\x63\x5f\xb6\x49\xe0\x4e\x07\xd1\xf3\xc5\x70\x08\xa0\xd1\x9d\x5a\x01\xd5\xa7\x38\xbb\x26\x98\x90\x14\x5d\xcd\x9e\x8c\x06\x8b\xe7\xbf\xe3\xf6\x6d\x1d\x52\x9f\x92\x62\x1d\x82\x06\x6c\xeb\x17\x80\x9d\x19\x5a\xa6\xce\x4c\xde\x5e\xc1\x77\xb0\xca\xb3\x67\xa7\x9f\x90\x73\xfa\xf9\xe7\xd5\x8b\xaf\xbe\xc2\xa7\x4f\x4f\xb0\xbf\xa4\x0c\x77\xea\x3e\x3c\xa2\x40\x2e\x93\xaa\x77\x71\xf0\xf4\xe4\xd9\x81\x43\x83\x49\x38\x0f\x6c\xbb\xf1\x8a\x63\xe7\xb2\x4d\x17\x58\x5b\x60\xd9\x18\x8e\x03\xaa\xa4\x9d\xfb\xec\xf4\x13\x10\x40\xc1\x63\x95\x65\x5c\x26\x3c\xc1\xae\xb0\x3f\xec\xd3\x93\xa7\x87\x9f\xb6\xa9\x57\x1d\xdb\xee\x1f\x6e\xee\x08\x09\x63\x17\x62\xe9\x2d\xdb\xe8\xed\x7a\x55\x7e\x6c\x40\xf5\x0b\x77\x3c\x03\x90\x69\x2d\xdb\xe6\x20\xc0\xcb\x18\x4b\x19\x78\xa9\x00\x7d\x71\x69\xda\xbb\x93\x26\x98\x03\x44\xfa\xb6\xcf\xb4\x1d\x0f\x8e\xb2\x4f\x70\x0f\xe4\x20\xaa\xb6\xe5\x52\x9b\xc0\x38\xac\x2c\x6d\xc8\xc7\xd0\x86\x81\xcd\x26\x55\x64\xaf\x89\xba\x55\x93\xe3\x36\x9d\xc9\x74\x83\x39\xd4\xac\x81\xb2\x2a\xa8\xe6\xe9\xb2\x05\xf1\x8b\x27\xcd\x89\xda\x9a\x78\x6d\xde\x36\xda\xd1\x38\x15\x5c\x9a\xe6\x38\x00\x06\x11\x80\x66\x6f\x08\xa1\x64\x57\x9f\xdc\x03\xa4\xad\x75\x3f\x84\xa4\xab\x11\x3b\x28\x8d\xf6\x65\x0b\x8e\x24\x29\xb8\xd6\x0e\x6a\xf3\xd9\x93\xe3\xe3\x36\x0d\x81\x87\x0a\x74\x62\xd3\x8a\x49\xca\xd1\x6a\xb7\x83\x55\x81\xec\xbf\x3d\x00\xf3\x3e\xa0\x3f\xc1\xd7\x9f\x35\x8a\x9a\x9f\xbe\xa5\xd6\x3b\xc9\xd0\x9f\x4d\xaa\x43\x09\xd8\xc4\x2e\x1d\x62\x92\xc8\x99\xd6\xb7\xaa\x48\x2a\x20\xd4\xc4\x40\x20\x18\xc3\xdf\x99\xce\xda\x64\x29\x1e\x54\xa5\x86\x17\x92\x19\x71\xc3\x2b\xe2\xe8\xb0\x4a\x1a\x00\xa9\x75\x3b\x32\x9c\x00\x42\x0d\x21\xc1\x43\xbe\x6c\x1c\x13\xc6\x2c\x5e\xef\x63\x3f\x9e\xa9\x62\x63\x71\x54\x22\xf4\x01\xf2\x05\x4f\x71\xe4\xc1\xfe\x91\x7f\x35\x98\xf4\x06\xbd\x79\x88\xa9\xda\x3e\xa9\x61\x55\xf5\xbe\xc2\x6a\xa3\xbe\x6d\x6d\xdc\xb0\xb4\x11\x12\xf7\x28\x9e\x1c\x12\x6f\x1a\xba\xfe\xcb\x1e\xe4\xa2\x93\xc3\x9a\x90\xdd\x8b\x45\x67\x8d\xbd\x54\xf8\x13\x01\x86\x02\xa5\x58\x5d\x90\x73\x8a\x13\xce\xa8\xb4\x2d\x95\xae\x89\x73\x07\x5e\x76\xcf\x4e\x9e\x7c\xf2\xa9\x53\x4b\xb8\x9b\xb1\x98\x15\x4a\x3a\xc9\x55\xf7\xd0\xc9\x95\x4a\x11\x52\x77\x8f\x0e\x0f\x1d\x91\xa4\x3c\xaa\x22\x78\xd7\xe2\x84\x7a\xe5\x33\xfa\x76\x07\x5f\x8f\x8e\x8e\x8f\x8e\xde\xd6\x6e\x0b\xd8\x04\x5b\x81\xf7\xcb\x14\x6a\xb1\x4a\xa4\xb5\x78\xef\x93\x67\x7d\xe3\xa4\x29\xd0\x79\xa1\x6e\x04\x60\x28\x04\x28\x2b\xaa\x72\xe0\x5b\xdb\x6d\xa9\x62\x73\x86\xae\x69\x4f\x3a\xe5\xa6\x1e\xb5\xe1\x86\x9c\x63\x09\x78\x46\xab\x9d\xed\x0a\xc2\xea\x9c\xed\x2d\xa2\xd6\xea\xad\x7e\xfb\x57\x26\x3d\x80\xff\x67\x74\xa5\x5a\xfa\xab\xb4\x95\x14\x90\x22\x3b\xf8\x90\x26\x5a\xd6\x1b\xd6\xa6\x10\x72\x55\xef\x0c\x6a\x80\xb3\x7a\xbd\xcf\xea\x3d\x46\x06\x02\xe3\xdb\xad\x98\xa2\xea\x32\x4f\x85\xbf\x6b\x4e\xb0\x59\x6d\x59\x8e\x95\xba\x16\xf6\xa6\x40\x0d\x68\x2b\x1c\x2b\xa2\x54\x5c\xf3\xc8\xc2\x19\x72\x0e\x61\x1b\x32\x1a\xc4\xad\x5a\x5e\x50\x0f\x02\x00\xaa\xcc\xb8\x19\x2e\x6d\xf8\xb1\x04\x03\xb7\xbf\xf0\xdd\x0f\xe1\x8a\xe6\xa6\x5a\x7f\x6f\x2e\x02\x92\xca\x41\x01\xa5\x5a\x2a\xbb\x23\xda\x7a\xeb\xa3\x3e\xe2\x88\xad\xeb\xec\x11\x39\x3d\x79\x7a\x78\x48\x46\xfd\xa8\xf6\x1a\x04\x16\xb4\x5b\xbd\xd8\x51\x49\xc5\x92\x23\x9d\x7b\xa6\x07\x2e\x76\xa5\xa3\xb1\x37\x74\xf7\xe7\x93\x37\xb9\x88\x4d\x59\x60\x84\xd8\xf6\xc4\xec\x39\xb1\xde\x9e\x81\x42\x71\x7b\xc3\x0c\x2b\x34\xe9\xbd\xec\x85\x3d\x3f\x5a\xcc\xc7\xb3\xde\x60\xef\x2c\xb8\x1e\x71\x4e\xfb\x6b\x21\xb9\xe6\xd5\x91\x15\x96\x91\x6b\xa5\x34\xa7\x07\x49\xa9\xf4\xba\x54\x07\xe4\x1c\x3c\x84\xd5\x87\x24\x76\x2a\xd5\xaa\x2c\x62\xee\xe0\x31\xa1\x85\xa4\x67\x9d\x4e\x2c\xdb\xab\xc2\x0e\x40\x58\x6a\xbf\x76\xc8\xc8\xaf\xb6\x12\xcc\x16\x7e\x1f\x0b\x96\x6a\x18\x5e\x40\x12\xda\x36\xbe\xb7\xb9\x7e\xa9\x8a\x78\x7b\x0e\x8d\xed\x2a\x21\xa9\x5a\x2e\xf1\x94\x27\xc3\xe6\x76\x9d\x5b\x6b\xd2\x0d\x4d\x0f\x79\x82\x3d\xb0\x5a\x10\x34\x55\xea\xba\xcc\x81\x45\x4d\x07\xd3\xa0\x2a\xe6\x63\x05\x50\xa0\x1a\xb2\xbb\x80\x40\xce\x2d\x08\xc1\x84\xa1\x1d\xaa\x39\xdf\x22\xee\xdb\xdb\xdb\x76\x2a\xae\x6a\x16\x55\xb1\xfa\x01\xfb\xc7\x6d\xdd\x65\x00\x44\x3a\xaa\xe8\x80\xee\x13\xa1\xaf\x58\x0a\x88\xa3\x32\xc2\xa1\x3b\x70\xfd\x5e\xe8\x0e\xa2\x2d\x7f\x15\x68\x66\xc6\xb0\x78\x9d\x71\x69\x2e\x1b\x8d\xf6\xdd\x53\x8d\x30\x84\xa3\xb9\x27\xed\xba\x49\x84\xa7\x9d\x6f\x81\xc4\xdb\x6a\x89\x3b\xf7\x0f\xf0\x92\xd6\x8e\xc8\x9d\x89\xd6\x6a\x76\xaf\xdf\xee\xd5\xd8\x8d\x17\xe4\x9c\xce\x24\xb2\x97\xa9\xe6\x95\x82\x4d\xce\xf5\x03\x37\x09\xee\x5e\x11\xb8\x7f\x50\xe3\x34\xb7\x79\x67\x60\x7f\xaf\x4f\x8e\x27\xcf\x49\xe3\xea\xc0\xd3\x6a\xda\xf7\x5f\x1b\xd8\x9f\x7f\x74\xf8\xc1\x35\x02\x70\x55\x10\x76\x90\xf3\x58\x2c\xed\xdd\x81\x6d\x86\x07\xc1\x2d\xcb\x34\xdd\x50\x55\x9a\xbc\x04\xbb\xc3\x53\xed\x7d\xaa\xfe\xb0\x7f\x74\x74\xfc\xa4\x26\xc2\xd2\x1a\x84\xf2\xa4\xbe\xc3\x02\x6a\xeb\x4d\x03\xaf\xef\xd0\x85\x14\xef\x06\x0c\x10\xb2\x5f\x5e\x6d\xaa\x6f\xc3\xfe\xe9\xf1\x71\xfd\xf9\xa5\xfd\xf2\xec\xd0\xa9\x49\x6f\xbf\xd8\x57\x4f\x9e\x3c\xf9\x74\xfb\x65\xca\xa4\x72\xe8\x0b\x61\xe2\x35\x97\x0e\x0d\x0c\xcb\xf2\xea\x63\x22\xd2\x54\x6c\xbf\xc7\x85\xc2\xbc\x8e\x3f\x61\x56\x95\xf3\xb3\xfa\x58\xbf\xae\x67\xd8\x15\xd4\x52\x0d\x31\xd4\x7e\x02\x85\xa9\x4a\x99\x5c\x81\x7b\x74\xf2\xeb\x55\x07\xa4\xd7\xf9\x51\x7e\xbd\x6a\xc5\x4a\x6a\xc3\xc0\x4a\x86\x33\x7f\xd2\xb3\x29\x3a\x55\xab\x4b\xb2\xdf\xd8\xac\x53\x35\x8c\x57\xb6\x8f\x54\xe5\x6a\x78\x24\xe1\x13\x2a\x8a\xea\x62\x42\xd5\x33\xbb\x93\xbd\xeb\xb9\x35\x80\x55\x59\xc6\x30\x60\xd6\x27\xa6\x59\x99\x1a\x91\xd7\x57\x93\x2a\xdb\xac\xa7\x39\x68\x24\x07\xa4\x6a\x50\x55\x4f\xff\x7f\x96\x63\x77\x2b\x31\x4c\x10\x35\xe3\x61\xc1\x62\x64\x77\xc0\xaf\xca\x15\x7c\xf1\xe4\x52\xc1\xe7\x2b\x56\x20\xff\x6e\x51\xa8\x02\xbe\xf4\x0b\x61\x44\xcc\xd2\x3b\xec\x5b\x0a\x64\xec\xbe\x74\x01\xbc\xe1\x4f\x52\x03\xb8\x5a\x36\x55\x28\x92\xe9\x06\xd5\xd0\xae\x9e\x5f\xd6\xd3\xb6\x13\x50\x18\x77\x47\xc3\xc3\xdd\xd0\x2a\x10\xda\xb8\xa3\x29\x2b\x8d\xca\x30\x08\xa7\x6a\x45\x0b\x65\x98\xe1\x8f\xf4\x2d\x58\x20\xba\xa0\x82\xc0\x00\xb5\x5c\x85\x9c\x1e\x7f\x98\x8e\xc7\xb3\x51\xe4\xcf\x42\x5b\x5b\x54\xa1\x0a\x1c\x19\x83\xe8\xce\x9b\xa1\x22\x4c\xed\x5d\xae\x3d\x1a\x28\xd3\x43\xeb\xcc\x63\x6f\x6a\x3b\x4c\xd5\xb3\x46\x20\xd1\x6b\xb1\x34\x0f\xd1\x39\x3e\xad\x6e\x36\x1d\xd1\x9f\xfc\x84\x1e\x9f\x3a\xf4\xf8\xd9\x49\x23\xc4\x44\xc1\x85\x37\xc4\x63\xc3\x53\x4c\xf1\x2b\x88\x83\xc8\x75\xc2\xc4\x1d\x88\x82\x5c\x0c\x7a\xde\xf8\xf5\x07\x9c\xb9\xef\x72\x51\x60\xec\xd8\xe0\x15\x15\x20\x00\x7b\x79\x94\xf0\x94\x1b\x4e\xd9\xd2\xf0\x82\x66\xec\x1d\x8e\xd8\x17\xd7\x27\xf6\xa6\x4a\xdd\x43\x6c\xa8\x59\xde\xa7\x63\xd9\xd4\x9a\xcf\xeb\xbe\x31\x82\x76\xbc\xc3\x60\xef\x91\x59\x79\x64\x5c\x6b\xb6\xe2\xf7\x20\x2d\xdf\xed\xcf\xa6\x53\xb7\x1f\x46\xb3\x69\x34\x09\x9a\xc7\x50\xa1\x3d\x36\x2c\xb6\xb4\xb1\x4e\x6e\x14\x08\x42\xd3\x54\x69\xf3\x10\xd5\x26\x76\xab\xdc\xc2\xc4\x39\x98\x7c\x29\xc5\x3b\xeb\xfb\x65\x92\xdf\xb1\x7b\x18\xd2\xbc\x81\x60\xe2\x1c\xbb\x4b\x8d\x7a\xc4\xde\x21\xd8\x4a\xc9\x46\x92\x3b\x52\x82\x87\x4d\x29\x3d\xd4\x24\xd9\xdf\xc0\x40\xb0\x95\x54\xda\x88\xb8\x16\x5d\x55\xc7\x63\x21\x7e\xd0\xe8\xa8\x3c\x3c\xf2\x4e\x8f\x65\xdb\x88\xf8\x6d\x8b\x54\x9f\xc7\x1c\xc0\xfd\xee\x98\x46\xed\xf2\x73\x15\xf5\x8e\x9a\x85\xb1\x73\xdc\xfc\x05\xfa\x70\xbd\x97\xae\x1f\x34\x44\xb6\x0d\xb9\x77\xc5\xb6\x3b\xbf\xd8\x89\x6e\xff\x1c\x83\xee\x9d\x1b\x90\x81\xef\xe1\xb1\x3f\x44\x56\xa6\x79\x42\x95\xa4\xef\x54\x91\xd9\x8d\x9d\xe1\xb1\xc3\x19\xfc\xf7\xd9\xf6\xf2\x08\x76\x39\xff\x66\x75\x7f\xbc\x5b\x9a\xe5\x29\x01\x8b\xc1\x5c\x12\x17\xaa\x79\x35\xa8\x28\xa5\x84\x18\x03\x8f\xb1\xb9\x88\x59\x5f\xa8\x04\x02\x66\xba\xb9\xe7\x2a\xa6\x5f\xca\xe6\x68\x34\x5b\x3c\x8c\xb3\xad\xc6\x36\xde\xd6\xef\x85\x11\x36\x8e\x76\x95\xfb\x39\x5d\xe0\x75\x90\xea\xd2\xb7\xb6\x3b\x69\xdb\x3b\x22\x51\xf5\xf0\x92\x04\xfd\x0b\x77\xb0\x40\xe8\xf5\x99\x75\xb2\xa3\xc3\x8c\xa0\x92\xb6\x77\x45\xd7\x9c\xa5\x66\x6d\x8f\x9a\x2b\x32\x05\xcf\x55\x64\x9f\x47\xf8\xfc\x3e\x4a\xc7\x4f\xd7\x64\xd7\xc7\x3c\x39\x04\x24\xd6\x2b\x56\xa5\x85\x84\xe0\xd6\x98\x02\x65\x42\x3f\x5e\x09\x43\x97\x3a\xbe\xfe\xb8\x4e\x7a\xad\x56\x29\x0b\x80\x53\x28\xb5\x56\xcb\xb0\x95\x86\xc4\x09\x39\x1d\x33\xbf\x92\xdb\xdc\x2e\x4c\x4b\xc7\x19\xc2\xfb\x44\xc5\x1a\x1f\x00\xb1\xce\x51\xfb\x93\xf6\x33\xd2\xf3\x47\x95\xa5\xf4\xf1\xb0\xbc\x71\x0b\x16\x4f\x40\xc1\xdc\x6b\xf1\x20\x2f\x11\x72\x07\xef\xf4\xe5\x5d\xe9\xa2\x52\xee\x67\x95\xbc\x59\x09\x04\xc0\x55\x63\x4e\xd3\xb5\x58\xad\x53\xb1\x5a\x63\x30\x67\x09\x16\x42\x32\xa1\x05\xcf\xd4\x8d\xfd\x83\x03\xb9\xe2\x7a\x5b\x38\x0c\xbc\xe1\x30\xba\xf0\x46\x17\x63\x6f\x74\x11\xee\xb5\xe6\x9b\x58\x11\x92\x8d\xde\xc2\x58\xa0\xdc\x4c\x14\x10\x08\x12\xb1\x5c\x62\xf3\x1f\x83\xf0\xc8\x0b\x2d\xe9\x66\xca\xf9\x80\x2a\x58\x2f\x8b\x0d\x94\x5c\x48\x32\x6d\x9e\x4d\x3e\x4c\x13\xff\x58\xa2\xd7\x0f\xd1\x23\xe9\xb3\x7b\x88\x5b\x78\xab\xd7\xea\x56\x3e\x40\xab\xc6\xb7\xb6\x09\xfc\x80\xa5\xac\xe2\x86\x9d\xb0\x15\xf8\xad\x16\x37\x60\x26\x90\xe3\x7f\x1b\x33\x59\xc5\x95\x91\x8c\xfa\xd1\xce\x4e\x66\xdb\x66\xea\x3d\x1d\x7a\xd0\x72\xbb\x7a\x7e\x49\xec\xd5\x7a\x17\xed\xfb\xb0\xfa\x13\x0a\x7b\xf3\x8b\xf4\xc7\xb3\xa9\x5b\x7d\x9f\x2f\xc6\xe3\xea\xeb\xa8\x6f\x3b\x57\xe4\x8d\x75\xc2\xcb\xc6\xb1\x79\xb3\xfd\xb5\x56\x65\xa1\xe9\x15\x37\xb7\x9c\x57\x9d\x7a\xeb\x81\x03\x77\xd8\x5b\x8c\xc3\xa8\xd1\x08\x3b\x85\x22\x2c\xc7\x9b\xc5\xfb\x82\x17\x86\x67\xda\x16\x81\xf6\x2a\x88\xad\xfb\x98\x6d\xfa\x83\xf4\xed\x5f\x3e\x05\x6e\xe4\x85\xee\x24\xa8\xaf\x48\x8a\xa3\x53\x48\xc9\xbd\x29\x88\x84\x72\xd9\x5a\x04\xce\xd7\xeb\x56\x7f\x0a\xff\x5f\xbc\x80\xff\xc3\x57\x4e\xc2\x5b\x03\xd7\x59\x16\xad\xa1\xef\xc8\xb4\x35\x1d\x3b\xe9\x4d\x6b\xfc\xd2\x29\xca\x96\xbf\x70\x7e\xc6\x5a\xbf\x33\x77\xb8\x6e\xb9\x81\x93\x9b\xd6\x73\xdf\xc9\xd3\xd6\x7c\xec\x5c\xad\x5a\xcf\x47\x8e\x30\x2d\x2f\x74\x96\xa2\x35\xf4\x1c\x53\xb4\x42\xdf\x89\x75\xab\xff\xa5\xa3\x8b\x56\x30\x77\xf4\x4d\x2b\x70\x9d\x6b\xd5\x7a\xe1\x3b\xab\xb4\xe5\x06\x78\x00\x0c\x7b\x71\xe5\x2a\x15\x7a\xed\xfc\xf9\xbf\xfd\xf9\x9f\xfd\x97\x7f\xf4\x67\xbf\xfa\xa3\xef\x7e\xef\xef\x38\x7f\xfe\xeb\x5f\xfc\xc5\xbf\xfe\xc7\xf6\xc7\x5f\xfe\xe6\xef\xfe\xc5\xbf\xfa\x67\xdf\xfd\xea\xdf\xfd\xe5\x6f\xfe\xde\xdd\x17\xff\xe3\x1f\xfe\xf1\x77\xbf\xfe\xaf\xf0\x62\xc0\x4b\xa3\xe3\xb5\x33\x2c\x98\xfc\xe6\x0f\x98\xd0\xce\x14\x6a\xf4\x94\xc9\x44\x3b\x63\x66\x6e\x04\xff\xd3\x5f\x96\xce\xfb\x7f\xf1\xed\xdf\xfe\xf6\x17\xdf\xfe\xe2\xfd\x7f\x7a\xff\xab\xf7\xbf\x76\xbe\xfb\xa7\xff\xf2\xbb\xdf\xff\x37\xff\xf3\x0f\xff\xb9\xe3\xea\x9c\x7d\xf3\x27\x2a\x75\xe6\xaa\x30\xe5\xaa\xfc\xe6\x0f\x35\x4d\x14\x7d\x5e\x30\x2d\xe0\x61\xaa\xaf\x85\xf3\xfe\x4f\xbe\xfd\xfb\xef\xff\xf3\xfb\x7f\xff\xfe\x8f\xbf\xfd\xb9\xa5\xe1\x78\x86\xa5\x02\x4a\x9f\xa0\x54\x19\x4b\x99\x90\x5c\x3a\xe1\x37\xbf\x29\xae\xbf\xf9\x03\xee\xfc\xf7\x7f\xc0\xff\xf4\x97\x46\x48\xe6\xbc\xff\xe5\xb7\x3f\x7f\xff\xdf\xaa\x49\xc1\x0d\x97\xfa\x9a\x39\xff\xe7\x9f\xfc\xfe\xff\xfa\x8f\x7f\xf4\xbf\x7f\xef\x3f\x38\x23\x96\xf2\x95\x22\xb6\x92\x48\xd0\x43\x20\xae\x83\x59\xe6\x22\xbe\xe6\x85\x55\x21\x64\x3f\x0e\x95\xcf\x25\x41\x1d\xa2\x2e\x09\x2a\x92\x76\xe9\xd7\x6b\x82\xda\xc4\xaf\xad\xf0\x15\xc1\xff\xb7\xbf\x50\xbb\xf8\x27\x60\x04\x55\x0c\x01\xa9\x20\xa8\x67\xda\xa5\x32\x25\xa8\x6c\xda\xa5\xe9\x0d\x41\x8d\xd3\x2e\x2d\x4a\x82\x6a\xa7\x5d\xfa\x33\x46\x50\xf7\xb0\xa6\x26\x68\x00\xb4\x4b\xf1\x93\xa0\x21\xc0\xaf\x94\xa0\x35\xd0\x2e\xbd\x5a\x11\x34\x09\x28\xb4\x0d\x41\xbb\x80\x05\x05\x41\xe3\xc0\xc8\x4b\xd0\x42\xa0\xf6\x81\x4f\x82\x96\x42\xbb\x54\x17\x04\xcd\x05\xbe\xde\x10\xb4\x19\xda\xa5\xd7\x8a\xa0\xe1\xd0\x2e\x5d\xa5\x04\xd1\x6c\x7d\xc3\x34\x63\x79\x8e\x37\xa2\x54\x23\x42\xc7\x29\xc3\xc6\x30\x86\x95\xb6\x51\x59\xda\x15\x52\x90\x37\xdb\x11\xed\x6a\xda\x25\x21\x6f\x14\xe0\x87\x4b\x12\x5c\xcc\x5e\x45\xc3\xd9\x2c\x74\xfd\xe8\xb9\x6f\xaf\x95\x34\xc2\x76\xb0\x56\xb7\x14\x70\x8e\x6d\x12\xde\xad\x54\x31\x89\x43\x4c\x1b\xa9\xfa\x8f\x68\x96\x4a\x19\x5e\xec\xd1\x05\x9c\x63\x4f\x39\xeb\xbe\x1f\x50\xc5\x8e\x5f\xf3\x3e\x8f\xbd\x96\x53\x75\x23\xbf\x87\x54\xe8\x4e\xe6\xe3\x5e\xe8\x46\xd8\x7c\xab\x1a\x79\x48\xf5\xff\x06\x00\x00\xff\xff\x8c\x3f\x7c\x4b\x45\x39\x00\x00") +var _confAppIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x7b\x5f\x8f\xe3\x48\x92\xdf\x7b\x7e\x8a\x9c\x5a\xaf\xa7\xdb\xa0\xa4\xaa\xea\x3f\x53\xd3\xb5\x5a\x2c\x5b\xa2\x54\xbc\xd6\xbf\x21\xa9\xee\xe9\x69\x14\xd8\x59\x64\x4a\xca\x2d\x32\x93\xc3\x4c\x56\xb5\x06\xc6\x61\x17\x7e\xf0\x1f\xc0\xf0\x83\xed\x33\x0c\x1c\x0c\xef\x83\x7d\xc0\xd9\x67\xdf\xc1\x36\xb0\x6b\xaf\xed\x87\xf1\xbd\xf7\x7c\x87\xf3\x9c\xcf\xb0\x71\x5f\xc1\x88\x48\x52\xa2\x6a\x6a\xda\x73\x80\x3d\x03\x94\x24\x32\x33\x32\x33\xf2\x17\x11\xbf\x88\xcc\xfe\x11\xfd\xe8\xa3\x8f\xe8\xcc\x7b\xe9\x05\x14\xff\x4c\xe7\x43\x7f\xf4\x9a\x46\x17\x7e\x48\x47\xfe\xc4\x83\xf7\xc4\xb6\x5a\x4c\x3c\x37\xf4\xe8\xd4\x7d\xe1\xd1\xc1\x85\x3b\x1b\x7b\x21\x9d\xcf\xe8\x60\x1e\x04\x5e\xb8\x98\xcf\x86\xfe\x6c\x4c\x07\xcb\x30\x9a\x4f\xe9\x60\x3e\x1b\xf9\xe3\xbb\x12\xfc\x11\x7d\x3d\x5f\x52\x37\xf0\xe8\xc2\x1d\xbc\x70\xc7\xd0\x63\x11\xcc\x5f\xfa\x43\x2f\x70\x0e\x06\x98\xbf\x02\xc9\x8b\xd7\x74\x3e\xa2\x7e\x84\x32\xc8\x39\x75\x8b\x82\x4a\x96\x73\x6a\x36\xcc\x50\xbd\x51\xb7\x9a\x2a\x49\xf9\x0d\x2f\xb7\xb4\x60\x6b\x4e\x8d\x30\x19\x27\xee\x62\x11\xcf\xdc\xa9\x47\xfb\x74\xac\xd6\xfa\x19\x1d\x2b\x3a\x16\x86\x86\xbc\xbc\x11\x09\x27\xe7\x34\xda\x70\x2b\x49\xad\xa8\xd9\x70\xaa\xb7\xda\xf0\x9c\x56\x9a\x97\x56\x78\x59\x49\x8d\x9d\x49\xb0\x9c\xc5\xcb\xd0\x0b\x68\x9f\xae\x85\x21\xe7\xd4\x13\x66\xc3\x4b\x7a\x94\xf2\x9b\x23\x87\x1e\x15\xa5\x4a\x8f\xa8\x2a\xe9\x91\xe1\xda\x1c\x61\xfb\xe9\x7c\x08\x83\xa7\xfc\x86\x90\x37\x25\x2f\x94\x16\x46\x95\xdb\x4b\x72\x4e\x03\xa5\x0c\x2d\x98\xd9\xd0\x95\x2a\xa9\x36\xaa\x14\x72\x4d\x77\x6d\x04\xd7\x1f\x6b\x9a\x32\xc3\x1c\x9a\xf2\x15\xab\x32\x43\x85\xa6\x47\xbf\xdb\xfb\x09\x4c\x0e\xe6\xfc\xd3\xde\x5a\xad\x75\xa7\xdd\xe5\x88\x04\xf3\x79\x44\xfb\xf5\xca\x74\x52\x8a\xc2\x50\xb3\x2d\x38\xd5\xbc\xbc\xe1\x25\xd5\x55\x51\xa8\xd2\x68\x87\x6a\x95\x73\x23\x72\xae\x69\xa2\xaa\x2c\xa5\x57\x9c\x1e\xe9\xcd\x11\x09\x07\x81\xbf\x88\xe2\xe8\xf5\x02\xa6\x7e\xc5\xf4\x86\x9c\xd3\x61\x3d\x05\x77\x16\xfa\x34\xd9\xb0\x52\x73\x83\x13\x67\x92\x56\xb2\xe4\x89\x5a\x4b\xf1\x15\x4f\x9b\x77\x04\x1a\xc6\x83\x0b\x37\x08\x3d\x3b\x9f\x91\x2a\x13\x5e\x6f\x91\xe4\xb7\xfb\x95\x6e\xa9\x51\x30\x78\x51\x8a\x1b\x66\x38\x19\xcd\x83\x81\x17\x2f\x02\xff\xa5\x1b\xc1\x0c\x56\x2c\xd3\xb0\x55\xe3\x4c\x5d\xb1\x8c\xe6\xec\x9d\xc8\xab\x9c\x26\x25\x67\x46\x28\x49\x33\x91\x0b\x03\xfb\xd7\x92\x58\xf0\x12\xf7\xd0\xa1\x9d\x13\x9a\x73\x26\x35\x95\xca\xb6\x24\x53\xf7\xf3\x78\x10\x78\x6e\xe4\xcf\x67\xf1\xc4\x9f\xfa\x11\xed\xd3\xce\x09\x39\xa7\x53\x51\x96\xb0\x17\x5b\x99\xd0\x2f\x2b\x5e\x71\x9a\x71\xb9\x36\x1b\x87\x0a\x09\xc3\x69\x4e\xc5\x8a\xe6\xfb\x56\xb0\x63\xda\xb0\xd2\x68\xba\x61\x72\x2d\xe4\x9a\x4c\xfd\x20\x98\x07\xf1\x67\x4b\x6f\xe9\xc5\x13\x6f\x36\x8e\x2e\x68\x9f\x9e\x1c\x1f\x1f\x93\x73\xba\x60\x26\xd9\x50\x80\xc7\x07\xe4\x17\x55\x96\xd1\x92\x7f\x59\x41\xb3\x62\xd7\xe3\x9e\xb1\x16\xcb\xc9\x24\x0e\xbc\xcf\x96\x5e\x18\x7d\xdf\x88\x25\x5f\xf1\xb2\xe4\x29\x9d\x88\x84\x4b\xcd\x35\x68\xbb\xc8\x58\xc2\x29\x33\x08\x79\xa3\x8a\x06\xfd\x99\xd0\x00\xec\x19\x18\x44\x5e\x69\x43\x73\x1c\x7e\x25\xb2\xda\x4a\x84\xa4\x89\x92\xab\x5e\x66\x85\x01\xda\x93\x4a\x1b\x95\xf7\xda\x8f\xc9\x22\xf0\x46\x5e\x10\x78\xc3\x78\xe2\x0f\xbc\x59\xe8\x85\xb4\x4f\xdd\x82\x25\x1b\xde\xcc\x83\x9e\x76\x8f\x1d\xd0\x7d\xfd\x1b\x30\x26\x34\xbb\xca\x38\x65\x57\x22\x13\x06\x61\x21\xa4\xe1\x25\x4b\x0c\xbd\x15\x66\x73\x60\x1c\xf4\x6a\x4b\x2f\xa2\x68\x41\x8b\x52\x19\x95\xa8\x8c\x0c\xfd\xd0\x7d\x3e\xf1\x62\x78\x1a\x8f\x71\x57\x1b\xe8\x78\xf2\xae\xe0\x5c\xac\x4b\x66\x78\x1b\x33\x57\x5b\x9a\xa9\x84\x65\x68\x94\xc4\x9b\xa1\xb0\xc9\x7c\xe0\x4e\xe2\x85\x1b\x5d\xc4\x53\x7f\x1c\x20\x68\x76\x82\xdb\x26\xdd\xe5\x29\x7c\x82\x65\x4f\x84\x46\x3c\xa2\xda\xf8\x3b\xc3\xa5\x16\x4a\xea\x9d\xb3\x02\x63\xdb\xb0\x1b\x50\xb7\xe4\xf4\xb6\x64\x85\x06\xc5\xc2\x06\x0c\x54\xca\x6b\x14\x5a\x79\x5d\x72\x4e\x43\x5e\x30\x9c\x6c\x4b\x16\xea\x83\xd1\x44\xe5\x39\xeb\xd2\x48\xed\x65\xe1\xb0\xb6\x81\xaa\xcc\xbe\x8f\x43\x7f\x0e\x3b\x5a\x54\xa6\xe9\x47\x26\xfe\xcc\x8b\x5f\x05\xee\x22\xf6\x3e\x8f\xbc\x59\xe8\xcf\x67\xb0\x51\x5d\xf3\xce\x38\xdd\x3c\x75\xba\x39\x2b\xaf\x53\x75\x2b\xe1\x97\xfd\xb8\x4e\x1d\x72\x4e\x5f\xb2\x4c\xa4\x76\x7d\xb9\x4a\x79\xbd\x34\x5c\x13\xa3\x45\xc9\x6f\x04\xbf\xa5\xee\xc2\xa7\x4c\x6b\x95\x08\x66\x78\x6a\x67\x6c\x36\x3c\x77\xa8\xae\x92\x0d\x65\x9a\xb2\x42\xf4\x6e\x4e\x7a\xcd\x28\x07\x6b\xbd\x61\x59\x65\x77\x19\xe7\xaa\xbb\x00\x65\x94\x6b\xd8\x15\xa8\x0b\xf4\x83\xa3\xd3\x5b\x25\x3f\xb6\x51\x00\xcc\x07\xd4\x78\xa8\x79\x9a\x2a\xae\xa1\x09\xa2\x19\xc0\xf9\xd2\xf7\x5e\xe1\xf6\x42\x60\x42\x27\x0d\xeb\x6e\xe6\x71\xb8\xaf\x55\x91\x29\x96\x5e\xee\x51\xd4\x82\x0c\x8e\x63\x1b\xe8\x6e\x0d\x99\x21\xed\x53\x53\x56\xdc\x9a\xfb\x06\xc0\x66\x78\x5e\xa8\x92\x95\x22\xdb\xa2\xa3\xdf\xf5\xa1\x0f\x1a\xd7\x8e\x81\x60\xcd\x8d\xa6\x49\xc6\x99\xe4\x29\xac\x1c\xc2\x0e\x2e\x15\x9d\x26\x1a\xff\x43\x12\x79\xd3\x05\x02\x12\xe2\x0a\x33\xac\x67\xf2\xa2\x57\xcb\x03\x37\x0b\x53\x02\x87\x5f\x6f\x0a\x2b\x39\x65\x59\xa6\x6e\x79\x5a\xfb\x59\xdb\x96\xa7\x0e\xe5\xdd\x75\x97\x8a\x9c\xad\x79\xef\xe7\x05\x5f\xff\x4d\xfb\xb5\x90\xeb\x2e\x9d\x70\xd8\x4c\x9e\x17\x66\x5b\xfb\x4f\x14\x42\x99\xac\x57\x0d\x43\x10\x77\x32\x99\xbf\xf2\x86\x18\x2b\x42\xf4\xf2\xd3\xda\x3b\x6b\xf1\x15\xc6\x54\xce\x1a\xff\x21\x24\x9d\x3e\x27\x56\xe1\xee\xe7\x71\xe8\x7f\x01\xce\xfd\x51\xab\x8f\xac\xf2\x2b\x5e\x36\x96\xa3\xad\x13\xc7\xc9\xa2\xcf\x86\xae\xb0\x4d\x4f\x08\x79\x53\x09\xd8\x90\xd9\xae\xc3\x81\x67\xd8\xad\x1b\x20\xc1\x53\x18\x59\x49\xc0\x43\x91\x81\xee\x81\x1f\x10\xef\xf3\xc5\x64\x1e\x78\xf1\x02\xc9\x47\x3c\x5b\x4e\x69\x9f\x9e\x1e\x1f\x08\x15\x5a\x57\xdf\x2f\x0e\xc5\xf8\x61\xb8\xbc\x23\xe4\xe4\x50\xc8\x2e\x5c\xa9\x3c\x17\x46\xdf\x11\xc2\x12\x23\x6e\xc0\x25\xad\x38\x4f\xc9\xc8\xf3\x86\xa8\x9c\xc1\x7c\x3a\xf5\xa3\x5a\xe0\x13\x6b\x70\x15\xea\xf3\x08\x2c\x88\x77\x12\x95\xa9\xf2\x88\xe6\xdc\x30\x6a\xd8\xda\x81\x60\x87\x90\x71\x65\x5a\x2a\x91\xd2\x9f\xf6\xe9\x93\x2e\xcc\xc4\x95\x54\xc8\x1b\xb4\x57\xec\x44\x33\x71\xcd\xe9\x91\x54\x92\x5b\xb2\x92\x5a\xaf\x7b\x44\x6f\x45\x96\x59\x1b\x06\x13\x6a\x80\xa9\xcd\x36\x03\x2c\x4f\x41\x75\x42\xae\xd4\x33\xba\x31\xa6\xd0\xcf\x7a\xbd\x94\xdf\xf0\x4c\x15\xbc\xd4\xdd\xb5\x52\xeb\x8c\x77\x13\x95\xf7\x6e\xf9\x55\xaf\x2a\x52\x66\xb8\xee\x9d\x1e\x9f\x3c\xee\x9d\x9c\xf4\x42\x4b\x3a\x3a\x2b\x55\x76\x5a\x0b\xe8\x08\xd9\x19\x6c\x4a\x95\xf3\xce\xa3\x4f\xf1\x65\x3d\x7d\x12\x5d\x78\x53\x2f\x1e\xcc\x27\xf3\x20\x9e\x7a\x91\x1b\x47\xee\x98\xf6\xe9\xdb\x1f\xad\x56\x4f\x1e\x3d\x7e\xf4\xd6\xa2\xc6\xa2\x4c\x48\x7a\xb5\x35\x5c\xef\x81\x63\x71\x9e\x0a\x5d\x64\x6c\xcb\xd3\xbd\x95\x09\x4d\xcf\xa6\xcf\x1f\x22\x9c\x86\x7e\xb8\x98\xb8\xaf\xad\x0b\xa8\xd1\x78\xf6\xe8\xec\xec\xe9\xf1\x19\x02\xac\xcb\xd2\x5c\xc8\x43\x98\x01\xa5\xf8\x30\x20\x80\x20\x1e\xe2\xe1\xc9\xf1\x77\x91\xfa\x41\x11\x81\xb7\x98\x7f\x50\x84\x54\x46\x24\xff\x17\x60\xce\xe6\x91\x3f\xb8\x0b\xef\x27\x07\x62\x54\xb9\x66\x52\x7c\x65\x49\xd4\x87\x64\xcd\x83\xf1\x77\xe6\x83\x1a\x02\x75\xdc\x63\x87\x7f\xc5\xd5\x9d\x80\x41\x37\xbe\xb7\xe5\x67\x37\xac\x4c\x6d\x58\xbb\x2a\x39\xbb\xde\xfb\xf3\x26\x36\x5f\xb8\x01\x10\x8c\x99\x17\x3f\x0f\x3c\xf7\x45\x2b\xde\x37\x11\xd8\x72\x13\xba\x0c\x26\x9d\x30\x01\xdc\xdd\xe3\x14\x99\x86\x41\xae\x35\xbd\xdd\x70\x49\x4b\x2e\x53\x8e\x4c\x7c\xda\x44\x83\x73\xe4\xb9\xfc\x1d\xcb\x8b\x8c\x03\xf5\x77\x72\xb6\x96\xdc\x10\x9b\xe3\xc4\xcb\x60\x12\x87\x03\x00\xac\x75\x81\x3f\x24\xfc\x5f\xf1\x7a\x24\x9e\xf6\x20\x90\xd9\x79\xb4\x86\xfc\x41\x31\xdf\x8a\x68\x02\x7e\x4f\xb5\x42\x1e\xd3\xbb\x70\x76\x4f\xe0\x47\xcc\x1f\xc6\xfc\xef\x0b\xf7\x84\xbc\xb1\x99\xc3\x25\x59\x04\xf3\x68\x3e\x98\x4f\x68\x1f\x5d\x00\x19\xce\xa7\xae\x0f\x6c\x08\x69\xd3\x46\x69\x83\xd9\x07\x28\x84\xf6\xe9\x8f\x1f\x34\xed\x1f\x82\xb3\xf8\xf1\x03\xdb\xfc\xa1\x7e\xf6\xe3\x07\x48\xd1\x16\xf3\x20\x7a\xa8\x7b\x04\x7f\xb8\xc3\x21\x24\x56\xc7\x5d\xfc\x9f\xec\x1a\x40\x88\xa8\x99\x2c\x2f\x73\xa1\x71\x71\xb0\x1f\x95\x14\xef\xa8\x56\xc9\x35\x37\x64\x39\xf3\x3f\x8f\xc3\xf9\xe0\x85\x17\xc5\x0b\x2f\x98\xfa\x61\x68\x69\xda\xd3\xa7\x4f\x61\x43\x90\xd5\x3d\x18\x4e\xbf\x78\x08\x50\xc0\xee\x18\x5a\x6f\x55\x79\x0d\x06\xfd\xa0\x21\x24\x61\x78\x41\xad\xef\x7a\x48\x59\x92\x70\xad\x01\x09\xb7\xfc\x0a\xb3\x27\x91\x70\xa0\x28\xbe\xa4\xb9\xd2\x86\x26\x0c\xd8\xf4\x56\x55\x34\x55\x60\x93\x54\x72\x1b\x63\x13\xe0\xe7\x87\x5e\x14\xd9\x0c\x74\x76\x33\xc3\x4b\x0a\xf9\x8a\xcc\xb6\x40\x57\xb6\xaa\x2a\x71\xdc\x3a\x3f\x93\xc0\x68\x84\x46\x81\x98\x90\x02\xed\x66\xda\x72\x5d\x78\xd9\x25\x96\x93\x7e\x48\xd5\x3b\x95\x7e\x57\xdb\x7b\x9a\x0d\x83\xae\x38\x33\x55\xc9\x2d\xf6\x61\x48\x76\xc3\x44\x06\xaf\x77\x74\x1a\x9a\xed\x2d\xeb\xd5\x86\x63\xd2\x5b\x69\x4e\xaf\x2a\x91\x19\x21\xdb\xb3\x57\xb0\x00\xd3\x25\x61\xe4\x06\x11\x74\x8d\x43\x2f\x78\x89\x39\x73\x23\x61\xa8\x72\x26\x64\x9d\xbe\xa3\xa3\xe6\xef\x0a\xa5\xad\x9b\x00\x51\x49\x06\xce\x62\x19\x4c\x08\xf4\xdf\x81\x6c\x0f\x20\x00\x83\x2a\x4d\xc3\x17\x7e\x80\x90\x1a\x49\xa7\xa7\xe0\xac\xb8\x81\x7d\xb7\xa9\xc5\x0a\xf2\xa0\x7b\xd6\x01\x89\x10\x97\x9a\x2a\x89\xfd\x27\x7e\x18\x79\xb3\xf8\x62\x1e\x46\x2d\x90\x1e\x4e\xe3\x07\x4b\xa9\x27\xf3\xe3\x07\xcd\xcc\x70\x45\xfb\x72\x80\x5a\xa1\x8c\x54\x94\x3c\x01\x96\x79\x90\xff\x7f\xfc\xbb\xbd\xae\xd6\x9b\x8f\x1d\x7a\x55\x19\x04\x9f\x8d\xd8\x0a\x77\xe4\xe3\xde\x46\xe5\xbc\xb7\x16\xc6\xb6\xea\xe2\xb8\x88\x14\xcb\x18\x71\xfb\x6b\xb9\x08\x55\x48\xa2\xf9\x8e\xa0\x6e\x1b\x5f\x02\x70\xc0\x34\xb5\xa8\xae\x32\x91\x5c\xd3\x6b\xbe\xa5\x15\x5a\x83\xd6\x9b\xce\x35\xdf\xae\xb9\x84\x4c\xa0\x35\xb5\xba\x74\xb2\x97\xb5\x5b\x81\x9d\xc6\x0b\xef\x75\x1c\x41\xa6\xba\x9b\x4a\xc3\x8f\x5b\x22\x0f\xd6\xba\x7f\xfe\x31\x65\x32\xa5\x19\x07\x07\xca\xb3\x8c\xae\x84\x4c\x29\xa4\x37\xb7\x1b\x91\x6c\x30\xba\xc0\x6a\x58\x96\xed\xc6\x1a\x83\xaa\x2d\x4d\xde\xcb\x41\xf3\x4d\x45\x02\x8b\xbe\xad\xa1\x8c\x16\xcb\x93\x6b\x9a\x0b\x89\x54\x0d\xd6\x8a\xcc\x02\x1d\x6e\xa2\xca\x92\xeb\x42\xc9\x14\x56\x8f\xb4\x77\xea\xcf\xfc\xe9\x72\x8a\x2b\x02\xe6\x10\x0f\x2e\xbc\x41\x3b\xfe\x34\x26\x36\x18\xce\x80\xbc\x03\x05\x6b\xea\x43\x90\xb1\x90\xf9\x68\x84\x71\xab\x2e\x0f\xd9\x6e\x8d\xc1\x05\xf3\x65\xe4\x05\xf1\x64\x3e\x6e\x17\x3f\xb8\xe4\x18\x0f\xb4\xe1\x85\x7e\x46\xce\xe9\x5f\xa3\x5d\xac\xff\xd0\x84\x97\x86\x76\x12\xd6\x87\xac\x83\x76\xd2\xaa\xc4\x90\xde\x3f\xfb\xe4\xe9\xf1\xe6\x38\x3f\xd6\xb4\x03\xbe\xb9\x9f\x6f\xe1\xa3\x5b\x07\x32\xe0\x6a\xe4\x9c\x9c\xd3\x79\x49\x57\xa5\xca\x29\xa3\xdd\x62\xf5\xae\x89\x5a\x40\xd7\x78\x6a\xdf\x80\x1b\x7a\x25\x64\xaa\x6e\xed\x60\x62\x65\x15\x68\x53\x99\x07\xa9\x22\xe7\xe8\x3b\x56\xaa\x5c\x73\x03\xfa\xb4\xfd\xb1\x63\x5d\xd5\x01\xa5\x3e\xb4\xd3\x56\x05\x97\x5a\x67\xb4\xb8\x4e\xf4\xc9\x29\xed\x08\x89\x52\x71\xf4\x0e\xec\xa9\xfd\xc5\x73\xda\x91\xea\x9a\x6f\xf5\x0f\xeb\x75\xcd\xb7\x4d\x27\x78\xa1\xe1\x4b\xca\x35\x19\x78\x41\x84\x24\x8f\xf6\x9b\x5a\x05\x12\xd8\x5e\x33\x0c\x81\x6d\xbc\xaf\x41\x2d\x91\x9c\xd3\x65\x01\xb9\x48\x06\x7c\x17\x4b\x25\x3c\x2f\x32\x58\x14\x80\x52\x1b\x66\x44\x62\xf5\x86\x95\x83\x03\xa3\x40\x15\x00\xcc\x6f\x37\xbc\xe4\x75\x46\xa7\x29\x7f\xc7\x93\xca\xf0\x14\x1c\x65\xe4\x0f\xee\x9a\x68\x3b\x29\x84\x68\xe5\x16\x05\xe6\x7a\x58\xd0\x1c\xba\x91\xdb\x4e\x00\x6d\x3d\x34\x83\x3d\xc1\x72\x18\xce\x72\xfc\x85\xbf\x68\x6a\x7d\x0d\x5f\xc2\x67\x2d\x92\xc4\x2c\xa4\xb1\x5e\xba\x42\xcf\x2d\x3b\x99\x5a\xaf\x79\x6a\x89\xae\x43\x13\x26\xb1\x2c\x08\x5e\xc5\x66\x0b\x75\x12\x75\x44\x26\x2e\x16\x7a\x81\xca\x81\xe2\xa0\x05\x21\x6f\x40\x71\x97\xbb\x7c\x05\xa7\x8e\x61\xb4\x33\x50\xd2\x94\x2a\xeb\xb8\xc0\xba\x3a\xf3\x52\xac\x85\xa4\x1b\xce\x52\x5e\x1e\xd8\x3c\x86\x3d\x45\x8b\x92\x6b\x2e\x0d\x71\x07\x03\x2f\x0c\xe3\xc1\x7c\x16\x05\xf3\x49\x8c\xf9\x66\x3c\x0f\xfc\x31\x86\x04\x62\x75\x05\x14\x71\xc7\xe6\xb2\xb5\x2a\x85\xd9\xe4\x1a\x37\xc7\x6c\xb8\x28\x0f\x0c\xdb\x56\xdc\xe8\x03\x70\x97\x9d\x13\x18\x2b\x6d\xca\x4e\x68\xdc\x0f\xc9\x1b\xad\x37\xdd\xba\x4b\x7c\xcd\xb7\x31\xf8\x02\x7d\x49\xbc\xe1\xe9\x93\x27\x27\x9f\x22\x91\x7e\x4a\xbc\xc1\x30\x74\x29\xad\x7f\x05\xf8\x1d\x7f\x1d\x3f\x3e\x23\xc3\xdd\xcf\x93\xe3\xd3\xc7\x84\xbc\x81\x7d\xba\x62\x9a\x5f\xb6\xca\xc6\xf9\x56\x7f\x99\x61\xe1\x58\x69\xb3\x2e\xb9\xb6\x1a\xd6\x5f\x66\xc2\xf0\x47\x47\x0e\x7a\x77\xd8\x81\x44\x49\xc9\x13\xd4\x4b\x24\x86\xcf\xad\x5b\x9a\x6e\xc3\xcf\x26\xad\xe2\xd7\xf3\xa6\x60\x8b\x62\x49\x1d\xaa\x4e\x4e\x3f\xc1\x60\x75\xf2\xec\xd1\xa3\xe3\xa7\xa4\xae\x85\x83\xdb\x20\x75\x29\xbb\x54\xca\x90\x85\x1b\x86\xaf\x86\x4d\x99\xf6\x60\x46\x32\xdb\x3a\x94\x37\x95\xee\x3a\x57\x74\xe8\x51\xc9\xbf\xac\x44\x59\xa3\xe2\x86\x97\x62\xb5\xed\xac\xaa\x2c\x3b\x22\x61\x38\xd9\xd5\xbd\x6d\xfb\x46\x6c\xb3\x34\xdc\x9a\x23\x23\xd2\xab\x23\xcc\x5c\x29\xbb\xd2\x2a\xab\xcc\xde\x54\x24\x2e\x1e\x2b\x1e\x40\x7e\x6a\xf6\x45\xda\x65\x0f\x58\x44\x37\xbd\x22\xe4\x4d\x9d\xa8\x01\x51\x4d\xaa\x52\x98\xed\x25\xf1\x67\x61\xe4\x4e\x26\xf1\x64\x7e\xe0\x97\x3f\xfa\xc8\x1e\x58\xd8\x73\x8d\x68\x4e\x5f\x78\xde\x82\xbe\x9e\x2f\x03\x8a\xea\x00\xd3\xa2\xa1\x3b\xf2\x3e\xfa\x88\x84\xde\x20\xf0\x22\xf0\xf1\xb4\x4f\x3f\xfa\xd1\xcf\x46\x43\xef\x55\xe0\xbd\x0a\xfe\xfa\xdf\x78\x00\x16\x57\x19\x05\xc6\x22\x20\x65\xc8\x39\x32\x80\x94\x6d\x35\x99\xcc\xc7\xfe\x2c\x0e\xbc\xa9\x37\x7d\xee\x05\xf1\xd0\x7d\x0d\xf4\xfa\x13\x32\x98\xcf\x5f\xf8\x1e\x1e\x20\xb4\x76\x21\x66\xb7\x5c\x83\xe9\xd4\xaf\x77\xfd\xda\x6d\xb0\x38\x9c\x0a\xab\xc8\x80\xdf\xf0\x52\x83\x5f\x55\xef\xb6\x94\x55\x66\xc3\xa5\x69\x6c\xdf\x1a\xd4\xee\x40\x03\x4f\x31\xe0\x07\x09\xbc\x97\x5e\x10\x7a\xf1\x22\x98\x7f\xfe\x3a\x76\x97\xd1\x85\x37\x8b\xfc\x81\xad\x81\xd7\x48\xf8\xbc\xf3\xca\x7b\x0e\xaf\x3a\xf0\xa0\xe6\xfd\x22\xe1\x97\xc4\x1d\x44\xfe\x4b\x48\xc7\x87\x5e\x3c\x81\x6f\x53\x7f\xb6\x8c\xb0\x18\x73\x72\x76\x4c\x02\x2f\x04\xe2\x8d\x18\xfa\xde\x46\xe7\x74\x89\xb3\x69\x38\xb2\x92\x2b\x51\xe6\x94\x77\x72\x26\x32\xf4\x14\x25\x5f\x0b\x6d\x6c\xf0\x22\x81\x37\x06\xb6\x14\xc4\xde\xd4\xf5\x27\x31\x9e\x23\x05\xd3\x03\x1a\xc9\xad\xb7\xb0\x75\x29\xdb\x99\x97\x08\x2d\x04\x44\xc3\x6d\x58\x92\xa8\x4a\x5a\xc2\xbd\x8f\xb1\x28\xfe\x4e\x39\xb7\x9e\x22\x16\xbe\xb5\x58\x63\xd4\x36\x8a\x62\xd1\x91\xc9\xad\xd9\x08\xb9\xee\x92\xc0\xfb\x6c\xe9\x07\x5e\x1c\xfa\xe3\x99\x3f\x8b\x5f\xfa\xde\xab\x96\x84\x29\xac\x06\x12\xf4\x55\xbd\x27\x8d\xf3\x85\x84\x7c\xf4\x3a\x86\xd5\xb4\x9b\x43\x04\x4d\xb9\x61\x22\xdb\xd7\x55\xd6\xc2\x6c\xaa\x2b\x2c\xa6\xac\xd5\x5a\x18\x8d\x58\xef\xd9\x72\x54\xef\xe4\xe9\x93\x46\xe6\x87\x76\x75\x37\xc8\xf7\xb5\x9d\x7f\x9f\x12\xea\xf4\x3b\x61\x85\x49\x36\x8c\x62\xed\xc8\xc2\xeb\x3b\xbb\x54\xcb\x1e\xb8\x8b\x68\x70\xe1\x36\x85\x4f\xf2\xe6\x96\x5f\x6d\x94\xba\x06\x6f\x77\xa1\xd4\x35\x35\x4c\x5f\x7f\xe0\xc4\xa3\x6e\x0e\xc9\xb1\xba\xef\x9c\xe3\xfe\xa3\x8d\x21\xcf\x04\xb0\x6c\x23\x72\x0e\x04\x40\x48\xaa\x79\xa2\x64\xaa\xc9\xd0\x03\x04\x06\x71\xe4\x4f\xbd\xf9\x32\xaa\x8b\x68\x18\x7b\xa8\x90\xe8\x26\x78\x8b\xca\xc0\x52\xc2\x17\xfe\x22\x8e\x26\x61\xfc\xd2\x0b\xfc\xd1\xeb\x96\x3e\xf6\xd5\x8d\x8d\xd0\x48\x9c\x85\x5c\xa9\x32\xb7\x3a\x11\xd2\xd6\x38\xb1\xb8\x71\xb7\x10\x48\xde\x00\xba\x21\x77\xde\xd7\x86\x1b\xb1\xcf\xab\xd5\x0a\x49\x05\xc6\x23\xb5\xc2\xb4\x51\xf2\xcc\xa1\xd7\x9c\x17\x90\x22\x32\x0d\x7f\x85\xae\xd3\x44\x9a\x62\x9d\xfb\x5a\xaa\x5b\x7a\xbb\x61\xc6\xbe\xec\x92\xd0\x9b\x0d\xe3\xe7\xcb\xd1\x08\x48\xa3\x37\xb3\x0a\x6a\x4e\x71\xf6\x45\x30\x21\x29\x9a\x9a\x3d\x19\x0d\x97\xcf\x7f\xc7\x1b\xd8\x3c\xa4\x39\x25\xc5\x3c\x04\x01\x6c\xf3\x17\xa0\x9d\x39\x22\x53\xe7\xa6\xe8\xae\xe1\x3b\xa0\xf2\xd9\x93\xb3\x4f\xc8\x39\xfd\xec\xb3\xfa\xc5\x97\x5f\xe2\xd3\xc7\x4f\xb1\xbe\xa4\x0c\x77\x9a\x3a\x3c\xb2\x40\x2e\xd3\xba\x76\x71\xf4\xf8\xe9\x93\x23\x87\x86\xd3\x68\x11\xda\x72\xe3\x15\xc7\xca\x65\x97\x2e\x31\xb7\xc0\xb4\x31\x9a\x84\x54\x49\xdb\xf7\xc9\xd9\x27\xa0\x80\x92\x27\x2a\xcf\xb9\x4c\x79\x8a\x55\xe1\x60\x34\xa0\x4f\x1f\x1f\x7f\xda\xa5\x7e\x7d\x6c\x7b\x78\xb8\xb9\x17\x24\x8c\x1d\x88\x65\xb7\x6c\xab\x77\xe3\xd5\xf1\xb1\x45\xd5\x2f\xbc\xc9\x1c\x48\xa6\x45\xb6\x8d\x41\xc0\x97\xd1\x97\x32\xb0\x52\x01\xfb\xc5\xa5\xe9\xee\x4f\x9a\xa0\x0f\x08\x19\xd8\x3a\xd3\xae\x3d\x18\xca\xa1\xc0\x03\x92\x83\xac\xda\xa6\x4b\x5d\x02\xed\x30\xb3\xb4\x2e\x1f\x5d\x1b\x3a\x36\x1b\x54\x71\x79\x6d\xd6\xad\xda\x2b\xee\xd2\xb9\xcc\xb6\x18\x43\xcd\x06\x24\xab\x92\x6a\x9e\xad\x3a\xe0\xbf\x78\xda\xee\xa8\x2d\xc4\x1b\x78\x5b\x6f\x47\x93\x4c\x70\x69\xda\xed\x80\x18\xc4\x40\x9a\xfd\x11\xb8\x92\x7d\x7e\x72\x0f\x91\xb6\xe8\xfe\x10\x93\xae\x5b\xec\xa9\x34\xe2\xcb\x26\x1c\x69\x5a\x72\xad\x1d\xdc\xcd\x27\x8f\x4e\x4f\xbb\x34\x82\x35\xd4\xa4\x13\x8b\x56\x4c\x52\x8e\xa8\xdd\x35\x56\x25\x2e\xff\xed\x11\xc0\xfb\x88\xfe\x04\x5f\xff\xac\x95\xd4\xfc\xf4\x2d\xb5\xd6\x49\x46\xc1\x7c\x5a\x1f\x4a\xc0\x24\xf6\xe1\x10\x83\x44\xc1\xb4\xbe\x55\x65\x5a\x13\xa1\x36\x07\x02\xc5\x18\xfe\xce\xf4\x36\x26\xcf\xf0\xa0\x2a\x33\xbc\x94\xcc\x88\x1b\x5e\x0b\x47\x83\x55\xd2\x00\x49\x6d\xca\x91\xd1\x14\x18\x6a\x04\x01\x1e\xe2\x65\xeb\x98\x30\x61\xc9\xe6\x90\xfb\xf1\x5c\x95\x5b\xcb\xa3\x52\xa1\x8f\x70\x5d\xf0\x14\x5b\x1e\x1d\x1e\xf9\xd7\x8d\x89\x3b\x74\x17\x11\x86\x6a\xfb\xa4\xa1\x55\xf5\xfb\x9a\xab\x8d\x07\xb6\xb4\x71\xc3\xb2\x96\x4b\x3c\x90\xf8\xf4\x98\xf8\xb3\xc8\x0b\x5e\xba\x10\x8b\x9e\x1e\x37\x82\xec\x5c\x2c\x3b\x6b\xcd\xa5\xe6\x9f\x48\x30\x14\x6c\x8a\xdd\x0b\x72\x4e\xb1\xc3\x33\x2a\x6d\x49\xa5\x6f\x92\xc2\x81\x97\xfd\x67\x4f\x1f\x7d\xf2\xa9\xd3\x68\xb8\x9f\xb3\x84\x95\x4a\x3a\xe9\x55\xff\xd8\x29\x94\xca\x90\x52\xf7\x4f\x8e\x8f\x1d\x91\x66\x3c\xae\x3d\x78\xdf\xf2\x84\x66\xe4\x67\xf4\xed\x9e\xbe\x9e\x9c\x9c\x9e\x9c\xbc\x6d\xcc\x16\xb8\x09\x96\x02\xef\xd7\x29\xe4\x62\xb5\x4a\x1b\xf5\xde\xa7\xcf\xe6\xc6\x49\x5b\xa1\x8b\x52\xdd\x08\xe0\x50\x48\x50\xd6\x54\x15\xb0\x6e\x6d\xa7\xa5\xca\xed\x33\x34\x4d\x7b\xd2\x29\xb7\x4d\xab\x2d\x37\xe4\x1c\x53\xc0\x67\xb4\x9e\xd9\x3e\x21\xac\xcf\xd9\xde\x22\x6b\xad\xdf\xea\xb7\xff\xdf\xb4\x07\xf4\xff\x19\x5d\xab\x8e\xfe\x32\xeb\xa4\x25\x84\xc8\x1e\x3e\xa4\xa9\x96\xcd\x84\xb5\x29\x85\x5c\x37\x33\x83\x1c\xe0\x59\x33\xde\xcf\x9a\x39\xc6\x06\x1c\xe3\xdb\x9d\x9a\xe2\xfa\x32\x4f\xcd\xbf\x9b\x95\x60\xb1\xda\x2e\x39\x51\xea\x5a\xd8\x9b\x02\x0d\xa1\xad\x79\xac\x88\x33\x71\xcd\x63\x4b\x67\xc8\x39\xb8\x6d\x88\x68\xe0\xb7\x1a\x7d\x41\x3e\x08\x04\xa8\x86\x71\xdb\x5d\x5a\xf7\x63\x05\x86\xde\x60\x19\x78\xdf\xa5\x2b\x9a\x9b\x7a\xfc\x83\xbe\x48\x48\x6a\x03\x05\x96\x6a\xa5\xec\x8f\x68\x9b\xa9\x8f\x07\xc8\x23\x76\xa6\x73\x20\xe4\xec\xe9\xe3\xe3\x63\x32\x1e\xc4\x8d\xd5\x20\xb1\xa0\xfd\xfa\xc5\x5e\x4a\x26\x56\x1c\xe5\xdc\xd3\x3d\xf4\xb0\x2a\x1d\x4f\xfc\x91\x77\xd8\x9f\xbc\x29\x44\x62\xaa\x12\x3d\xc4\xae\x26\x66\xcf\x89\xf5\xee\x0c\x14\x92\xdb\x1b\x66\x58\xa9\x89\xfb\xd2\x8d\xdc\x20\x5e\x2e\x26\x73\x77\x78\x70\x16\xdc\xb4\x38\xa7\x83\x8d\x90\x5c\xf3\xfa\xc8\x0a\xd3\xc8\x8d\x52\x9a\xd3\xa3\xb4\x52\x7a\x53\xa9\x23\x72\x0e\x16\xc2\x9a\x43\x12\xdb\x95\x6a\x55\x95\x09\x77\xf0\x98\xd0\x52\xd2\x67\xbd\x5e\x22\xbb\xeb\xd2\x36\x40\x5a\x6a\xbf\xf6\xc8\x38\xa8\xa7\x12\xce\x97\xc1\x00\x13\x96\xba\x19\x5e\x40\x12\xda\x16\xbe\x77\xb1\x7e\xa5\xca\x64\x77\x0e\x8d\xe5\x2a\x21\xa9\x5a\xad\xf0\x94\x27\xc7\xe2\x76\x13\x5b\x1b\xd1\xad\x9d\x1e\xf1\x14\x6b\x60\x8d\x22\x68\xa6\xd4\x75\x55\xc0\x12\x35\x1d\xce\xc2\x3a\x99\x4f\x14\x50\x81\xba\xc9\xfe\x02\x02\x39\xb7\x24\x04\x03\x86\x76\xa8\xe6\x7c\xc7\xb8\x6f\x6f\x6f\xbb\x99\xb8\x6a\x96\xa8\xca\xf5\x0f\x98\x3f\x4e\xeb\xee\x02\x40\xa5\xe3\x5a\x0e\xec\x7d\x2a\xf4\x15\xcb\x80\x71\xd4\x20\x1c\x79\x43\x2f\x70\x23\x6f\x18\xef\xd6\x57\x93\x66\x66\x0c\x4b\x36\x39\x97\xe6\xb2\x55\x68\xdf\x3f\xd5\x48\x43\x38\xc2\x3d\xed\x36\x45\x22\x3c\xed\x7c\x0b\x22\xde\xd6\x43\xdc\xb9\x7f\x80\x97\xb4\xf6\x42\xee\x74\xb4\xa8\xd9\xbf\x7e\x7b\x90\x63\xb7\x5e\x90\x73\x3a\x97\xb8\xbc\x5c\xb5\xaf\x14\x6c\x0b\xae\x3f\x70\x93\xe0\xee\x15\x81\xfb\x1b\xb5\x4e\x73\xdb\x77\x06\x0e\xe7\xfa\xe8\x74\xfa\x9c\xb4\xae\x0e\x3c\xae\xbb\x7d\xff\xb5\x81\xc3\xfe\x27\xc7\xdf\xb9\x46\x00\xa6\x0a\xca\x0e\x0b\x9e\x88\x95\xbd\x3b\xb0\x8b\xf0\xa0\xb8\x55\x95\x65\x5b\xaa\x2a\x53\x54\x80\x3b\x3c\xd5\x3e\x94\x1a\x8c\x06\x27\x27\xa7\x8f\x1a\x21\x2c\x6b\x48\x28\x4f\x9b\x3b\x2c\xb0\x6d\xee\x2c\xf4\x07\x0e\x5d\x4a\xf1\x6e\xc8\x80\x21\x07\xd5\xd5\xb6\xfe\x36\x1a\x9c\x9d\x9e\x36\x9f\x5f\xd8\x2f\x4f\x8e\x9d\x46\xf4\xee\x8b\x7d\xf5\xe8\xd1\xa3\x4f\x77\x5f\x66\x4c\x2a\x87\xbe\x10\x26\xd9\x70\xe9\xd0\xd0\xb0\xbc\xa8\x3f\xa6\x22\xcb\xc4\xee\x7b\x52\x2a\x8c\xeb\xf8\x13\x7a\xd5\x31\x3f\x6f\x8e\xf5\x9b\x7c\x86\x5d\x41\x2e\xd5\x52\x43\x63\x27\x90\x98\xaa\x8c\xc9\x35\x98\x47\xaf\xb8\x5e\xf7\x40\x7b\xbd\x1f\x15\xd7\xeb\x4e\xa2\xa4\x36\x0c\x50\x32\x9a\x07\x53\xd7\x86\xe8\x4c\xad\x2f\xc9\x61\x61\x73\x50\xd7\x13\xa1\xbd\xca\x78\x4d\x35\xea\x70\xdd\x0e\xd1\x4d\x83\x86\xa5\xaa\x3c\x67\xe8\x15\x9b\x63\xd1\xbc\xca\x8c\x28\x9a\xfb\x47\x35\x00\x9b\x6e\x0e\x22\xe1\x88\xd4\x55\xa8\xfa\xe9\xff\xcb\x9c\xeb\x9e\x74\xab\xa1\x21\x51\xc9\x12\xac\x90\xf9\x72\xa5\xe0\xf3\x15\x2b\x25\x7c\x7a\x65\xa9\x4a\xf8\x32\x62\x86\x65\x77\x16\x6c\x7b\x91\x89\xf7\xd2\x03\x4e\x86\x3f\x49\xc3\xcb\x76\xea\xb2\x1e\x46\x66\x5b\xd4\x6e\xb7\x7e\x7e\xd9\x74\xdb\x75\xc0\xe5\xdf\x6d\x0d\x0f\xf7\x4d\x6b\xff\x66\xdd\x89\xa6\xac\x32\x2a\x47\xdf\x9a\xa9\x35\x2d\x95\x01\x25\x3f\xd0\xb7\x80\x2c\x34\x2d\x05\x06\x0f\x39\x5a\xcd\x88\x1e\x92\xc9\x7c\x1c\x07\xf3\xc8\xa6\x08\xbb\x70\xba\x06\x6f\x81\x42\x52\x26\xb2\x2d\x19\xba\xfe\xe4\xf5\x77\xda\xed\xcc\x5d\x6f\xc4\x0a\xc9\x34\xe4\x7f\x99\xbd\xb9\x75\xa0\x99\xd3\xb3\xfa\xfe\xd1\x09\xfd\xc9\x4f\xe8\xe9\x99\x43\x4f\x9f\x3c\x6d\x39\x82\x38\xbc\xf0\x47\x78\xb8\x77\x56\xcb\x45\x5f\xbc\x77\x0a\x2d\xc1\xd8\x69\xe2\xcf\x6c\x51\xea\x18\xff\x83\x9d\x7b\x57\x88\x12\xad\x7b\x8b\x97\x48\x60\xf2\xc8\xde\x1e\xa4\x3c\xe3\x86\x53\xb6\x32\xbc\xa4\x39\x7b\x87\x4d\xea\xeb\x23\x4d\x61\x8f\xbc\x49\x4a\xd5\xbe\xb7\x50\x56\x52\x82\xa2\xe0\x31\x56\x3e\xd0\x25\x09\x95\x8a\x84\x65\xd9\xf6\x9e\x7b\x62\x41\x25\xdb\xad\x31\xf7\xc4\x93\x02\x5b\x07\xe9\xe2\x55\x62\x37\x8a\x31\xab\xdd\xa7\x15\xe7\x74\x89\x67\xd5\xf5\x8d\x54\x6d\x67\xd2\xb5\x07\xd8\x71\xfd\xf0\x92\x84\x83\x0b\x6f\xb8\xc4\xb8\xf0\x33\x7b\x93\xec\xe4\x38\x27\x58\x4a\xdc\x5d\x64\xdb\x70\x96\x99\x8d\x3d\x07\xab\xc5\x94\xbc\x50\xb1\x7d\x1e\xe3\xf3\xfb\x24\x9d\x3e\xde\x90\x7d\x91\xe5\xe9\x31\x84\x09\xb7\x5c\x57\x36\x5e\x81\x07\x45\xd3\x95\x29\xfd\x78\x2d\x0c\x5d\xe9\xe4\xfa\xe3\xc6\x58\x3b\x9d\x4a\x96\xe0\xeb\x51\x6b\x9d\x8e\x61\x6b\x0d\x06\x0f\x0e\x07\xdd\x92\x92\x3b\xc7\x23\x4c\x47\x27\x39\x72\x8f\x54\x25\x1a\x1f\x80\xb0\xde\x49\xf7\x93\xee\x13\xe2\x06\xe3\xd0\xc2\x7f\x80\x27\x79\xad\x2b\x7a\x78\x3c\xa3\x8d\x48\x1a\xf5\xe0\x5a\x62\x5c\x1d\xbc\xd3\x97\x77\xb5\x8b\x9b\x72\xff\x52\xc9\x9b\xb5\xc0\xe8\x5c\x57\x0d\x34\xdd\x88\xf5\x26\x13\xeb\x0d\x62\x98\xa5\xc8\xd2\x64\x4a\x4b\x9e\xab\x1b\x7b\x1b\x5a\xae\xb9\xde\xb1\x9a\xa1\x3f\x1a\xc5\x17\xfe\xf8\x62\xe2\x8f\x2f\xa2\x83\xba\x61\x3b\x90\x01\x84\xf5\x2e\xc6\x82\xe4\x36\x8c\x81\x73\xa4\x62\xb5\xc2\xca\x24\x82\x71\xec\x47\x56\x74\x1b\xdc\xdf\x91\x9a\x6c\x58\xc9\x12\x03\x7c\x10\x45\x66\xed\x83\x93\x0f\xcb\xc4\x9b\xdc\xee\x20\xf2\x02\x0c\x9d\xf7\x08\xb7\xb1\x57\x6f\xd4\xad\xfc\x80\xac\x26\xf8\x5a\x97\xf9\x01\xa4\xac\x93\x16\x4e\xd8\x7a\x0d\x09\x27\x64\xdf\x9d\x0e\x78\xaa\xbf\x0a\x4c\xd6\x49\x0d\x92\xf1\x20\xde\xe3\x64\xbe\xab\xf4\xdc\x53\x3e\x84\x5d\xee\xd6\xcf\x2f\x89\xbd\xf7\xeb\x21\xbe\x8f\xeb\xfb\xdd\xf6\x5a\x0a\x19\x4c\xe6\x33\xaf\xfe\xbe\x58\x4e\x26\xf5\xd7\xf1\xc0\xa6\xd5\xe4\x8d\x35\xc2\xcb\xd6\x99\x5e\x3b\x37\xdf\xa8\xaa\xd4\xf4\x8a\x9b\x5b\xce\xeb\x32\xa2\xb5\xc0\xa1\x37\x72\x97\x93\x28\x6e\x65\xe9\x67\xc0\x10\x0b\xbc\xf6\x78\xa8\x78\x61\x78\xae\x2d\x43\xb5\xe7\xd4\x96\x94\x32\x5b\x91\x04\xed\xdb\x7f\x96\x11\x7a\xb1\x1f\x79\xd3\xb0\xb9\xbf\x25\x4e\xce\xe4\x25\x99\xb8\x33\x50\x09\xe5\xb2\xb3\x0c\x9d\xaf\x36\x9d\xc1\x0c\xfe\x5e\xbc\x80\xbf\xd1\x2b\x27\xe5\x9d\xa1\xe7\xac\xca\xce\x28\x70\x64\xd6\x99\x4d\x9c\xec\xa6\x33\x79\xe9\x94\x55\x27\x58\x3a\x3f\x67\x9d\xdf\x59\x38\x5c\x77\xbc\xd0\x29\x4c\xe7\x79\xe0\x14\x59\x67\x31\x71\xae\xd6\x9d\xe7\x63\x47\x98\x8e\x1f\x39\x2b\xd1\x19\xf9\x8e\x29\x3b\x51\xe0\x24\xba\x33\xf8\xc2\xd1\x65\x27\x5c\x38\xfa\xa6\x13\x7a\xce\xb5\xea\xbc\x08\x9c\x75\xd6\xf1\x42\x3c\x9d\x82\xb9\x78\x72\x9d\x09\xbd\x71\xfe\xfc\xdf\xfc\xe2\xcf\xfe\xf3\x3f\xfc\xb3\x5f\xff\xd1\xb7\xbf\xf7\xb7\x9d\x3f\xff\xcd\x2f\xff\xe2\x5f\xfd\x23\xfb\xe3\x2f\x7f\xfb\x77\xfe\xe2\x5f\xfe\xd3\x6f\x7f\xfd\x6f\xff\xf2\xb7\x7f\xf7\xee\x8b\xff\xfe\x0f\xfe\xf8\xdb\xdf\xfc\x17\x78\x31\xe4\x95\xd1\xc9\xc6\x19\x95\x4c\x7e\xfd\x07\x4c\x68\x67\x06\x09\x44\xc6\x64\xaa\x9d\x09\x33\x37\x82\xff\xe9\xaf\x2a\xe7\xfd\x3f\xff\xe6\x6f\x7d\xf3\xcb\x6f\x7e\xf9\xfe\x3f\xbe\xff\xf5\xfb\xdf\x38\xdf\xfe\x93\x7f\xf1\xed\xef\xff\xeb\xff\xf1\x87\xff\xcc\xf1\x74\xc1\xbe\xfe\x13\x95\x39\x0b\x55\x9a\x6a\x5d\x7d\xfd\x87\x9a\xa6\x8a\x3e\x2f\x99\x16\xf0\x30\xd3\xd7\xc2\x79\xff\x27\xdf\xfc\xbd\xf7\xff\xe9\xfd\xbf\x7b\xff\xc7\xdf\xfc\xc2\xca\x70\x7c\xc3\x32\x01\xbc\x2c\xac\x54\xce\x32\x26\x24\x97\x4e\xf4\xf5\x6f\xcb\xeb\xaf\xff\x80\x3b\xff\xed\xef\xf3\x3f\xfd\x95\x11\x92\x39\xef\x7f\xf5\xcd\x2f\xde\xff\xd7\xba\x53\x78\xc3\xa5\xbe\x66\xce\xff\xfe\xc7\xbf\xff\x3f\xff\xc3\x1f\xfd\xaf\xdf\xfb\xf7\xce\x98\x65\x7c\xad\x88\x65\x40\x29\x5a\x08\xf8\x75\x80\x65\x21\x92\x6b\x5e\xda\x2d\xec\xc2\x43\xa0\x65\x97\x04\xf7\x10\xf7\x92\xe0\x46\xd2\x3e\xfd\x6a\x43\x70\x37\xf1\x6b\x27\x7a\x45\xf0\xef\xee\x17\xee\x2e\xfe\xfb\x14\x82\x5b\x0c\x0e\xa9\x24\xb8\xcf\xb4\x4f\x65\x46\x70\xb3\x69\x9f\x66\x37\x04\x77\x9c\xf6\x69\x59\x11\xdc\x76\xda\xa7\x3f\x67\x04\xf7\x1e\xc6\xd4\x04\x01\x40\xfb\x14\x3f\x09\x02\x01\x7e\x65\x04\xd1\x40\xfb\xf4\x6a\x4d\x10\x12\x90\x05\x18\x82\xb8\x80\x01\x05\x41\x70\xa0\xe7\x25\x88\x10\xe0\x6c\xf0\x49\x10\x29\xb4\x4f\x75\x49\x10\x2e\xf0\xf5\x86\x20\x66\x68\x9f\x5e\x2b\x82\xc0\x81\xb4\x33\x23\x18\xc8\x9b\xeb\x6f\x39\x2b\x0a\xbc\xae\xa1\x5a\x1e\x3a\xc9\x18\x56\xad\xd0\xad\x74\x8d\xca\xb3\xbe\x90\x82\xbc\xd9\xb5\xe8\xd6\xdd\x2e\x09\x79\xa3\x80\xcd\x5d\x92\xf0\x62\xfe\x2a\x1e\xcd\xe7\x91\x17\xc4\xcf\x03\x7b\xe6\xdd\x72\xdb\xe1\x46\xdd\xd2\x1b\x5e\xd6\x15\x8c\xbb\x34\x1a\x83\x38\xf8\xb4\xb1\x6a\x6e\xf8\xaf\x94\x32\xbc\x3c\x90\xfb\xd2\x0b\xea\xfb\x6a\x0d\x8b\x02\xa9\x58\x8e\x68\x5f\x36\xb0\x77\x06\xea\x52\xc9\xf7\x88\x8a\xbc\xe9\x62\xe2\x46\x5e\x8c\x95\x81\xba\xca\x80\x52\xff\x4f\x00\x00\x00\xff\xff\x09\x25\x85\x94\xe2\x35\x00\x00") func confAppIniBytes() ([]byte, error) { return bindataRead( @@ -306,7 +306,7 @@ func confAppIni() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "conf/app.ini", size: 14661, mode: os.FileMode(420), modTime: time.Unix(1486650672, 0)} + info := bindataFileInfo{name: "conf/app.ini", size: 13794, mode: os.FileMode(420), modTime: time.Unix(1486682130, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/modules/context/api.go b/modules/context/api.go index 770daa3ad..500452edc 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -9,10 +9,10 @@ import ( "strings" "github.com/Unknwon/paginater" + log "gopkg.in/clog.v1" "gopkg.in/macaron.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/modules/context/context.go b/modules/context/context.go index 228ed3d84..296608f0c 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -16,12 +16,12 @@ import ( "github.com/go-macaron/csrf" "github.com/go-macaron/i18n" "github.com/go-macaron/session" + log "gopkg.in/clog.v1" "gopkg.in/macaron.v1" "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -73,7 +73,7 @@ func (ctx *Context) HasValue(name string) bool { // HTML calls Context.HTML and converts template name to string. func (ctx *Context) HTML(status int, name base.TplName) { - log.Debug("Template: %s", name) + log.Trace("Template: %s", name) ctx.Context.HTML(status, string(name)) } @@ -191,8 +191,8 @@ func Contexter() macaron.Handler { ctx.Data["CsrfToken"] = x.GetToken() ctx.Data["CsrfTokenHtml"] = template.HTML(``) - log.Debug("Session ID: %s", sess.ID()) - log.Debug("CSRF Token: %v", ctx.Data["CsrfToken"]) + log.Trace("Session ID: %s", sess.ID()) + log.Trace("CSRF Token: %v", ctx.Data["CsrfToken"]) ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding diff --git a/modules/context/repo.go b/modules/context/repo.go index 59891f868..1c322a95a 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -11,13 +11,13 @@ import ( "strings" "github.com/Unknwon/com" + log "gopkg.in/clog.v1" "gopkg.in/editorconfig/editorconfig-core-go.v1" "gopkg.in/macaron.v1" "github.com/gogits/git-module" "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) @@ -267,7 +267,7 @@ func RepoAssignment(args ...bool) macaron.Handler { // repo is bare and display enable if ctx.Repo.Repository.IsBare { - log.Debug("Bare repository: %s", ctx.Repo.RepoLink) + log.Trace("Bare repository: %s", ctx.Repo.RepoLink) // NOTE: to prevent templating error ctx.Data["BranchName"] = "" if displayBare { diff --git a/modules/cron/cron.go b/modules/cron/cron.go index 7695b974b..d11de18c2 100644 --- a/modules/cron/cron.go +++ b/modules/cron/cron.go @@ -7,10 +7,11 @@ package cron import ( "time" + log "gopkg.in/clog.v1" + "github.com/gogits/cron" "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/modules/log/conn.go b/modules/log/conn.go deleted file mode 100644 index c104a16c9..000000000 --- a/modules/log/conn.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package log - -import ( - "encoding/json" - "io" - "log" - "net" -) - -// ConnWriter implements LoggerInterface. -// it writes messages in keep-live tcp connection. -type ConnWriter struct { - lg *log.Logger - innerWriter io.WriteCloser - ReconnectOnMsg bool `json:"reconnectOnMsg"` - Reconnect bool `json:"reconnect"` - Net string `json:"net"` - Addr string `json:"addr"` - Level int `json:"level"` -} - -// create new ConnWrite returning as LoggerInterface. -func NewConn() LoggerInterface { - conn := new(ConnWriter) - conn.Level = TRACE - return conn -} - -// init connection writer with json config. -// json config only need key "level". -func (cw *ConnWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), cw) -} - -// write message in connection. -// if connection is down, try to re-connect. -func (cw *ConnWriter) WriteMsg(msg string, skip, level int) error { - if cw.Level > level { - return nil - } - if cw.neddedConnectOnMsg() { - if err := cw.connect(); err != nil { - return err - } - } - - if cw.ReconnectOnMsg { - defer cw.innerWriter.Close() - } - cw.lg.Println(msg) - return nil -} - -func (_ *ConnWriter) Flush() { -} - -// destroy connection writer and close tcp listener. -func (cw *ConnWriter) Destroy() { - if cw.innerWriter == nil { - return - } - cw.innerWriter.Close() -} - -func (cw *ConnWriter) connect() error { - if cw.innerWriter != nil { - cw.innerWriter.Close() - cw.innerWriter = nil - } - - conn, err := net.Dial(cw.Net, cw.Addr) - if err != nil { - return err - } - - if tcpConn, ok := conn.(*net.TCPConn); ok { - tcpConn.SetKeepAlive(true) - } - - cw.innerWriter = conn - cw.lg = log.New(conn, "", log.Ldate|log.Ltime) - return nil -} - -func (cw *ConnWriter) neddedConnectOnMsg() bool { - if cw.Reconnect { - cw.Reconnect = false - return true - } - - if cw.innerWriter == nil { - return true - } - - return cw.ReconnectOnMsg -} - -func init() { - Register("conn", NewConn) -} diff --git a/modules/log/console.go b/modules/log/console.go deleted file mode 100644 index f5a8b96fd..000000000 --- a/modules/log/console.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package log - -import ( - "encoding/json" - "log" - "os" - "runtime" -) - -type Brush func(string) string - -func NewBrush(color string) Brush { - pre := "\033[" - reset := "\033[0m" - return func(text string) string { - return pre + color + "m" + text + reset - } -} - -var colors = []Brush{ - NewBrush("1;36"), // Trace cyan - NewBrush("1;34"), // Debug blue - NewBrush("1;32"), // Info green - NewBrush("1;33"), // Warn yellow - NewBrush("1;31"), // Error red - NewBrush("1;35"), // Critical purple - NewBrush("1;31"), // Fatal red -} - -// ConsoleWriter implements LoggerInterface and writes messages to terminal. -type ConsoleWriter struct { - lg *log.Logger - Level int `json:"level"` -} - -// create ConsoleWriter returning as LoggerInterface. -func NewConsole() LoggerInterface { - return &ConsoleWriter{ - lg: log.New(os.Stdout, "", log.Ldate|log.Ltime), - Level: TRACE, - } -} - -func (cw *ConsoleWriter) Init(config string) error { - return json.Unmarshal([]byte(config), cw) -} - -func (cw *ConsoleWriter) WriteMsg(msg string, skip, level int) error { - if cw.Level > level { - return nil - } - if runtime.GOOS == "windows" { - cw.lg.Println(msg) - } else { - cw.lg.Println(colors[level](msg)) - } - return nil -} - -func (_ *ConsoleWriter) Flush() { - -} - -func (_ *ConsoleWriter) Destroy() { -} - -func init() { - Register("console", NewConsole) -} diff --git a/modules/log/file.go b/modules/log/file.go deleted file mode 100644 index e9402815f..000000000 --- a/modules/log/file.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package log - -import ( - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" - "sync" - "time" -) - -// FileLogWriter implements LoggerInterface. -// It writes messages by lines limit, file size limit, or time frequency. -type FileLogWriter struct { - *log.Logger - mw *MuxWriter - // The opened file - Filename string `json:"filename"` - - Maxlines int `json:"maxlines"` - maxlines_curlines int - - // Rotate at size - Maxsize int `json:"maxsize"` - maxsize_cursize int - - // Rotate daily - Daily bool `json:"daily"` - Maxdays int64 `json:"maxdays"` - daily_opendate int - - Rotate bool `json:"rotate"` - - startLock sync.Mutex // Only one log can write to the file - - Level int `json:"level"` -} - -// an *os.File writer with locker. -type MuxWriter struct { - sync.Mutex - fd *os.File -} - -// write to os.File. -func (l *MuxWriter) Write(b []byte) (int, error) { - l.Lock() - defer l.Unlock() - return l.fd.Write(b) -} - -// set os.File in writer. -func (l *MuxWriter) SetFd(fd *os.File) { - if l.fd != nil { - l.fd.Close() - } - l.fd = fd -} - -// create a FileLogWriter returning as LoggerInterface. -func NewFileWriter() LoggerInterface { - w := &FileLogWriter{ - Filename: "", - Maxlines: 1000000, - Maxsize: 1 << 28, //256 MB - Daily: true, - Maxdays: 7, - Rotate: true, - Level: TRACE, - } - // use MuxWriter instead direct use os.File for lock write when rotate - w.mw = new(MuxWriter) - // set MuxWriter as Logger's io.Writer - w.Logger = log.New(w.mw, "", log.Ldate|log.Ltime) - return w -} - -// Init file logger with json config. -// config like: -// { -// "filename":"log/gogs.log", -// "maxlines":10000, -// "maxsize":1<<30, -// "daily":true, -// "maxdays":15, -// "rotate":true -// } -func (w *FileLogWriter) Init(config string) error { - if err := json.Unmarshal([]byte(config), w); err != nil { - return err - } - if len(w.Filename) == 0 { - return errors.New("config must have filename") - } - return w.StartLogger() -} - -// start file logger. create log file and set to locker-inside file writer. -func (w *FileLogWriter) StartLogger() error { - fd, err := w.createLogFile() - if err != nil { - return err - } - w.mw.SetFd(fd) - if err = w.initFd(); err != nil { - return err - } - return nil -} - -func (w *FileLogWriter) docheck(size int) { - w.startLock.Lock() - defer w.startLock.Unlock() - if w.Rotate && ((w.Maxlines > 0 && w.maxlines_curlines >= w.Maxlines) || - (w.Maxsize > 0 && w.maxsize_cursize >= w.Maxsize) || - (w.Daily && time.Now().Day() != w.daily_opendate)) { - if err := w.DoRotate(); err != nil { - fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err) - return - } - } - w.maxlines_curlines++ - w.maxsize_cursize += size -} - -// write logger message into file. -func (w *FileLogWriter) WriteMsg(msg string, skip, level int) error { - if level < w.Level { - return nil - } - n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] " - w.docheck(n) - w.Logger.Println(msg) - return nil -} - -func (w *FileLogWriter) createLogFile() (*os.File, error) { - // Open the log file - return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) -} - -func (w *FileLogWriter) initFd() error { - fd := w.mw.fd - finfo, err := fd.Stat() - if err != nil { - return fmt.Errorf("get stat: %s\n", err) - } - w.maxsize_cursize = int(finfo.Size()) - w.daily_opendate = time.Now().Day() - if finfo.Size() > 0 { - content, err := ioutil.ReadFile(w.Filename) - if err != nil { - return err - } - w.maxlines_curlines = len(strings.Split(string(content), "\n")) - } else { - w.maxlines_curlines = 0 - } - return nil -} - -// DoRotate means it need to write file in new file. -// new file name like xx.log.2013-01-01.2 -func (w *FileLogWriter) DoRotate() error { - _, err := os.Lstat(w.Filename) - if err == nil { // file exists - // Find the next available number - num := 1 - fname := "" - for ; err == nil && num <= 999; num++ { - fname = w.Filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num) - _, err = os.Lstat(fname) - } - // return error if the last file checked still existed - if err == nil { - return fmt.Errorf("rotate: cannot find free log number to rename %s\n", w.Filename) - } - - // block Logger's io.Writer - w.mw.Lock() - defer w.mw.Unlock() - - fd := w.mw.fd - fd.Close() - - // close fd before rename - // Rename the file to its newfound home - if err = os.Rename(w.Filename, fname); err != nil { - return fmt.Errorf("Rotate: %s\n", err) - } - - // re-start logger - if err = w.StartLogger(); err != nil { - return fmt.Errorf("Rotate StartLogger: %s\n", err) - } - - go w.deleteOldLog() - } - - return nil -} - -func (w *FileLogWriter) deleteOldLog() { - dir := filepath.Dir(w.Filename) - filepath.Walk(dir, func(path string, info os.FileInfo, err error) (returnErr error) { - defer func() { - if r := recover(); r != nil { - returnErr = fmt.Errorf("Unable to delete old log '%s', error: %+v", path, r) - } - }() - - if !info.IsDir() && info.ModTime().Unix() < (time.Now().Unix()-60*60*24*w.Maxdays) { - if strings.HasPrefix(filepath.Base(path), filepath.Base(w.Filename)) { - os.Remove(path) - } - } - return returnErr - }) -} - -// destroy file logger, close file writer. -func (w *FileLogWriter) Destroy() { - w.mw.fd.Close() -} - -// flush file logger. -// there are no buffering messages in file logger in memory. -// flush file means sync file from disk. -func (w *FileLogWriter) Flush() { - w.mw.fd.Sync() -} - -func init() { - Register("file", NewFileWriter) -} diff --git a/modules/log/log.go b/modules/log/log.go deleted file mode 100644 index 41be41405..000000000 --- a/modules/log/log.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package log - -import ( - "fmt" - "os" - "path" - "path/filepath" - "runtime" - "strings" - "sync" -) - -var ( - loggers []*Logger - GitLogger *Logger -) - -func NewLogger(bufLen int64, mode, config string) { - logger := newLogger(bufLen) - - isExist := false - for i, l := range loggers { - if l.adapter == mode { - isExist = true - loggers[i] = logger - } - } - if !isExist { - loggers = append(loggers, logger) - } - if err := logger.SetLogger(mode, config); err != nil { - Fatal(2, "Fail to set logger (%s): %v", mode, err) - } -} - -// FIXME: use same log level as other loggers. -func NewGitLogger(logPath string) { - os.MkdirAll(path.Dir(logPath), os.ModePerm) - GitLogger = newLogger(0) - GitLogger.SetLogger("file", fmt.Sprintf(`{"level":0,"filename":"%s","rotate":false}`, logPath)) -} - -func Trace(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Trace(format, v...) - } -} - -func Debug(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Debug(format, v...) - } -} - -func Info(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Info(format, v...) - } -} - -func Warn(format string, v ...interface{}) { - for _, logger := range loggers { - logger.Warn(format, v...) - } -} - -func Error(skip int, format string, v ...interface{}) { - for _, logger := range loggers { - logger.Error(skip, format, v...) - } -} - -func Critical(skip int, format string, v ...interface{}) { - for _, logger := range loggers { - logger.Critical(skip, format, v...) - } -} - -func Fatal(skip int, format string, v ...interface{}) { - Error(skip, format, v...) - for _, l := range loggers { - l.Close() - } - os.Exit(1) -} - -func Close() { - for _, l := range loggers { - l.Close() - } -} - -// .___ __ _____ -// | | _____/ |_ ____________/ ____\____ ____ ____ -// | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \ -// | | | \ | \ ___/| | \/| | / __ \\ \__\ ___/ -// |___|___| /__| \___ >__| |__| (____ /\___ >___ > -// \/ \/ \/ \/ \/ - -type LogLevel int - -const ( - TRACE = iota - DEBUG - INFO - WARN - ERROR - CRITICAL - FATAL -) - -// LoggerInterface represents behaviors of a logger provider. -type LoggerInterface interface { - Init(config string) error - WriteMsg(msg string, skip, level int) error - Destroy() - Flush() -} - -type loggerType func() LoggerInterface - -var adapters = make(map[string]loggerType) - -// Register registers given logger provider to adapters. -func Register(name string, log loggerType) { - if log == nil { - panic("log: register provider is nil") - } - if _, dup := adapters[name]; dup { - panic("log: register called twice for provider \"" + name + "\"") - } - adapters[name] = log -} - -type logMsg struct { - skip, level int - msg string -} - -// Logger is default logger in beego application. -// it can contain several providers and log message into all providers. -type Logger struct { - adapter string - lock sync.Mutex - level int - msg chan *logMsg - outputs map[string]LoggerInterface - quit chan bool -} - -// newLogger initializes and returns a new logger. -func newLogger(buffer int64) *Logger { - l := &Logger{ - msg: make(chan *logMsg, buffer), - outputs: make(map[string]LoggerInterface), - quit: make(chan bool), - } - go l.StartLogger() - return l -} - -// SetLogger sets new logger instance with given logger adapter and config. -func (l *Logger) SetLogger(adapter string, config string) error { - l.lock.Lock() - defer l.lock.Unlock() - if log, ok := adapters[adapter]; ok { - lg := log() - if err := lg.Init(config); err != nil { - return err - } - l.outputs[adapter] = lg - l.adapter = adapter - } else { - panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") - } - return nil -} - -// DelLogger removes a logger adapter instance. -func (l *Logger) DelLogger(adapter string) error { - l.lock.Lock() - defer l.lock.Unlock() - if lg, ok := l.outputs[adapter]; ok { - lg.Destroy() - delete(l.outputs, adapter) - } else { - panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") - } - return nil -} - -func (l *Logger) writerMsg(skip, level int, msg string) error { - if l.level > level { - return nil - } - lm := &logMsg{ - skip: skip, - level: level, - } - - // Only error information needs locate position for debugging. - if lm.level >= ERROR { - pc, file, line, ok := runtime.Caller(skip) - if ok { - // Get caller function name. - fn := runtime.FuncForPC(pc) - var fnName string - if fn == nil { - fnName = "?()" - } else { - fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()" - } - - fileName := file - if len(fileName) > 20 { - fileName = "..." + fileName[len(fileName)-20:] - } - lm.msg = fmt.Sprintf("[%s:%d %s] %s", fileName, line, fnName, msg) - } else { - lm.msg = msg - } - } else { - lm.msg = msg - } - l.msg <- lm - return nil -} - -// StartLogger starts logger chan reading. -func (l *Logger) StartLogger() { - for { - select { - case bm := <-l.msg: - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { - fmt.Println("ERROR, unable to WriteMsg:", err) - } - } - case <-l.quit: - return - } - } -} - -// Flush flushs all chan data. -func (l *Logger) Flush() { - for _, l := range l.outputs { - l.Flush() - } -} - -// Close closes logger, flush all chan data and destroy all adapter instances. -func (l *Logger) Close() { - l.quit <- true - for { - if len(l.msg) > 0 { - bm := <-l.msg - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { - fmt.Println("ERROR, unable to WriteMsg:", err) - } - } - } else { - break - } - } - for _, l := range l.outputs { - l.Flush() - l.Destroy() - } -} - -func (l *Logger) Trace(format string, v ...interface{}) { - msg := fmt.Sprintf("[T] "+format, v...) - l.writerMsg(0, TRACE, msg) -} - -func (l *Logger) Debug(format string, v ...interface{}) { - msg := fmt.Sprintf("[D] "+format, v...) - l.writerMsg(0, DEBUG, msg) -} - -func (l *Logger) Info(format string, v ...interface{}) { - msg := fmt.Sprintf("[I] "+format, v...) - l.writerMsg(0, INFO, msg) -} - -func (l *Logger) Warn(format string, v ...interface{}) { - msg := fmt.Sprintf("[W] "+format, v...) - l.writerMsg(0, WARN, msg) -} - -func (l *Logger) Error(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[E] "+format, v...) - l.writerMsg(skip, ERROR, msg) -} - -func (l *Logger) Critical(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[C] "+format, v...) - l.writerMsg(skip, CRITICAL, msg) -} - -func (l *Logger) Fatal(skip int, format string, v ...interface{}) { - msg := fmt.Sprintf("[F] "+format, v...) - l.writerMsg(skip, FATAL, msg) - l.Close() - os.Exit(1) -} diff --git a/modules/log/smtp.go b/modules/log/smtp.go deleted file mode 100644 index 0a10e56a6..000000000 --- a/modules/log/smtp.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package log - -import ( - "encoding/json" - "fmt" - "net/smtp" - "strings" - "time" -) - -const ( - subjectPhrase = "Diagnostic message from server" -) - -// smtpWriter implements LoggerInterface and is used to send emails via given SMTP-server. -type SmtpWriter struct { - Username string `json:"Username"` - Password string `json:"password"` - Host string `json:"Host"` - Subject string `json:"subject"` - RecipientAddresses []string `json:"sendTos"` - Level int `json:"level"` -} - -// create smtp writer. -func NewSmtpWriter() LoggerInterface { - return &SmtpWriter{Level: TRACE} -} - -// init smtp writer with json config. -// config like: -// { -// "Username":"example@gmail.com", -// "password:"password", -// "host":"smtp.gmail.com:465", -// "subject":"email title", -// "sendTos":["email1","email2"], -// "level":LevelError -// } -func (sw *SmtpWriter) Init(jsonconfig string) error { - return json.Unmarshal([]byte(jsonconfig), sw) -} - -// write message in smtp writer. -// it will send an email with subject and only this message. -func (s *SmtpWriter) WriteMsg(msg string, skip, level int) error { - if level < s.Level { - return nil - } - - hp := strings.Split(s.Host, ":") - - // Set up authentication information. - auth := smtp.PlainAuth( - "", - s.Username, - s.Password, - hp[0], - ) - // Connect to the server, authenticate, set the sender and recipient, - // and send the email all in one step. - content_type := "Content-Type: text/plain" + "; charset=UTF-8" - mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.Username + "<" + s.Username + - ">\r\nSubject: " + s.Subject + "\r\n" + content_type + "\r\n\r\n" + fmt.Sprintf(".%s", time.Now().Format("2006-01-02 15:04:05")) + msg) - - return smtp.SendMail( - s.Host, - auth, - s.Username, - s.RecipientAddresses, - mailmsg, - ) -} - -func (_ *SmtpWriter) Flush() { -} - -func (_ *SmtpWriter) Destroy() { -} - -func init() { - Register("smtp", NewSmtpWriter) -} diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go index ed2f43736..b65073a1d 100644 --- a/modules/mailer/mail.go +++ b/modules/mailer/mail.go @@ -8,11 +8,11 @@ import ( "fmt" "html/template" + log "gopkg.in/clog.v1" "gopkg.in/gomail.v2" "gopkg.in/macaron.v1" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/markdown" "github.com/gogits/gogs/modules/setting" ) diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go index 32f25f5b5..c111732f5 100644 --- a/modules/mailer/mailer.go +++ b/modules/mailer/mailer.go @@ -15,9 +15,9 @@ import ( "time" "github.com/jaytaylor/html2text" + log "gopkg.in/clog.v1" "gopkg.in/gomail.v2" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" ) diff --git a/modules/process/manager.go b/modules/process/manager.go index 1f98ca7cf..ae83a0b57 100644 --- a/modules/process/manager.go +++ b/modules/process/manager.go @@ -11,7 +11,7 @@ import ( "os/exec" "time" - "github.com/gogits/gogs/modules/log" + log "gopkg.in/clog.v1" ) var ( diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 54a837e2e..d5cb0b7cb 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -5,7 +5,6 @@ package setting import ( - "fmt" "net/mail" "net/url" "os" @@ -22,12 +21,12 @@ import ( _ "github.com/go-macaron/cache/redis" "github.com/go-macaron/session" _ "github.com/go-macaron/session/redis" + log "gopkg.in/clog.v1" "gopkg.in/ini.v1" "github.com/gogits/go-libravatar" "github.com/gogits/gogs/modules/bindata" - "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/user" ) @@ -180,7 +179,7 @@ var ( // Log settings LogRootPath string LogModes []string - LogConfigs []string + LogConfigs []interface{} // Attachment settings AttachmentPath string @@ -290,11 +289,11 @@ func execPath() (string, error) { func init() { IsWindows = runtime.GOOS == "windows" - log.NewLogger(0, "console", `{"level": 0}`) + log.New(log.CONSOLE, log.ConsoleConfig{}) var err error if AppPath, err = execPath(); err != nil { - log.Fatal(4, "fail to get app path: %v\n", err) + log.Fatal(4, "Fail to get app path: %v\n", err) } // Note: we don't use path.Dir here because it does not handle case @@ -617,82 +616,78 @@ func newService() { Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() } -var logLevels = map[string]string{ - "Trace": "0", - "Debug": "1", - "Info": "2", - "Warn": "3", - "Error": "4", - "Critical": "5", -} - func newLogService() { - log.Info("%s %s", AppName, AppVer) - if len(BuildTime) > 0 { log.Info("Build Time: %s", BuildTime) log.Info("Build Git Hash: %s", BuildGitHash) } + // Because we always create a console logger as primary logger before all settings are loaded, + // thus if user doesn't set console logger, we should remove it after other loggers are created. + hasConsole := false + // Get and check log mode. LogModes = strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") - LogConfigs = make([]string, len(LogModes)) + LogConfigs = make([]interface{}, len(LogModes)) for i, mode := range LogModes { - mode = strings.TrimSpace(mode) + mode = strings.ToLower(strings.TrimSpace(mode)) sec, err := Cfg.GetSection("log." + mode) if err != nil { - log.Fatal(4, "Unknown log mode: %s", mode) + log.Fatal(4, "Unknown logger mode: %s", mode) } - validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"} - // Log level. - levelName := Cfg.Section("log."+mode).Key("LEVEL").In( - Cfg.Section("log").Key("LEVEL").In("Trace", validLevels), - validLevels) - level, ok := logLevels[levelName] - if !ok { - log.Fatal(4, "Unknown log level: %s", levelName) - } + validLevels := []string{"trace", "info", "warn", "error", "fatal"} + levelName := Cfg.Section("log." + mode).Key("LEVEL").Validate(func(v string) string { + v = strings.ToLower(v) + if com.IsSliceContainsStr(validLevels, v) { + return v + } + return "trace" + }) + level := map[string]log.LEVEL{ + "trace": log.TRACE, + "info": log.INFO, + "warn": log.WARN, + "error": log.ERROR, + "fatal": log.FATAL, + }[levelName] // Generate log configuration. switch mode { case "console": - LogConfigs[i] = fmt.Sprintf(`{"level":%s}`, level) + hasConsole = true + LogConfigs[i] = log.ConsoleConfig{ + Level: level, + BufferSize: Cfg.Section("log").Key("BUFFER_LEN").MustInt64(100), + } case "file": - logPath := sec.Key("FILE_NAME").MustString(path.Join(LogRootPath, "gogs.log")) + logPath := path.Join(LogRootPath, "gogs.log") if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { - panic(err.Error()) + log.Fatal(4, "Fail to create log directory '%s': %v", path.Dir(logPath), err) } - LogConfigs[i] = fmt.Sprintf( - `{"level":%s,"filename":"%s","rotate":%v,"maxlines":%d,"maxsize":%d,"daily":%v,"maxdays":%d}`, level, - logPath, - sec.Key("LOG_ROTATE").MustBool(true), - sec.Key("MAX_LINES").MustInt(1000000), - 1<