diff --git a/Gopkg.lock b/Gopkg.lock index b7eb6d9e..65d36964 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -55,6 +55,14 @@ pruneopts = "UT" revision = "1eb28afdf9b6e56cf673badd47545f844fe81103" +[[projects]] + digest = "1:ca82a3b99694824c627573c2a76d0e49719b4a9c02d1d85a2ac91f1c1f52ab9b" + name = "github.com/fatih/structs" + packages = ["."] + pruneopts = "UT" + revision = "a720dfa8df582c51dee1b36feabb906bde1588bd" + version = "v1.0" + [[projects]] digest = "1:e37eb23cfd852df9c65b5dee28456595d7b12479421221a088b6ea7ad95a3570" name = "github.com/go-mail/mail" @@ -133,14 +141,6 @@ pruneopts = "UT" revision = "04140366298a54a039076d798123ffa108fff46c" -[[projects]] - branch = "master" - digest = "1:55011902fbefd825fd286f47e1783e2f5e0316eac7be414d28f8f5dd82156b0f" - name = "github.com/jinzhu/now" - packages = ["."] - pruneopts = "UT" - revision = "ed742868f2aebdb1c0c437bf4f7257f88834b66f" - [[projects]] digest = "1:ecd9aa82687cf31d1585d4ac61d0ba180e42e8a6182b85bd785fcca8dfeefc1b" name = "github.com/joho/godotenv" @@ -260,6 +260,7 @@ "github.com/GeertJohan/go.rice", "github.com/GeertJohan/go.rice/embedded", "github.com/ararog/timeago", + "github.com/fatih/structs", "github.com/go-mail/mail", "github.com/go-yaml/yaml", "github.com/gorilla/mux", @@ -269,7 +270,6 @@ "github.com/jinzhu/gorm/dialects/mysql", "github.com/jinzhu/gorm/dialects/postgres", "github.com/jinzhu/gorm/dialects/sqlite", - "github.com/jinzhu/now", "github.com/joho/godotenv", "github.com/rendon/testcli", "github.com/stretchr/testify/assert", diff --git a/Gopkg.toml b/Gopkg.toml index c873f70a..273a4257 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -33,6 +33,10 @@ name = "github.com/ararog/timeago" version = "0.0.1" +[[constraint]] + name = "github.com/fatih/structs" + version = "1.0.0" + [[constraint]] name = "github.com/go-mail/mail" version = "2.2.0" @@ -53,10 +57,6 @@ name = "github.com/jinzhu/gorm" version = "1.9.1" -[[constraint]] - branch = "master" - name = "github.com/jinzhu/now" - [[constraint]] name = "github.com/joho/godotenv" version = "1.3.0" diff --git a/Makefile b/Makefile index 1fb20b95..518db848 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,12 @@ build: compile build-plugin: $(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o ./dev/plugin/example.so -v ./dev/plugin +test-plugin: clean + mkdir plugins + $(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o ./dev/plugin/example.so -v ./dev/plugin + mv ./dev/plugin/example.so ./plugins/example.so + STATUP_DIR=$(TEST_DIR) go test -v -p=1 $(BUILDVERSION) -coverprofile=coverage.out ./plugin + # build Statup debug app build-debug: compile $(GOBUILD) $(BUILDVERSION) -tags debug -o $(BINARY_NAME) -v ./cmd @@ -75,7 +81,7 @@ benchmark-view: go tool pprof handlers/handlers.test handlers/prof.cpu > top20 # test Statup golang tetsing files -test: clean compile install +test: clean compile install build-plugin STATUP_DIR=$(TEST_DIR) go test -v -p=1 $(BUILDVERSION) -coverprofile=coverage.out ./... gocov convert coverage.out > coverage.json diff --git a/dev/COVERAGE.html b/dev/COVERAGE.html index 00bf0abf..5d946cee 100644 --- a/dev/COVERAGE.html +++ b/dev/COVERAGE.html @@ -128,16 +128,16 @@
Coverage Report
-
Generated on 07 Oct 18 01:15 -0700 with gocov-html
Report Overview
+
Generated on 08 Oct 18 14:07 -0700 with gocov-html
Report Overview
- + - - - + + + - - + +
github.com/hunterlong/statup/cmd31.37%48/153
github.com/hunterlong/statup/core54.09%496/917
github.com/hunterlong/statup/core53.35%510/956
github.com/hunterlong/statup/core/notifier72.73%152/209
github.com/hunterlong/statup/handlers68.52%642/937
github.com/hunterlong/statup/notifiers7.03%18/256
github.com/hunterlong/statup/plugin33.33%1/3
github.com/hunterlong/statup/handlers67.61%643/951
github.com/hunterlong/statup/notifiers7.00%18/257
github.com/hunterlong/statup/plugin25.58%11/43
github.com/hunterlong/statup/source77.71%136/175
github.com/hunterlong/statup/utils54.76%115/210
Report Total56.22%1608/2860
github.com/hunterlong/statup/utils54.98%116/211
Report Total55.30%1634/2955
Package Overview: github.com/hunterlong/statup/cmd 31.37%

This is a coverage report created after analysis of the github.com/hunterlong/statup/cmd package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/cmd | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

@@ -151,220 +151,221 @@ -
CheckGithubUpdates(...)github.com/hunterlong/statup/cmd/cli.go0.00%0/10
parseFlags(...)github.com/hunterlong/statup/cmd/main.go0.00%0/5
ForEachPlugin(...)github.com/hunterlong/statup/cmd/main.go0.00%0/1
LoadPlugins(...)github.com/hunterlong/statup/cmd/main.go0.00%0/0
github.com/hunterlong/statup/cmd31.37%48/153
func HelpEcho
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/cli.go:

-
152
func HelpEcho() {
153
        fmt.Printf("Statup v%v - Statup.io\n", VERSION)
154
        fmt.Printf("A simple Application Status Monitor that is opensource and lightweight.\n")
155
        fmt.Printf("Commands:\n")
156
        fmt.Println("     statup                    - Main command to run Statup server")
157
        fmt.Println("     statup version            - Returns the current version of Statup")
158
        fmt.Println("     statup run                - Check all services 1 time and then quit")
159
        fmt.Println("     statup test plugins       - Test all plugins for required information")
160
        fmt.Println("     statup assets             - Dump all assets used locally to be edited.")
161
        fmt.Println("     statup sass               - Compile .scss files into the css directory")
162
        fmt.Println("     statup env                - Show all environment variables being used for Statup")
163
        fmt.Println("     statup export             - Exports the index page as a static HTML for pushing")
164
        fmt.Println("     statup update             - Attempts to update to the latest version")
165
        fmt.Println("     statup help               - Shows the user basic information about Statup")
166
        fmt.Printf("Flags:\n")
167
        fmt.Println("     -ip 127.0.0.1             - Run HTTP server on specific IP address (default: localhost)")
168
        fmt.Println("     -port 8080                - Run HTTP server on Port (default: 8080)")
169
        fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
170
}
+153
func HelpEcho() {
154
        fmt.Printf("Statup v%v - Statup.io\n", VERSION)
155
        fmt.Printf("A simple Application Status Monitor that is opensource and lightweight.\n")
156
        fmt.Printf("Commands:\n")
157
        fmt.Println("     statup                    - Main command to run Statup server")
158
        fmt.Println("     statup version            - Returns the current version of Statup")
159
        fmt.Println("     statup run                - Check all services 1 time and then quit")
160
        fmt.Println("     statup test plugins       - Test all plugins for required information")
161
        fmt.Println("     statup assets             - Dump all assets used locally to be edited.")
162
        fmt.Println("     statup sass               - Compile .scss files into the css directory")
163
        fmt.Println("     statup env                - Show all environment variables being used for Statup")
164
        fmt.Println("     statup export             - Exports the index page as a static HTML for pushing")
165
        fmt.Println("     statup update             - Attempts to update to the latest version")
166
        fmt.Println("     statup help               - Shows the user basic information about Statup")
167
        fmt.Printf("Flags:\n")
168
        fmt.Println("     -ip 127.0.0.1             - Run HTTP server on specific IP address (default: localhost)")
169
        fmt.Println("     -port 8080                - Run HTTP server on Port (default: 8080)")
170
        fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
171
}
func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
40
func init() {
41
        core.VERSION = VERSION
42
}
+41
func init() {
42
        core.VERSION = VERSION
43
}
func LoadDotEnvs
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
87
func LoadDotEnvs() error {
88
        err := godotenv.Load()
89
        if err == nil {
90
                utils.Log(1, "Environment file '.env' Loaded")
91
                UsingDotEnv = true
92
        }
93
        return err
94
}
+88
func LoadDotEnvs() error {
89
        err := godotenv.Load()
90
        if err == nil {
91
                utils.Log(1, "Environment file '.env' Loaded")
92
                UsingDotEnv = true
93
        }
94
        return err
95
}
func CatchCLI
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/cli.go:

-
33
func CatchCLI(args []string) error {
34
        dir := utils.Directory
35
        utils.InitLogs()
36
        source.Assets()
37
        LoadDotEnvs()
38
39
        switch args[0] {
40
        case "app":
41
                handlers.DesktopInit(ipAddress, port)
42
        case "version":
43
                if COMMIT != "" {
44
                        fmt.Printf("Statup v%v (%v)\n", VERSION, COMMIT)
45
                } else {
46
                        fmt.Printf("Statup v%v\n", VERSION)
47
                }
48
                return errors.New("end")
49
        case "assets":
50
                err := source.CreateAllAssets(dir)
51
                if err != nil {
52
                        return err
53
                } else {
54
                        return errors.New("end")
55
                }
56
        case "sass":
57
                utils.InitLogs()
58
                source.Assets()
59
                err := source.CompileSASS(dir)
60
                if err == nil {
61
                        return errors.New("end")
62
                }
63
                return err
64
        case "update":
65
                gitCurrent, err := CheckGithubUpdates()
66
                if err != nil {
67
                        return nil
68
                }
69
                fmt.Printf("Statup Version: v%v\nLatest Version: %v\n", VERSION, gitCurrent.TagName)
70
                if VERSION != gitCurrent.TagName[1:] {
71
                        fmt.Printf("You don't have the latest version v%v!\nDownload the latest release at: https://github.com/hunterlong/statup\n", gitCurrent.TagName[1:])
72
                } else {
73
                        fmt.Printf("You have the latest version of Statup!\n")
74
                }
75
                if err == nil {
76
                        return errors.New("end")
77
                }
78
                return nil
79
        case "test":
80
                cmd := args[1]
81
                switch cmd {
82
                case "plugins":
83
                        LoadPlugins(true)
84
                }
85
                return errors.New("end")
86
        case "export":
87
                var err error
88
                fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
89
                core.Configs, err = core.LoadConfig(dir)
90
                if err != nil {
91
                        utils.Log(4, "config.yml file not found")
92
                        return err
93
                }
94
                indexSource := core.ExportIndexHTML()
95
                err = utils.SaveFile("./index.html", []byte(indexSource))
96
                if err != nil {
97
                        utils.Log(4, err)
98
                        return err
99
                }
100
                utils.Log(1, "Exported Statup index page: 'index.html'")
101
        case "help":
102
                HelpEcho()
103
                return errors.New("end")
104
        case "run":
105
                utils.Log(1, "Running 1 time and saving to database...")
106
                RunOnce()
107
                fmt.Println("Check is complete.")
108
                return errors.New("end")
109
        case "env":
110
                fmt.Println("Statup Environment Variables")
111
                envs, err := godotenv.Read(".env")
112
                if err != nil {
113
                        utils.Log(4, "No .env file found in current directory.")
114
                        return err
115
                }
116
                for k, e := range envs {
117
                        fmt.Printf("%v=%v\n", k, e)
118
                }
119
        default:
120
                return nil
121
        }
122
        return errors.New("end")
123
}
+34
func CatchCLI(args []string) error {
35
        dir := utils.Directory
36
        utils.InitLogs()
37
        source.Assets()
38
        LoadDotEnvs()
39
40
        switch args[0] {
41
        case "app":
42
                handlers.DesktopInit(ipAddress, port)
43
        case "version":
44
                if COMMIT != "" {
45
                        fmt.Printf("Statup v%v (%v)\n", VERSION, COMMIT)
46
                } else {
47
                        fmt.Printf("Statup v%v\n", VERSION)
48
                }
49
                return errors.New("end")
50
        case "assets":
51
                err := source.CreateAllAssets(dir)
52
                if err != nil {
53
                        return err
54
                } else {
55
                        return errors.New("end")
56
                }
57
        case "sass":
58
                utils.InitLogs()
59
                source.Assets()
60
                err := source.CompileSASS(dir)
61
                if err == nil {
62
                        return errors.New("end")
63
                }
64
                return err
65
        case "update":
66
                gitCurrent, err := CheckGithubUpdates()
67
                if err != nil {
68
                        return nil
69
                }
70
                fmt.Printf("Statup Version: v%v\nLatest Version: %v\n", VERSION, gitCurrent.TagName)
71
                if VERSION != gitCurrent.TagName[1:] {
72
                        fmt.Printf("You don't have the latest version v%v!\nDownload the latest release at: https://github.com/hunterlong/statup\n", gitCurrent.TagName[1:])
73
                } else {
74
                        fmt.Printf("You have the latest version of Statup!\n")
75
                }
76
                if err == nil {
77
                        return errors.New("end")
78
                }
79
                return nil
80
        case "test":
81
                cmd := args[1]
82
                switch cmd {
83
                case "plugins":
84
                        plugin.LoadPlugins(true)
85
                }
86
                return errors.New("end")
87
        case "export":
88
                var err error
89
                fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
90
                core.Configs, err = core.LoadConfig(dir)
91
                if err != nil {
92
                        utils.Log(4, "config.yml file not found")
93
                        return err
94
                }
95
                indexSource := core.ExportIndexHTML()
96
                err = utils.SaveFile("./index.html", []byte(indexSource))
97
                if err != nil {
98
                        utils.Log(4, err)
99
                        return err
100
                }
101
                utils.Log(1, "Exported Statup index page: 'index.html'")
102
        case "help":
103
                HelpEcho()
104
                return errors.New("end")
105
        case "run":
106
                utils.Log(1, "Running 1 time and saving to database...")
107
                RunOnce()
108
                fmt.Println("Check is complete.")
109
                return errors.New("end")
110
        case "env":
111
                fmt.Println("Statup Environment Variables")
112
                envs, err := godotenv.Read(".env")
113
                if err != nil {
114
                        utils.Log(4, "No .env file found in current directory.")
115
                        return err
116
                }
117
                for k, e := range envs {
118
                        fmt.Printf("%v=%v\n", k, e)
119
                }
120
        default:
121
                return nil
122
        }
123
        return errors.New("end")
124
}
func main
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
56
func main() {
57
        var err error
58
        parseFlags()
59
        LoadDotEnvs()
60
        source.Assets()
61
        utils.InitLogs()
62
        args := flag.Args()
63
64
        if len(args) >= 1 {
65
                err := CatchCLI(args)
66
                if err != nil {
67
                        if err.Error() == "end" {
68
                                os.Exit(0)
69
                        }
70
                        fmt.Println(err)
71
                        os.Exit(1)
72
                }
73
        }
74
        utils.Log(1, fmt.Sprintf("Starting Statup v%v", VERSION))
75
        core.Configs, err = core.LoadConfig(utils.Directory)
76
        if err != nil {
77
                utils.Log(3, err)
78
                core.SetupMode = true
79
                fmt.Println(handlers.RunHTTPServer(ipAddress, port))
80
                os.Exit(1)
81
        }
82
        defer core.CloseDB()
83
        mainProcess()
84
}
+57
func main() {
58
        var err error
59
        parseFlags()
60
        LoadDotEnvs()
61
        source.Assets()
62
        utils.InitLogs()
63
        args := flag.Args()
64
65
        if len(args) >= 1 {
66
                err := CatchCLI(args)
67
                if err != nil {
68
                        if err.Error() == "end" {
69
                                os.Exit(0)
70
                        }
71
                        fmt.Println(err)
72
                        os.Exit(1)
73
                }
74
        }
75
        utils.Log(1, fmt.Sprintf("Starting Statup v%v", VERSION))
76
        core.Configs, err = core.LoadConfig(utils.Directory)
77
        if err != nil {
78
                utils.Log(3, err)
79
                core.SetupMode = true
80
                fmt.Println(handlers.RunHTTPServer(ipAddress, port))
81
                os.Exit(1)
82
        }
83
        defer core.CloseDB()
84
        mainProcess()
85
}
func RunOnce
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/cli.go:

-
126
func RunOnce() {
127
        var err error
128
        core.Configs, err = core.LoadConfig(utils.Directory)
129
        if err != nil {
130
                utils.Log(4, "config.yml file not found")
131
        }
132
        err = core.Configs.Connect(false, utils.Directory)
133
        if err != nil {
134
                utils.Log(4, err)
135
        }
136
        core.CoreApp, err = core.SelectCore()
137
        if err != nil {
138
                fmt.Println("Core database was not found, Statup is not setup yet.")
139
        }
140
        core.CoreApp.SelectAllServices()
141
        if err != nil {
142
                utils.Log(4, err)
143
        }
144
        for _, out := range core.CoreApp.Services {
145
                service := out.Select()
146
                out.Check(true)
147
                fmt.Printf("    Service %v | URL: %v | Latency: %0.0fms | Online: %v\n", service.Name, service.Domain, (service.Latency * 1000), service.Online)
148
        }
149
}
+127
func RunOnce() {
128
        var err error
129
        core.Configs, err = core.LoadConfig(utils.Directory)
130
        if err != nil {
131
                utils.Log(4, "config.yml file not found")
132
        }
133
        err = core.Configs.Connect(false, utils.Directory)
134
        if err != nil {
135
                utils.Log(4, err)
136
        }
137
        core.CoreApp, err = core.SelectCore()
138
        if err != nil {
139
                fmt.Println("Core database was not found, Statup is not setup yet.")
140
        }
141
        core.CoreApp.SelectAllServices()
142
        if err != nil {
143
                utils.Log(4, err)
144
        }
145
        for _, out := range core.CoreApp.Services {
146
                service := out.Select()
147
                out.Check(true)
148
                fmt.Printf("    Service %v | URL: %v | Latency: %0.0fms | Online: %v\n", service.Name, service.Domain, (service.Latency * 1000), service.Online)
149
        }
150
}
func mainProcess
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
97
func mainProcess() {
98
        dir := utils.Directory
99
        var err error
100
        core.Configs, err = core.LoadConfig(dir)
101
        if err != nil {
102
                utils.Log(4, fmt.Sprintf("could not load config.yml %v", err))
103
        }
104
        err = core.Configs.Connect(false, dir)
105
        if err != nil {
106
                utils.Log(4, fmt.Sprintf("could not connect to database: %v", err))
107
        }
108
        core.Configs.MigrateDatabase()
109
        core.InitApp()
110
        if !core.SetupMode {
111
                LoadPlugins(false)
112
                fmt.Println(handlers.RunHTTPServer(ipAddress, port))
113
                os.Exit(1)
114
        }
115
}
+98
func mainProcess() {
99
        dir := utils.Directory
100
        var err error
101
        core.Configs, err = core.LoadConfig(dir)
102
        if err != nil {
103
                utils.Log(4, fmt.Sprintf("could not load config.yml %v", err))
104
        }
105
        err = core.Configs.Connect(false, dir)
106
        if err != nil {
107
                utils.Log(4, fmt.Sprintf("could not connect to database: %v", err))
108
        }
109
        core.Configs.MigrateDatabase()
110
        core.InitApp()
111
        if !core.SetupMode {
112
                plugin.LoadPlugins(false)
113
                fmt.Println(handlers.RunHTTPServer(ipAddress, port))
114
                os.Exit(1)
115
        }
116
}
func CheckGithubUpdates
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/cli.go:

-
306
func CheckGithubUpdates() (GithubResponse, error) {
307
        var gitResp GithubResponse
308
        response, err := http.Get("https://api.github.com/repos/hunterlong/statup/releases/latest")
309
        if err != nil {
310
                return GithubResponse{}, err
311
        }
312
        defer response.Body.Close()
313
        contents, err := ioutil.ReadAll(response.Body)
314
        if err != nil {
315
                return GithubResponse{}, err
316
        }
317
        err = json.Unmarshal(contents, &gitResp)
318
        return gitResp, err
319
}
+307
func CheckGithubUpdates() (GithubResponse, error) {
308
        var gitResp GithubResponse
309
        response, err := http.Get("https://api.github.com/repos/hunterlong/statup/releases/latest")
310
        if err != nil {
311
                return GithubResponse{}, err
312
        }
313
        defer response.Body.Close()
314
        contents, err := ioutil.ReadAll(response.Body)
315
        if err != nil {
316
                return GithubResponse{}, err
317
        }
318
        err = json.Unmarshal(contents, &gitResp)
319
        return gitResp, err
320
}
func parseFlags
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
47
func parseFlags() {
48
        ip := flag.String("ip", "0.0.0.0", "IP address to run the Statup HTTP server")
49
        p := flag.Int("port", 8080, "Port to run the HTTP server")
50
        flag.Parse()
51
        ipAddress = *ip
52
        port = *p
53
}
+48
func parseFlags() {
49
        ip := flag.String("ip", "0.0.0.0", "IP address to run the Statup HTTP server")
50
        p := flag.Int("port", 8080, "Port to run the HTTP server")
51
        flag.Parse()
52
        ipAddress = *ip
53
        port = *p
54
}
func ForEachPlugin
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
117
func ForEachPlugin() {
118
        if len(core.CoreApp.Plugins) > 0 {
119
                //for _, p := range core.Plugins {
120
                //        p.OnShutdown()
121
                //}
122
        }
123
}
- -
func LoadPlugins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/cmd/main.go:

-
125
func LoadPlugins(debug bool) {
126
        //utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
127
        //if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
128
        //        os.Mkdir("./plugins", os.ModePerm)
129
        //}
130
        //
131
        ////ForEachPlugin()
132
        //files, err := ioutil.ReadDir("./plugins")
133
        //if err != nil {
134
        //        utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
135
        //        return
136
        //}
137
        //for _, f := range files {
138
        //        utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
139
        //        ext := strings.Split(f.Name(), ".")
140
        //        if len(ext) != 2 {
141
        //                utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
142
        //                continue
143
        //        }
144
        //        if ext[1] != "so" {
145
        //                utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
146
        //                continue
147
        //        }
148
        //        plug, err := plg.Open("plugins/" + f.Name())
149
        //        if err != nil {
150
        //                utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
151
        //                continue
152
        //        }
153
        //        symPlugin, err := plug.Lookup("Plugin")
154
        //        if err != nil {
155
        //                utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
156
        //                continue
157
        //        }
158
        //
159
        //        if debug {
160
        //                utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
161
        //                utils.Log(1, structs.Map(symPlugin))
162
        //        }
163
        //
164
        //        var plugActions types.PluginActions
165
        //        plugActions, ok := symPlugin.(types.PluginActions)
166
        //        if !ok {
167
        //                utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
168
        //                if debug {
169
        //                        //fmt.Println(symPlugin.(plugin.PluginActions))
170
        //                }
171
        //                continue
172
        //        }
173
        //
174
        //        if debug {
175
        //                TestPlugin(plugActions)
176
        //        } else {
177
        //                plugActions.OnLoad(*core.DbSession)
178
        //                core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
179
        //                core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
180
        //        }
181
        //}
182
        //if !debug {
183
        //        utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
184
        //}
185
}
+118
func ForEachPlugin() {
119
        if len(core.CoreApp.Plugins) > 0 {
120
                //for _, p := range core.Plugins {
121
                //        p.OnShutdown()
122
                //}
123
        }
124
}
-
Package Overview: github.com/hunterlong/statup/core 54.09%

This is a coverage report created after analysis of the github.com/hunterlong/statup/core package. It +

Package Overview: github.com/hunterlong/statup/core 53.35%

This is a coverage report created after analysis of the github.com/hunterlong/statup/core package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/core | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

- + - - + - - + + - + + + + + - - - - - - - - + + + + - - - + + + + - - - + + + + + + - - - + + + + + + - - - - + + + + - - - - - - - - + + + - + - + + - + - + - + + - + - - + - + - + + - - - + + - + + - - + + - - - - - - - + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + +
InsertLargeSampleData(...)github.com/hunterlong/statup/core/sample.go100.00%28/28
Service.CheckQueue(...)github.com/hunterlong/statup/core/checker.go100.00%13/13
InsertSampleData(...)github.com/hunterlong/statup/core/sample.go100.00%13/13
Service.CheckQueue(...)github.com/hunterlong/statup/core/checker.go100.00%13/13
insertSampleCheckins(...)github.com/hunterlong/statup/core/sample.go100.00%12/12
Service.dnsCheck(...)github.com/hunterlong/statup/core/checker.go100.00%11/11
DbConfig.CreateDatabase(...)github.com/hunterlong/statup/core/database.go100.00%11/11
insertHitRecords(...)github.com/hunterlong/statup/core/sample.go100.00%10/10
DbConfig.DropDatabase(...)github.com/hunterlong/statup/core/database.go100.00%10/10
insertFailureRecords(...)github.com/hunterlong/statup/core/sample.go100.00%8/8
recordSuccess(...)github.com/hunterlong/statup/core/checker.go100.00%6/6
checkin.Expected(...)github.com/hunterlong/statup/core/checkin.go100.00%5/5
Checkin.Expected(...)github.com/hunterlong/statup/core/checkin.go100.00%5/5
Core.CountOnline(...)github.com/hunterlong/statup/core/services.go100.00%5/5
recordFailure(...)github.com/hunterlong/statup/core/checker.go100.00%5/5
Service.Hits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
Service.LimitedHits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
Service.CheckinProcess(...)github.com/hunterlong/statup/core/services.go100.00%4/4
Service.LimitedFailures(...)github.com/hunterlong/statup/core/failures.go100.00%4/4
Service.TotalHits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
Service.Hits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
Checkin.CreateFailure(...)github.com/hunterlong/statup/core/checkin.go100.00%4/4
Service.TotalFailuresSince(...)github.com/hunterlong/statup/core/failures.go100.00%4/4
user.Update(...)github.com/hunterlong/statup/core/users.go100.00%4/4
NewCore(...)github.com/hunterlong/statup/core/core.go100.00%4/4
Service.TotalHitsSince(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
insertSampleUsers(...)github.com/hunterlong/statup/core/sample.go100.00%4/4
Service.TotalFailuresSince(...)github.com/hunterlong/statup/core/failures.go100.00%4/4
NewCore(...)github.com/hunterlong/statup/core/core.go100.00%4/4
Service.LimitedHits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
SelectUsername(...)github.com/hunterlong/statup/core/users.go100.00%4/4
user.Update(...)github.com/hunterlong/statup/core/users.go100.00%4/4
reverseHits(...)github.com/hunterlong/statup/core/hits.go100.00%3/3
insertSampleCore(...)github.com/hunterlong/statup/core/sample.go100.00%3/3
checkin.Last(...)github.com/hunterlong/statup/core/checkin.go100.00%3/3
SelectUser(...)github.com/hunterlong/statup/core/users.go100.00%3/3
Service.TotalHits(...)github.com/hunterlong/statup/core/hits.go100.00%4/4
Checkin.BeforeCreate(...)github.com/hunterlong/statup/core/database.go100.00%3/3
Service.Check(...)github.com/hunterlong/statup/core/checker.go100.00%3/3
insertSampleCore(...)github.com/hunterlong/statup/core/sample.go100.00%3/3
SelectUser(...)github.com/hunterlong/statup/core/users.go100.00%3/3
Service.Checkins(...)github.com/hunterlong/statup/core/services.go100.00%3/3
checkin.Hits(...)github.com/hunterlong/statup/core/checkin.go100.00%3/3
checkin.BeforeCreate(...)github.com/hunterlong/statup/core/database.go100.00%3/3
checkinHit.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
reverseHits(...)github.com/hunterlong/statup/core/hits.go100.00%3/3
Checkin.Hits(...)github.com/hunterlong/statup/core/checkin.go100.00%3/3
Checkin.Last(...)github.com/hunterlong/statup/core/checkin.go100.00%3/3
updateService(...)github.com/hunterlong/statup/core/services.go100.00%2/2
user.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
checkin.Grace(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
checkin.Period(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
failure.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
Checkin.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
Checkin.Period(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
checkinHit.Ago(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
checkinHit.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
Checkin.Grace(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
Checkin.Service(...)github.com/hunterlong/statup/core/checkin.go100.00%2/2
failure.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
CheckHash(...)github.com/hunterlong/statup/core/users.go100.00%2/2
Service.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
updateService(...)github.com/hunterlong/statup/core/services.go100.00%2/2
checkin.AfterFind(...)github.com/hunterlong/statup/core/database.go100.00%2/2
hitsDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
user.Delete(...)github.com/hunterlong/statup/core/users.go100.00%1/1
init(...)github.com/hunterlong/statup/core/core.go100.00%1/1
ReturnService(...)github.com/hunterlong/statup/core/services.go100.00%1/1
reorderServices(...)github.com/hunterlong/statup/core/services.go100.00%1/1
ServiceOrder.Len(...)github.com/hunterlong/statup/core/core.go100.00%1/1
ServiceOrder.Swap(...)github.com/hunterlong/statup/core/core.go100.00%1/1
ServiceOrder.Less(...)github.com/hunterlong/statup/core/core.go100.00%1/1
failuresDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
ServiceOrder.Swap(...)github.com/hunterlong/statup/core/core.go100.00%1/1
servicesDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
coreDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
ServiceOrder.Len(...)github.com/hunterlong/statup/core/core.go100.00%1/1
hitsDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
ReturnUser(...)github.com/hunterlong/statup/core/users.go100.00%1/1
ReturnCheckinHit(...)github.com/hunterlong/statup/core/checkin.go100.00%1/1
usersDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
checkinDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
checkinHitsDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
init(...)github.com/hunterlong/statup/core/core.go100.00%1/1
ReturnCheckin(...)github.com/hunterlong/statup/core/checkin.go100.00%1/1
usersDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
reorderServices(...)github.com/hunterlong/statup/core/services.go100.00%1/1
Service.Select(...)github.com/hunterlong/statup/core/services.go100.00%1/1
ReturnUser(...)github.com/hunterlong/statup/core/users.go100.00%1/1
user.Delete(...)github.com/hunterlong/statup/core/users.go100.00%1/1
DbConfig.Close(...)github.com/hunterlong/statup/core/database.go100.00%1/1
ReturnCheckinHit(...)github.com/hunterlong/statup/core/checkin.go100.00%1/1
ReturnService(...)github.com/hunterlong/statup/core/services.go100.00%1/1
servicesDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
coreDB(...)github.com/hunterlong/statup/core/database.go100.00%1/1
Service.parseHost(...)github.com/hunterlong/statup/core/checker.go90.91%10/11
Service.dnsCheck(...)github.com/hunterlong/statup/core/checker.go90.91%10/11
Service.Sum(...)github.com/hunterlong/statup/core/hits.go85.71%6/7
Core.SelectAllServices(...)github.com/hunterlong/statup/core/services.go84.62%11/13
Service.Update(...)github.com/hunterlong/statup/core/services.go84.62%11/13
Core.SelectAllServices(...)github.com/hunterlong/statup/core/services.go84.62%11/13
Service.Delete(...)github.com/hunterlong/statup/core/services.go81.82%9/11
Service.Create(...)github.com/hunterlong/statup/core/services.go81.82%9/11
Service.OnlineSince(...)github.com/hunterlong/statup/core/services.go80.00%12/15
Service.duration(...)github.com/hunterlong/statup/core/checker.go80.00%4/5
Checkin.Routine(...)github.com/hunterlong/statup/core/checkin.go80.00%12/15
SelectAllUsers(...)github.com/hunterlong/statup/core/users.go80.00%4/5
Service.duration(...)github.com/hunterlong/statup/core/checker.go80.00%4/5
Service.AvgUptime(...)github.com/hunterlong/statup/core/services.go78.57%11/14
Service.AllFailures(...)github.com/hunterlong/statup/core/failures.go77.78%7/9
Service.Downtime(...)github.com/hunterlong/statup/core/services.go75.00%6/8
SelectService(...)github.com/hunterlong/statup/core/services.go75.00%3/4
Checkin.Create(...)github.com/hunterlong/statup/core/checkin.go75.00%6/8
Service.index(...)github.com/hunterlong/statup/core/services.go75.00%3/4
Service.checkHttp(...)github.com/hunterlong/statup/core/checker.go74.47%35/47
SelectService(...)github.com/hunterlong/statup/core/services.go75.00%3/4
user.Create(...)github.com/hunterlong/statup/core/users.go72.73%8/11
Service.checkTcp(...)github.com/hunterlong/statup/core/checker.go72.00%18/25
DbConfig.Save(...)github.com/hunterlong/statup/core/database.go71.43%10/14
AuthUser(...)github.com/hunterlong/statup/core/users.go71.43%5/7
Service.CreateFailure(...)github.com/hunterlong/statup/core/failures.go71.43%5/7
AuthUser(...)github.com/hunterlong/statup/core/users.go71.43%5/7
SelectCore(...)github.com/hunterlong/statup/core/core.go69.23%9/13
Service.checkHttp(...)github.com/hunterlong/statup/core/checker.go68.09%32/47
LoadConfig(...)github.com/hunterlong/statup/core/configs.go66.67%8/12
DbConfig.MigrateDatabase(...)github.com/hunterlong/statup/core/database.go66.67%8/12
checkin.Create(...)github.com/hunterlong/statup/core/checkin.go66.67%4/6
Service.BeforeCreate(...)github.com/hunterlong/statup/core/database.go66.67%2/3
user.BeforeCreate(...)github.com/hunterlong/statup/core/database.go66.67%2/3
checkinHit.BeforeCreate(...)github.com/hunterlong/statup/core/database.go66.67%2/3
Service.BeforeCreate(...)github.com/hunterlong/statup/core/database.go66.67%2/3
Service.CreateHit(...)github.com/hunterlong/statup/core/hits.go60.00%3/5
checkin.Update(...)github.com/hunterlong/statup/core/checkin.go60.00%3/5
Checkin.Update(...)github.com/hunterlong/statup/core/checkin.go60.00%3/5
checkinHit.Create(...)github.com/hunterlong/statup/core/checkin.go57.14%4/7
Service.SmallText(...)github.com/hunterlong/statup/core/services.go50.00%6/12
insertNotifierDB(...)github.com/hunterlong/statup/core/core.go50.00%3/6
@363:8(...)github.com/hunterlong/statup/core/database.go50.00%1/2
DbConfig.Connect(...)github.com/hunterlong/statup/core/database.go46.67%14/30
LoadUsingEnv(...)github.com/hunterlong/statup/core/configs.go0.00%0/40
failure.ParseError(...)github.com/hunterlong/statup/core/failures.go0.00%0/28
failure.ParseError(...)github.com/hunterlong/statup/core/failures.go0.00%0/30
ExportIndexHTML(...)github.com/hunterlong/statup/core/export.go0.00%0/23
GraphDataRaw(...)github.com/hunterlong/statup/core/services.go0.00%0/16
InsertSampleHits(...)github.com/hunterlong/statup/core/sample.go0.00%0/14
DbConfig.Update(...)github.com/hunterlong/statup/core/database.go0.00%0/12
Dbtimestamp(...)github.com/hunterlong/statup/core/services.go0.00%0/12
DbConfig.Update(...)github.com/hunterlong/statup/core/database.go0.00%0/12
ExportChartsJs(...)github.com/hunterlong/statup/core/export.go0.00%0/11
Service.TotalUptime(...)github.com/hunterlong/statup/core/services.go0.00%0/10
Checkin.RecheckCheckinFailure(...)github.com/hunterlong/statup/core/checkin.go0.00%0/8
DbConfig.CreateCore(...)github.com/hunterlong/statup/core/database.go0.00%0/8
checkin.RecheckCheckinFailure(...)github.com/hunterlong/statup/core/checkin.go0.00%0/8
Service.GraphData(...)github.com/hunterlong/statup/core/services.go0.00%0/8
Service.AvgTime(...)github.com/hunterlong/statup/core/services.go0.00%0/8
InitApp(...)github.com/hunterlong/statup/core/core.go0.00%0/6
Service.GraphData(...)github.com/hunterlong/statup/core/services.go0.00%0/8
Core.Count24HFailures(...)github.com/hunterlong/statup/core/failures.go0.00%0/6
InitApp(...)github.com/hunterlong/statup/core/core.go0.00%0/6
CountFailures(...)github.com/hunterlong/statup/core/failures.go0.00%0/6
Service.lastFailure(...)github.com/hunterlong/statup/core/services.go0.00%0/5
recordFailure(...)github.com/hunterlong/statup/core/checker.go0.00%0/5
DateScanObj.ToString(...)github.com/hunterlong/statup/core/services.go0.00%0/5
Service.lastFailure(...)github.com/hunterlong/statup/core/services.go0.00%0/5
DatabaseMaintence(...)github.com/hunterlong/statup/core/database.go0.00%0/5
Core.CurrentTime(...)github.com/hunterlong/statup/core/core.go0.00%0/4
DeleteAllSince(...)github.com/hunterlong/statup/core/database.go0.00%0/4
Core.AllOnline(...)github.com/hunterlong/statup/core/core.go0.00%0/4
Service.TotalFailures(...)github.com/hunterlong/statup/core/failures.go0.00%0/4
DeleteAllSince(...)github.com/hunterlong/statup/core/database.go0.00%0/4
Service.DeleteFailures(...)github.com/hunterlong/statup/core/failures.go0.00%0/4
DbConfig.InsertCore(...)github.com/hunterlong/statup/core/database.go0.00%0/4
Core.AllOnline(...)github.com/hunterlong/statup/core/core.go0.00%0/4
DeleteConfig(...)github.com/hunterlong/statup/core/configs.go0.00%0/3
Core.SassVars(...)github.com/hunterlong/statup/core/core.go0.00%0/3
Core.BaseSASS(...)github.com/hunterlong/statup/core/core.go0.00%0/3
SelectCheckin(...)github.com/hunterlong/statup/core/checkin.go0.00%0/3
Core.MobileSASS(...)github.com/hunterlong/statup/core/core.go0.00%0/3
checkServices(...)github.com/hunterlong/statup/core/checker.go0.00%0/3
Core.CurrentTime(...)github.com/hunterlong/statup/core/core.go0.00%0/4
Hit.BeforeCreate(...)github.com/hunterlong/statup/core/database.go0.00%0/3
SelectCheckinId(...)github.com/hunterlong/statup/core/checkin.go0.00%0/3
Core.SassVars(...)github.com/hunterlong/statup/core/core.go0.00%0/3
SelectCheckin(...)github.com/hunterlong/statup/core/checkin.go0.00%0/3
DeleteConfig(...)github.com/hunterlong/statup/core/configs.go0.00%0/3
Service.LimitedCheckins(...)github.com/hunterlong/statup/core/services.go0.00%0/3
Core.MobileSASS(...)github.com/hunterlong/statup/core/core.go0.00%0/3
Core.BaseSASS(...)github.com/hunterlong/statup/core/core.go0.00%0/3
failure.BeforeCreate(...)github.com/hunterlong/statup/core/database.go0.00%0/3
Checkin.Delete(...)github.com/hunterlong/statup/core/checkin.go0.00%0/3
checkServices(...)github.com/hunterlong/statup/core/checker.go0.00%0/3
Service.TotalFailures24(...)github.com/hunterlong/statup/core/failures.go0.00%0/2
Service.Online24(...)github.com/hunterlong/statup/core/services.go0.00%0/2
Service.ToJSON(...)github.com/hunterlong/statup/core/services.go0.00%0/2
Service.HitsBetween(...)github.com/hunterlong/statup/core/database.go0.00%0/2
failure.Ago(...)github.com/hunterlong/statup/core/failures.go0.00%0/2
Service.HitsBetween(...)github.com/hunterlong/statup/core/database.go0.00%0/2
CloseDB(...)github.com/hunterlong/statup/core/database.go0.00%0/2
failure.Delete(...)github.com/hunterlong/statup/core/failures.go0.00%0/2
Hit.AfterFind(...)github.com/hunterlong/statup/core/database.go0.00%0/2
DbConfig.waitForDb(...)github.com/hunterlong/statup/core/database.go0.00%0/2
Service.TotalFailures24(...)github.com/hunterlong/statup/core/failures.go0.00%0/2
CloseDB(...)github.com/hunterlong/statup/core/database.go0.00%0/2
Service.AvgUptime24(...)github.com/hunterlong/statup/core/services.go0.00%0/2
UpdateCore(...)github.com/hunterlong/statup/core/core.go0.00%0/2
@65:17(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Service.DowntimeText(...)github.com/hunterlong/statup/core/services.go0.00%0/1
Service.UpdateSingle(...)github.com/hunterlong/statup/core/services.go0.00%0/1
@56:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@59:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Core.ServicesCount(...)github.com/hunterlong/statup/core/services.go0.00%0/1
@62:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@50:9(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Core.UsingAssets(...)github.com/hunterlong/statup/core/core.go0.00%0/1
@68:10(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@71:17(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Core.ToCore(...)github.com/hunterlong/statup/core/core.go0.00%0/1
@94:11(...)github.com/hunterlong/statup/core/export.go0.00%0/1
injectDatabase(...)github.com/hunterlong/statup/core/export.go0.00%0/1
checkin.String(...)github.com/hunterlong/statup/core/checkin.go0.00%0/1
@53:11(...)github.com/hunterlong/statup/core/export.go0.00%0/1
github.com/hunterlong/statup/core54.09%496/917
DbConfig.Close(...)github.com/hunterlong/statup/core/database.go0.00%0/1
Core.UsingAssets(...)github.com/hunterlong/statup/core/core.go0.00%0/1
Service.UpdateSingle(...)github.com/hunterlong/statup/core/services.go0.00%0/1
Service.DowntimeText(...)github.com/hunterlong/statup/core/services.go0.00%0/1
injectDatabase(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Core.ServicesCount(...)github.com/hunterlong/statup/core/services.go0.00%0/1
@94:11(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@71:17(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@68:10(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@65:17(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@62:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@59:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
Checkin.String(...)github.com/hunterlong/statup/core/checkin.go0.00%0/1
@56:14(...)github.com/hunterlong/statup/core/export.go0.00%0/1
@50:9(...)github.com/hunterlong/statup/core/export.go0.00%0/1
github.com/hunterlong/statup/core53.35%510/956
func InsertLargeSampleData
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

185
func InsertLargeSampleData() error {
186
        insertSampleCore()
187
        InsertSampleData()
188
        insertSampleUsers()
189
        insertSampleCheckins()
190
        s6 := ReturnService(&types.Service{
191
                Name:           "JSON Lint",
192
                Domain:         "https://jsonlint.com",
193
                ExpectedStatus: 200,
194
                Interval:       15,
195
                Type:           "http",
196
                Method:         "GET",
197
                Timeout:        10,
198
                Order:          6,
199
        })
200
201
        s7 := ReturnService(&types.Service{
202
                Name:           "Demo Page",
203
                Domain:         "https://demo.statup.io",
204
                ExpectedStatus: 200,
205
                Interval:       30,
206
                Type:           "http",
207
                Method:         "GET",
208
                Timeout:        15,
209
                Order:          7,
210
        })
211
212
        s8 := ReturnService(&types.Service{
213
                Name:           "Golang",
214
                Domain:         "https://golang.org",
215
                ExpectedStatus: 200,
216
                Interval:       15,
217
                Type:           "http",
218
                Method:         "GET",
219
                Timeout:        10,
220
                Order:          8,
221
        })
222
223
        s9 := ReturnService(&types.Service{
224
                Name:           "Santa Monica",
225
                Domain:         "https://www.santamonica.com",
226
                ExpectedStatus: 200,
227
                Interval:       15,
228
                Type:           "http",
229
                Method:         "GET",
230
                Timeout:        10,
231
                Order:          9,
232
        })
233
234
        s10 := ReturnService(&types.Service{
235
                Name:           "Oeschs Die Dritten",
236
                Domain:         "https://www.oeschs-die-dritten.ch/en/",
237
                ExpectedStatus: 200,
238
                Interval:       15,
239
                Type:           "http",
240
                Method:         "GET",
241
                Timeout:        10,
242
                Order:          10,
243
        })
244
245
        s11 := ReturnService(&types.Service{
246
                Name:           "XS Project - Bochka, Bass, Kolbaser",
247
                Domain:         "https://www.youtube.com/watch?v=VLW1ieY4Izw",
248
                ExpectedStatus: 200,
249
                Interval:       60,
250
                Type:           "http",
251
                Method:         "GET",
252
                Timeout:        20,
253
                Order:          11,
254
        })
255
256
        s12 := ReturnService(&types.Service{
257
                Name:           "Github",
258
                Domain:         "https://github.com/hunterlong",
259
                ExpectedStatus: 200,
260
                Interval:       60,
261
                Type:           "http",
262
                Method:         "GET",
263
                Timeout:        20,
264
                Order:          12,
265
        })
266
267
        s13 := ReturnService(&types.Service{
268
                Name:           "Failing URL",
269
                Domain:         "http://thisdomainisfakeanditsgoingtofail.com",
270
                ExpectedStatus: 200,
271
                Interval:       45,
272
                Type:           "http",
273
                Method:         "GET",
274
                Timeout:        10,
275
                Order:          13,
276
        })
277
278
        s14 := ReturnService(&types.Service{
279
                Name:           "Oesch's die Dritten - Die Jodelsprache",
280
                Domain:         "https://www.youtube.com/watch?v=k3GTxRt4iao",
281
                ExpectedStatus: 200,
282
                Interval:       60,
283
                Type:           "http",
284
                Method:         "GET",
285
                Timeout:        12,
286
                Order:          14,
287
        })
288
289
        s15 := ReturnService(&types.Service{
290
                Name:           "Gorm",
291
                Domain:         "http://gorm.io/",
292
                ExpectedStatus: 200,
293
                Interval:       30,
294
                Type:           "http",
295
                Method:         "GET",
296
                Timeout:        12,
297
                Order:          15,
298
        })
299
300
        s6.Create(false)
301
        s7.Create(false)
302
        s8.Create(false)
303
        s9.Create(false)
304
        s10.Create(false)
305
        s11.Create(false)
306
        s12.Create(false)
307
        s13.Create(false)
308
        s14.Create(false)
309
        s15.Create(false)
310
311
        var dayAgo = time.Now().Add(-24 * time.Hour).Add(-10 * time.Minute)
312
313
        insertHitRecords(dayAgo, 1450)
314
315
        insertFailureRecords(dayAgo, 730)
316
317
        return nil
318
}
-
func Service.CheckQueue
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
43
func (s *Service) CheckQueue(record bool) {
44
        s.Checkpoint = time.Now()
45
        s.SleepDuration = time.Duration((time.Duration(s.Id) * 100) * time.Millisecond)
46
CheckLoop:
47
        for {
48
                select {
49
                case <-s.Running:
50
                        utils.Log(1, fmt.Sprintf("Stopping service: %v", s.Name))
51
                        break CheckLoop
52
                case <-time.After(s.SleepDuration):
53
                        s.Check(record)
54
                        s.Checkpoint = s.Checkpoint.Add(s.duration())
55
                        sleep := s.Checkpoint.Sub(time.Now())
56
                        if !s.Online {
57
                                s.SleepDuration = s.duration()
58
                        } else {
59
                                s.SleepDuration = sleep
60
                        }
61
                }
62
                continue
63
        }
64
}
-
func InsertSampleData
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

27
func InsertSampleData() error {
28
        utils.Log(1, "Inserting Sample Data...")
29
        s1 := ReturnService(&types.Service{
30
                Name:           "Google",
31
                Domain:         "https://google.com",
32
                ExpectedStatus: 200,
33
                Interval:       10,
34
                Type:           "http",
35
                Method:         "GET",
36
                Timeout:        10,
37
                Order:          1,
38
        })
39
        s2 := ReturnService(&types.Service{
40
                Name:           "Statup Github",
41
                Domain:         "https://github.com/hunterlong/statup",
42
                ExpectedStatus: 200,
43
                Interval:       30,
44
                Type:           "http",
45
                Method:         "GET",
46
                Timeout:        20,
47
                Order:          2,
48
        })
49
        s3 := ReturnService(&types.Service{
50
                Name:           "JSON Users Test",
51
                Domain:         "https://jsonplaceholder.typicode.com/users",
52
                ExpectedStatus: 200,
53
                Interval:       60,
54
                Type:           "http",
55
                Method:         "GET",
56
                Timeout:        30,
57
                Order:          3,
58
        })
59
        s4 := ReturnService(&types.Service{
60
                Name:           "JSON API Tester",
61
                Domain:         "https://jsonplaceholder.typicode.com/posts",
62
                ExpectedStatus: 201,
63
                Expected:       `(title)": "((\\"|[statup])*)"`,
64
                Interval:       30,
65
                Type:           "http",
66
                Method:         "POST",
67
                PostData:       `{ "title": "statup", "body": "bar", "userId": 19999 }`,
68
                Timeout:        30,
69
                Order:          4,
70
        })
71
        s5 := ReturnService(&types.Service{
72
                Name:     "Google DNS",
73
                Domain:   "8.8.8.8",
74
                Interval: 20,
75
                Type:     "tcp",
76
                Port:     53,
77
                Timeout:  120,
78
                Order:    5,
79
        })
80
81
        s1.Create(false)
82
        s2.Create(false)
83
        s3.Create(false)
84
        s4.Create(false)
85
        s5.Create(false)
86
87
        utils.Log(1, "Sample data has finished importing")
88
89
        return nil
90
}
-
func insertSampleCheckins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

-
93
func insertSampleCheckins() error {
94
        s1 := SelectService(1)
95
        checkin1 := ReturnCheckin(&types.Checkin{
96
                Service:     s1.Id,
97
                Interval:    300,
98
                GracePeriod: 300,
99
        })
100
        checkin1.Update()
101
102
        s2 := SelectService(1)
103
        checkin2 := ReturnCheckin(&types.Checkin{
104
                Service:     s2.Id,
105
                Interval:    900,
106
                GracePeriod: 300,
107
        })
108
        checkin2.Update()
109
110
        checkTime := time.Now().Add(-24 * time.Hour)
111
        for i := 0; i <= 60; i++ {
112
                checkHit := ReturnCheckinHit(&types.CheckinHit{
113
                        Checkin:   checkin1.Id,
114
                        From:      "192.168.0.1",
115
                        CreatedAt: checkTime.UTC(),
116
                })
117
                checkHit.Create()
118
                checkTime = checkTime.Add(10 * time.Minute)
119
        }
120
        return nil
121
}
+
func Service.CheckQueue
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
43
func (s *Service) CheckQueue(record bool) {
44
        s.Checkpoint = time.Now()
45
        s.SleepDuration = time.Duration((time.Duration(s.Id) * 100) * time.Millisecond)
46
CheckLoop:
47
        for {
48
                select {
49
                case <-s.Running:
50
                        utils.Log(1, fmt.Sprintf("Stopping service: %v", s.Name))
51
                        break CheckLoop
52
                case <-time.After(s.SleepDuration):
53
                        s.Check(record)
54
                        s.Checkpoint = s.Checkpoint.Add(s.duration())
55
                        sleep := s.Checkpoint.Sub(time.Now())
56
                        if !s.Online {
57
                                s.SleepDuration = s.duration()
58
                        } else {
59
                                s.SleepDuration = sleep
60
                        }
61
                }
62
                continue
63
        }
64
}
-
func Service.dnsCheck
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
96
func (s *Service) dnsCheck() (float64, error) {
97
        var err error
98
        t1 := time.Now()
99
        host := s.parseHost()
100
        if s.Type == "tcp" {
101
                _, err = net.LookupHost(host)
102
        } else {
103
                _, err = net.LookupIP(host)
104
        }
105
        if err != nil {
106
                return 0, err
107
        }
108
        t2 := time.Now()
109
        subTime := t2.Sub(t1).Seconds()
110
        return subTime, err
111
}
+
func insertSampleCheckins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

+
93
func insertSampleCheckins() error {
94
        s1 := SelectService(1)
95
        checkin1 := ReturnCheckin(&types.Checkin{
96
                ServiceId:   s1.Id,
97
                Interval:    300,
98
                GracePeriod: 300,
99
        })
100
        checkin1.Update()
101
102
        s2 := SelectService(1)
103
        checkin2 := ReturnCheckin(&types.Checkin{
104
                ServiceId:   s2.Id,
105
                Interval:    900,
106
                GracePeriod: 300,
107
        })
108
        checkin2.Update()
109
110
        checkTime := time.Now().Add(-24 * time.Hour)
111
        for i := 0; i <= 60; i++ {
112
                checkHit := ReturnCheckinHit(&types.CheckinHit{
113
                        Checkin:   checkin1.Id,
114
                        From:      "192.168.0.1",
115
                        CreatedAt: checkTime.UTC(),
116
                })
117
                checkHit.Create()
118
                checkTime = checkTime.Add(10 * time.Minute)
119
        }
120
        return nil
121
}
func DbConfig.CreateDatabase
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

342
func (db *DbConfig) CreateDatabase() error {
343
        utils.Log(1, "Creating Database Tables...")
344
        err := DbSession.CreateTable(&types.Checkin{})
345
        err = DbSession.CreateTable(&types.CheckinHit{})
346
        err = DbSession.CreateTable(&notifier.Notification{})
347
        err = DbSession.Table("core").CreateTable(&types.Core{})
348
        err = DbSession.CreateTable(&types.Failure{})
349
        err = DbSession.CreateTable(&types.Hit{})
350
        err = DbSession.CreateTable(&types.Service{})
351
        err = DbSession.CreateTable(&types.User{})
352
        utils.Log(1, "Statup Database Created")
353
        return err.Error
354
}
@@ -381,23 +382,35 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func recordSuccess
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

232
func recordSuccess(s *Service) {
233
        s.Online = true
234
        s.LastOnline = time.Now()
235
        hit := &types.Hit{
236
                Service:   s.Id,
237
                Latency:   s.Latency,
238
                PingTime:  s.PingTime,
239
                CreatedAt: time.Now(),
240
        }
241
        utils.Log(1, fmt.Sprintf("Service %v Successful Response: %0.2f ms | Lookup in: %0.2f ms", s.Name, hit.Latency*1000, hit.PingTime*1000))
242
        s.CreateHit(hit)
243
        notifier.OnSuccess(s.Service)
244
}
-
func checkin.Expected
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
69
func (c *checkin) Expected() time.Duration {
70
        last := c.Last().CreatedAt
71
        now := time.Now()
72
        lastDir := now.Sub(last)
73
        sub := time.Duration(c.Period() - lastDir)
74
        return sub
75
}
+
func Checkin.Expected
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
120
func (c *Checkin) Expected() time.Duration {
121
        last := c.Last().CreatedAt
122
        now := time.Now()
123
        lastDir := now.Sub(last)
124
        sub := time.Duration(c.Period() - lastDir)
125
        return sub
126
}
func Core.CountOnline
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
382
func (c *Core) CountOnline() int {
383
        amount := 0
384
        for _, s := range CoreApp.Services {
385
                if s.Select().Online {
386
                        amount++
387
                }
388
        }
389
        return amount
390
}
+402
func (c *Core) CountOnline() int {
403
        amount := 0
404
        for _, s := range CoreApp.Services {
405
                if s.Select().Online {
406
                        amount++
407
                }
408
        }
409
        return amount
410
}
-
func recordFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
247
func recordFailure(s *Service, issue string) {
248
        s.Online = false
249
        fail := &types.Failure{
250
                Service:   s.Id,
251
                Issue:     issue,
252
                PingTime:  s.PingTime,
253
                CreatedAt: time.Now(),
254
        }
255
        utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000))
256
        s.CreateFailure(fail)
257
        notifier.OnFailure(s.Service, fail)
258
}
+
func Service.LimitedHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

+
47
func (s *Service) LimitedHits() ([]*types.Hit, error) {
48
        var hits []*types.Hit
49
        col := hitsDB().Where("service = ?", s.Id).Order("id desc").Limit(1024)
50
        err := col.Find(&hits)
51
        return reverseHits(hits), err.Error
52
}
-
func Service.Hits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

-
39
func (s *Service) Hits() ([]*types.Hit, error) {
40
        var hits []*types.Hit
41
        col := hitsDB().Where("service = ?", s.Id).Order("id desc")
42
        err := col.Find(&hits)
43
        return hits, err.Error
44
}
+
func Service.CheckinProcess
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
55
func (s *Service) CheckinProcess() {
56
        checkins := s.Checkins()
57
        for _, c := range checkins {
58
                c.Start()
59
                go c.Routine()
60
        }
61
}
func Service.LimitedFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

68
func (s *Service) LimitedFailures() []*failure {
69
        var failArr []*failure
70
        col := failuresDB().Where("service = ?", s.Id).Order("id desc").Limit(10)
71
        col.Find(&failArr)
72
        return failArr
73
}
-
func Service.TotalHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

-
63
func (s *Service) TotalHits() (uint64, error) {
64
        var count uint64
65
        col := hitsDB().Where("service = ?", s.Id)
66
        err := col.Count(&count)
67
        return count, err.Error
68
}
+
func Service.Hits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

+
39
func (s *Service) Hits() ([]*types.Hit, error) {
40
        var hits []*types.Hit
41
        col := hitsDB().Where("service = ?", s.Id).Order("id desc")
42
        err := col.Find(&hits)
43
        return hits, err.Error
44
}
+ +
func Checkin.CreateFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
80
func (c *Checkin) CreateFailure() (int64, error) {
81
        service := c.Service()
82
        fail := &types.Failure{
83
                Issue:    fmt.Sprintf("Checkin %v was not reported %v ago, it expects a request every %v", c.Name, utils.FormatDuration(c.Expected()), utils.FormatDuration(c.Period())),
84
                Method:   "checkin",
85
                MethodId: c.Id,
86
                Service:  service.Id,
87
                PingTime: c.Expected().Seconds() * 0.001,
88
        }
89
        row := failuresDB().Create(&fail)
90
        return fail.Id, row.Error
91
}
+ +
func Service.TotalFailuresSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

+
124
func (s *Service) TotalFailuresSince(ago time.Time) (uint64, error) {
125
        var count uint64
126
        rows := failuresDB().Where("service = ? AND created_at > ?", s.Id, ago.UTC().Format("2006-01-02 15:04:05")).Not("method = 'checkin'")
127
        err := rows.Count(&count)
128
        return count, err.Error
129
}
+ +
func user.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

+
56
func (u *user) Update() error {
57
        u.Password = utils.HashPassword(u.Password)
58
        u.ApiKey = utils.NewSHA1Hash(5)
59
        u.ApiSecret = utils.NewSHA1Hash(10)
60
        return usersDB().Update(u).Error
61
}
+ +
func NewCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
47
func NewCore() *Core {
48
        CoreApp = new(Core)
49
        CoreApp.Core = new(types.Core)
50
        CoreApp.Started = time.Now()
51
        return CoreApp
52
}
func Service.TotalHitsSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

71
func (s *Service) TotalHitsSince(ago time.Time) (uint64, error) {
72
        var count uint64
73
        rows := hitsDB().Where("service = ? AND created_at > ?", s.Id, ago.UTC().Format("2006-01-02 15:04:05"))
74
        err := rows.Count(&count)
75
        return count, err.Error
76
}
@@ -405,77 +418,86 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func insertSampleUsers
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

165
func insertSampleUsers() {
166
        u2 := ReturnUser(&types.User{
167
                Username: "testadmin",
168
                Password: "password123",
169
                Email:    "info@betatude.com",
170
                Admin:    true,
171
        })
172
173
        u3 := ReturnUser(&types.User{
174
                Username: "testadmin2",
175
                Password: "password123",
176
                Email:    "info@adminhere.com",
177
                Admin:    true,
178
        })
179
180
        u2.Create()
181
        u3.Create()
182
}
-
func Service.TotalFailuresSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

-
124
func (s *Service) TotalFailuresSince(ago time.Time) (uint64, error) {
125
        var count uint64
126
        rows := failuresDB().Where("service = ? AND created_at > ?", s.Id, ago.UTC().Format("2006-01-02 15:04:05"))
127
        err := rows.Count(&count)
128
        return count, err.Error
129
}
- -
func NewCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
47
func NewCore() *Core {
48
        CoreApp = new(Core)
49
        CoreApp.Core = new(types.Core)
50
        CoreApp.Started = time.Now()
51
        return CoreApp
52
}
- -
func Service.LimitedHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

-
47
func (s *Service) LimitedHits() ([]*types.Hit, error) {
48
        var hits []*types.Hit
49
        col := hitsDB().Where("service = ?", s.Id).Order("id desc").Limit(1024)
50
        err := col.Find(&hits)
51
        return reverseHits(hits), err.Error
52
}
-
func SelectUsername
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

43
func SelectUsername(username string) (*user, error) {
44
        var user user
45
        res := usersDB().Where("username = ?", username)
46
        err := res.First(&user)
47
        return &user, err.Error
48
}
-
func user.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

-
56
func (u *user) Update() error {
57
        u.Password = utils.HashPassword(u.Password)
58
        u.ApiKey = utils.NewSHA1Hash(5)
59
        u.ApiSecret = utils.NewSHA1Hash(10)
60
        return usersDB().Update(u).Error
61
}
+
func Service.TotalHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

+
63
func (s *Service) TotalHits() (uint64, error) {
64
        var count uint64
65
        col := hitsDB().Where("service = ?", s.Id)
66
        err := col.Count(&count)
67
        return count, err.Error
68
}
-
func reverseHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

-
55
func reverseHits(input []*types.Hit) []*types.Hit {
56
        if len(input) == 0 {
57
                return input
58
        }
59
        return append(reverseHits(input[1:]), input[0])
60
}
- -
func insertSampleCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

-
149
func insertSampleCore() error {
150
        core := &types.Core{
151
                Name:        "Statup Sample Data",
152
                Description: "This data is only used to testing",
153
                ApiKey:      "sample",
154
                ApiSecret:   "samplesecret",
155
                Domain:      "http://localhost:8080",
156
                Version:     "test",
157
                CreatedAt:   time.Now(),
158
                UseCdn:      false,
159
        }
160
        query := coreDB().Create(core)
161
        return query.Error
162
}
- -
func checkin.Last
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
78
func (c *checkin) Last() checkinHit {
79
        var hit checkinHit
80
        checkinHitsDB().Where("checkin = ?", c.Id).Last(&hit)
81
        return hit
82
}
- -
func SelectUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

-
36
func SelectUser(id int64) (*user, error) {
37
        var user user
38
        err := usersDB().First(&user, id)
39
        return &user, err.Error
40
}
+
func Checkin.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
163
func (c *Checkin) BeforeCreate() (err error) {
164
        if c.CreatedAt.IsZero() {
165
                c.CreatedAt = time.Now().UTC()
166
        }
167
        return
168
}
func Service.Check
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

222
func (s *Service) Check(record bool) {
223
        switch s.Type {
224
        case "http":
225
                s.checkHttp(record)
226
        case "tcp", "udp":
227
                s.checkTcp(record)
228
        }
229
}
+
func insertSampleCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

+
149
func insertSampleCore() error {
150
        core := &types.Core{
151
                Name:        "Statup Sample Data",
152
                Description: "This data is only used to testing",
153
                ApiKey:      "sample",
154
                ApiSecret:   "samplesecret",
155
                Domain:      "http://localhost:8080",
156
                Version:     "test",
157
                CreatedAt:   time.Now(),
158
                UseCdn:      false,
159
        }
160
        query := coreDB().Create(core)
161
        return query.Error
162
}
+ +
func SelectUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

+
36
func SelectUser(id int64) (*user, error) {
37
        var user user
38
        err := usersDB().First(&user, id)
39
        return &user, err.Error
40
}
+
func Service.Checkins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
55
func (s *Service) Checkins() []*checkin {
56
        var checkin []*checkin
57
        checkinDB().Where("service = ?", s.Id).Find(&checkin)
58
        return checkin
59
}
+64
func (s *Service) Checkins() []*Checkin {
65
        var checkin []*Checkin
66
        checkinDB().Where("service = ?", s.Id).Find(&checkin)
67
        return checkin
68
}
-
func checkin.Hits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
85
func (c *checkin) Hits() []checkinHit {
86
        var checkins []checkinHit
87
        checkinHitsDB().Where("checkin = ?", c.Id).Order("id DESC").Find(&checkins)
88
        return checkins
89
}
+
func reverseHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

+
55
func reverseHits(input []*types.Hit) []*types.Hit {
56
        if len(input) == 0 {
57
                return input
58
        }
59
        return append(reverseHits(input[1:]), input[0])
60
}
-
func checkin.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
163
func (c *checkin) BeforeCreate() (err error) {
164
        if c.CreatedAt.IsZero() {
165
                c.CreatedAt = time.Now().UTC()
166
        }
167
        return
168
}
+
func Checkin.Hits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
140
func (c *Checkin) Hits() []*checkinHit {
141
        var checkins []*checkinHit
142
        checkinHitsDB().Where("checkin = ?", c.Id).Order("id DESC").Find(&checkins)
143
        return checkins
144
}
-
func checkinHit.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
125
func (c *checkinHit) AfterFind() (err error) {
126
        c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
127
        return
128
}
+
func Checkin.Last
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
129
func (c *Checkin) Last() *checkinHit {
130
        var hit checkinHit
131
        checkinHitsDB().Where("checkin = ?", c.Id).Last(&hit)
132
        return &hit
133
}
+ +
func updateService
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
335
func updateService(service *Service) {
336
        index := service.index()
337
        CoreApp.Services[index] = service
338
}
func user.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

113
func (u *user) AfterFind() (err error) {
114
        u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone)
115
        return
116
}
-
func checkin.Grace
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
63
func (c *checkin) Grace() time.Duration {
64
        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.GracePeriod))
65
        return duration
66
}
+
func Checkin.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
119
func (c *Checkin) AfterFind() (err error) {
120
        c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
121
        return
122
}
-
func checkin.Period
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
57
func (c *checkin) Period() time.Duration {
58
        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.Interval))
59
        return duration
60
}
+
func Checkin.Period
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
108
func (c *Checkin) Period() time.Duration {
109
        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.Interval))
110
        return duration
111
}
+ +
func checkinHit.Ago
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
190
func (c *checkinHit) Ago() string {
191
        got, _ := timeago.TimeAgoWithTime(time.Now(), c.CreatedAt)
192
        return got
193
}
+ +
func checkinHit.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
125
func (c *checkinHit) AfterFind() (err error) {
126
        c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
127
        return
128
}
+ +
func Checkin.Grace
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
114
func (c *Checkin) Grace() time.Duration {
115
        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", c.GracePeriod))
116
        return duration
117
}
+ +
func Checkin.Service
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
75
func (c *Checkin) Service() *Service {
76
        service := SelectService(c.ServiceId)
77
        return service
78
}
func failure.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

107
func (f *failure) AfterFind() (err error) {
108
        f.CreatedAt = utils.Timezoner(f.CreatedAt, CoreApp.Timezone)
109
        return
110
}
-
func checkinHit.Ago
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
126
func (c *checkinHit) Ago() string {
127
        got, _ := timeago.TimeAgoWithTime(time.Now(), c.CreatedAt)
128
        return got
129
}
-
func CheckHash
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

105
func CheckHash(password, hash string) bool {
106
        err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
107
        return err == nil
108
}
func Service.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

95
func (s *Service) AfterFind() (err error) {
96
        s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone)
97
        return
98
}
-
func updateService
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
315
func updateService(service *Service) {
316
        index := service.index()
317
        CoreApp.Services[index] = service
318
}
+
func user.Delete
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

+
51
func (u *user) Delete() error {
52
        return usersDB().Delete(u).Error
53
}
-
func checkin.AfterFind
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
119
func (c *checkin) AfterFind() (err error) {
120
        c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone)
121
        return
122
}
+
func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
42
func init() {
43
        CoreApp = NewCore()
44
}
-
func hitsDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
47
func hitsDB() *gorm.DB {
48
        return DbSession.Model(&types.Hit{})
49
}
+
func ReturnService
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
40
func ReturnService(s *types.Service) *Service {
41
        return &Service{s}
42
}
+ +
func reorderServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
97
func reorderServices() {
98
        sort.Sort(ServiceOrder(CoreApp.Services))
99
}
+ +
func ServiceOrder.Len
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
160
func (c ServiceOrder) Len() int           { return len(c) }
+ +
func ServiceOrder.Swap
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
161
func (c ServiceOrder) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
func ServiceOrder.Less
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

162
func (c ServiceOrder) Less(i, j int) bool { return c[i].(*Service).Order < c[j].(*Service).Order }
@@ -483,17 +505,17 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func failuresDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

42
func failuresDB() *gorm.DB {
43
        return DbSession.Model(&types.Failure{})
44
}
-
func ServiceOrder.Swap
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
161
func (c ServiceOrder) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
+
func hitsDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
47
func hitsDB() *gorm.DB {
48
        return DbSession.Model(&types.Hit{})
49
}
-
func servicesDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
52
func servicesDB() *gorm.DB {
53
        return DbSession.Model(&types.Service{})
54
}
+
func ReturnUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

+
31
func ReturnUser(u *types.User) *user {
32
        return &user{u}
33
}
-
func coreDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
57
func coreDB() *gorm.DB {
58
        return DbSession.Table("core").Model(&CoreApp)
59
}
+
func ReturnCheckinHit
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
71
func ReturnCheckinHit(c *types.CheckinHit) *checkinHit {
72
        return &checkinHit{CheckinHit: c}
73
}
-
func ServiceOrder.Len
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
160
func (c ServiceOrder) Len() int           { return len(c) }
+
func usersDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
62
func usersDB() *gorm.DB {
63
        return DbSession.Model(&types.User{})
64
}
func checkinDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

67
func checkinDB() *gorm.DB {
68
        return DbSession.Model(&types.Checkin{})
69
}
@@ -501,81 +523,69 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func checkinHitsDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

72
func checkinHitsDB() *gorm.DB {
73
        return DbSession.Model(&types.CheckinHit{})
74
}
-
func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
42
func init() {
43
        CoreApp = NewCore()
44
}
-
func ReturnCheckin
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
40
func ReturnCheckin(c *types.Checkin) *checkin {
41
        return &checkin{Checkin: c}
42
}
- -
func usersDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
62
func usersDB() *gorm.DB {
63
        return DbSession.Model(&types.User{})
64
}
- -
func reorderServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
81
func reorderServices() {
82
        sort.Sort(ServiceOrder(CoreApp.Services))
83
}
+66
func ReturnCheckin(c *types.Checkin) *Checkin {
67
        return &Checkin{Checkin: c}
68
}
func Service.Select
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

35
func (s *Service) Select() *types.Service {
36
        return s.Service
37
}
-
func ReturnUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

-
31
func ReturnUser(u *types.User) *user {
32
        return &user{u}
33
}
+
func servicesDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
52
func servicesDB() *gorm.DB {
53
        return DbSession.Model(&types.Service{})
54
}
-
func user.Delete
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

-
51
func (u *user) Delete() error {
52
        return usersDB().Delete(u).Error
53
}
- -
func DbConfig.Close
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
90
func (db *DbConfig) Close() error {
91
        return DbSession.DB().Close()
92
}
- -
func ReturnCheckinHit
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
45
func ReturnCheckinHit(c *types.CheckinHit) *checkinHit {
46
        return &checkinHit{CheckinHit: c}
47
}
- -
func ReturnService
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
40
func ReturnService(s *types.Service) *Service {
41
        return &Service{s}
42
}
+
func coreDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
57
func coreDB() *gorm.DB {
58
        return DbSession.Table("core").Model(&CoreApp)
59
}
func Service.parseHost
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

77
func (s *Service) parseHost() string {
78
        if s.Type == "tcp" || s.Type == "udp" {
79
                return s.Domain
80
        } else {
81
                domain := s.Domain
82
                hasPort, _ := regexp.MatchString(`\:([0-9]+)`, domain)
83
                if hasPort {
84
                        splitDomain := strings.Split(s.Domain, ":")
85
                        domain = splitDomain[len(splitDomain)-2]
86
                }
87
                host, err := url.Parse(domain)
88
                if err != nil {
89
                        return s.Domain
90
                }
91
                return host.Host
92
        }
93
}
+
func Service.dnsCheck
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
96
func (s *Service) dnsCheck() (float64, error) {
97
        var err error
98
        t1 := time.Now()
99
        host := s.parseHost()
100
        if s.Type == "tcp" {
101
                _, err = net.LookupHost(host)
102
        } else {
103
                _, err = net.LookupIP(host)
104
        }
105
        if err != nil {
106
                return 0, err
107
        }
108
        t2 := time.Now()
109
        subTime := t2.Sub(t1).Seconds()
110
        return subTime, err
111
}
+
func Service.Sum
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

79
func (s *Service) Sum() (float64, error) {
80
        var amount float64
81
        hits, err := s.Hits()
82
        if err != nil {
83
                utils.Log(2, err)
84
        }
85
        for _, h := range hits {
86
                amount += h.Latency
87
        }
88
        return amount, err
89
}
-
func Core.SelectAllServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
62
func (c *Core) SelectAllServices() ([]*Service, error) {
63
        var services []*Service
64
        db := servicesDB().Find(&services).Order("order_id desc")
65
        if db.Error != nil {
66
                utils.Log(3, fmt.Sprintf("service error: %v", db.Error))
67
                return nil, db.Error
68
        }
69
        CoreApp.Services = nil
70
        for _, service := range services {
71
                service.Start()
72
                service.Checkins()
73
                service.AllFailures()
74
                CoreApp.Services = append(CoreApp.Services, service)
75
        }
76
        sort.Sort(ServiceOrder(CoreApp.Services))
77
        return services, db.Error
78
}
-
func Service.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
342
func (s *Service) Update(restart bool) error {
343
        err := servicesDB().Update(s)
344
        if err.Error != nil {
345
                utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", s.Name, err))
346
                return err.Error
347
        }
348
        if restart {
349
                s.Close()
350
                s.Start()
351
                s.SleepDuration = time.Duration(s.Interval) * time.Second
352
                go s.CheckQueue(true)
353
        }
354
        reorderServices()
355
        updateService(s)
356
        notifier.OnUpdatedService(s.Service)
357
        return err.Error
358
}
+362
func (s *Service) Update(restart bool) error {
363
        err := servicesDB().Update(s)
364
        if err.Error != nil {
365
                utils.Log(3, fmt.Sprintf("Failed to update service %v. %v", s.Name, err))
366
                return err.Error
367
        }
368
        if restart {
369
                s.Close()
370
                s.Start()
371
                s.SleepDuration = time.Duration(s.Interval) * time.Second
372
                go s.CheckQueue(true)
373
        }
374
        reorderServices()
375
        updateService(s)
376
        notifier.OnUpdatedService(s.Service)
377
        return err.Error
378
}
+ +
func Core.SelectAllServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
78
func (c *Core) SelectAllServices() ([]*Service, error) {
79
        var services []*Service
80
        db := servicesDB().Find(&services).Order("order_id desc")
81
        if db.Error != nil {
82
                utils.Log(3, fmt.Sprintf("service error: %v", db.Error))
83
                return nil, db.Error
84
        }
85
        CoreApp.Services = nil
86
        for _, service := range services {
87
                service.Start()
88
                service.CheckinProcess()
89
                service.AllFailures()
90
                CoreApp.Services = append(CoreApp.Services, service)
91
        }
92
        sort.Sort(ServiceOrder(CoreApp.Services))
93
        return services, db.Error
94
}
func Service.Delete
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
321
func (s *Service) Delete() error {
322
        i := s.index()
323
        err := servicesDB().Delete(s)
324
        if err.Error != nil {
325
                utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", s.Name, err.Error))
326
                return err.Error
327
        }
328
        s.Close()
329
        slice := CoreApp.Services
330
        CoreApp.Services = append(slice[:i], slice[i+1:]...)
331
        reorderServices()
332
        notifier.OnDeletedService(s.Service)
333
        return err.Error
334
}
+341
func (s *Service) Delete() error {
342
        i := s.index()
343
        err := servicesDB().Delete(s)
344
        if err.Error != nil {
345
                utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", s.Name, err.Error))
346
                return err.Error
347
        }
348
        s.Close()
349
        slice := CoreApp.Services
350
        CoreApp.Services = append(slice[:i], slice[i+1:]...)
351
        reorderServices()
352
        notifier.OnDeletedService(s.Service)
353
        return err.Error
354
}
func Service.Create
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
361
func (s *Service) Create(check bool) (int64, error) {
362
        s.CreatedAt = time.Now()
363
        db := servicesDB().Create(s)
364
        if db.Error != nil {
365
                utils.Log(3, fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))
366
                return 0, db.Error
367
        }
368
        s.Start()
369
        go s.CheckQueue(check)
370
        CoreApp.Services = append(CoreApp.Services, s)
371
        reorderServices()
372
        notifier.OnNewService(s.Service)
373
        return s.Id, nil
374
}
+381
func (s *Service) Create(check bool) (int64, error) {
382
        s.CreatedAt = time.Now()
383
        db := servicesDB().Create(s)
384
        if db.Error != nil {
385
                utils.Log(3, fmt.Sprintf("Failed to create service %v #%v: %v", s.Name, s.Id, db.Error))
386
                return 0, db.Error
387
        }
388
        s.Start()
389
        go s.CheckQueue(check)
390
        CoreApp.Services = append(CoreApp.Services, s)
391
        reorderServices()
392
        notifier.OnNewService(s.Service)
393
        return s.Id, nil
394
}
func Service.OnlineSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
111
func (s *Service) OnlineSince(ago time.Time) float32 {
112
        failed, _ := s.TotalFailuresSince(ago)
113
        if failed == 0 {
114
                s.Online24Hours = 100.00
115
                return s.Online24Hours
116
        }
117
        total, _ := s.TotalHitsSince(ago)
118
        if total == 0 {
119
                s.Online24Hours = 0
120
                return s.Online24Hours
121
        }
122
        avg := float64(failed) / float64(total) * 100
123
        avg = 100 - avg
124
        if avg < 0 {
125
                avg = 0
126
        }
127
        amount, _ := strconv.ParseFloat(fmt.Sprintf("%0.2f", avg), 10)
128
        s.Online24Hours = float32(amount)
129
        return s.Online24Hours
130
}
+127
func (s *Service) OnlineSince(ago time.Time) float32 {
128
        failed, _ := s.TotalFailuresSince(ago)
129
        if failed == 0 {
130
                s.Online24Hours = 100.00
131
                return s.Online24Hours
132
        }
133
        total, _ := s.TotalHitsSince(ago)
134
        if total == 0 {
135
                s.Online24Hours = 0
136
                return s.Online24Hours
137
        }
138
        avg := float64(failed) / float64(total) * 100
139
        avg = 100 - avg
140
        if avg < 0 {
141
                avg = 0
142
        }
143
        amount, _ := strconv.ParseFloat(fmt.Sprintf("%0.2f", avg), 10)
144
        s.Online24Hours = float32(amount)
145
        return s.Online24Hours
146
}
-
func Service.duration
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
67
func (s *Service) duration() time.Duration {
68
        var amount time.Duration
69
        if s.Interval >= 10000 {
70
                amount = time.Duration(s.Interval) * time.Microsecond
71
        } else {
72
                amount = time.Duration(s.Interval) * time.Second
73
        }
74
        return amount
75
}
+
func Checkin.Routine
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
35
func (c *Checkin) Routine() {
36
        if c.Last() == nil {
37
                return
38
        }
39
        reCheck := c.Period()
40
CheckinLoop:
41
        for {
42
                select {
43
                case <-c.Running:
44
                        utils.Log(1, fmt.Sprintf("Stopping checkin routine: %v", c.Name))
45
                        break CheckinLoop
46
                case <-time.After(reCheck):
47
                        utils.Log(1, fmt.Sprintf("Checkin %v is expected at %v, checking every %v", c.Name, utils.FormatDuration(c.Expected()), utils.FormatDuration(c.Period())))
48
                        if c.Expected().Seconds() <= 0 {
49
                                issue := fmt.Sprintf("Checkin %v is failing, no request since %v", c.Name, c.Last().CreatedAt)
50
                                utils.Log(3, issue)
51
                                c.Service()
52
                                c.CreateFailure()
53
                        }
54
                        reCheck = c.Period()
55
                }
56
                continue
57
        }
58
}
func SelectAllUsers
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

81
func SelectAllUsers() ([]*user, error) {
82
        var users []*user
83
        db := usersDB().Find(&users)
84
        if db.Error != nil {
85
                utils.Log(3, fmt.Sprintf("Failed to load all users. %v", db.Error))
86
        }
87
        return users, db.Error
88
}
+
func Service.duration
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
67
func (s *Service) duration() time.Duration {
68
        var amount time.Duration
69
        if s.Interval >= 10000 {
70
                amount = time.Duration(s.Interval) * time.Microsecond
71
        } else {
72
                amount = time.Duration(s.Interval) * time.Second
73
        }
74
        return amount
75
}
+
func Service.AvgUptime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
267
func (s *Service) AvgUptime(ago time.Time) string {
268
        failed, _ := s.TotalFailuresSince(ago)
269
        if failed == 0 {
270
                return "100"
271
        }
272
        total, _ := s.TotalHitsSince(ago)
273
        if total == 0 {
274
                return "0.00"
275
        }
276
        percent := float64(failed) / float64(total) * 100
277
        percent = 100 - percent
278
        if percent < 0 {
279
                percent = 0
280
        }
281
        amount := fmt.Sprintf("%0.2f", percent)
282
        if amount == "100.00" {
283
                amount = "100"
284
        }
285
        return amount
286
}
+287
func (s *Service) AvgUptime(ago time.Time) string {
288
        failed, _ := s.TotalFailuresSince(ago)
289
        if failed == 0 {
290
                return "100"
291
        }
292
        total, _ := s.TotalHitsSince(ago)
293
        if total == 0 {
294
                return "0.00"
295
        }
296
        percent := float64(failed) / float64(total) * 100
297
        percent = 100 - percent
298
        if percent < 0 {
299
                percent = 0
300
        }
301
        amount := fmt.Sprintf("%0.2f", percent)
302
        if amount == "100.00" {
303
                amount = "100"
304
        }
305
        return amount
306
}
func Service.AllFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

-
44
func (s *Service) AllFailures() []*failure {
45
        var fails []*failure
46
        col := failuresDB().Where("service = ?", s.Id).Order("id desc")
47
        err := col.Find(&fails)
48
        if err.Error != nil {
49
                utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err))
50
                return nil
51
        }
52
        for _, f := range fails {
53
                s.Failures = append(s.Failures, f)
54
        }
55
        return fails
56
}
+44
func (s *Service) AllFailures() []*failure {
45
        var fails []*failure
46
        col := failuresDB().Where("service = ?", s.Id).Not("method = 'checkin'").Order("id desc")
47
        err := col.Find(&fails)
48
        if err.Error != nil {
49
                utils.Log(3, fmt.Sprintf("Issue getting failures for service %v, %v", s.Name, err))
50
                return nil
51
        }
52
        for _, f := range fails {
53
                s.Failures = append(s.Failures, f)
54
        }
55
        return fails
56
}
func Service.Downtime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
202
func (s *Service) Downtime() time.Duration {
203
        hits, _ := s.Hits()
204
        fails := s.LimitedFailures()
205
        if len(fails) == 0 {
206
                return time.Duration(0)
207
        }
208
        if len(hits) == 0 {
209
                return time.Now().UTC().Sub(fails[len(fails)-1].CreatedAt.UTC())
210
        }
211
        since := fails[0].CreatedAt.UTC().Sub(hits[0].CreatedAt.UTC())
212
        return since
213
}
+222
func (s *Service) Downtime() time.Duration {
223
        hits, _ := s.Hits()
224
        fails := s.LimitedFailures()
225
        if len(fails) == 0 {
226
                return time.Duration(0)
227
        }
228
        if len(hits) == 0 {
229
                return time.Now().UTC().Sub(fails[len(fails)-1].CreatedAt.UTC())
230
        }
231
        since := fails[0].CreatedAt.UTC().Sub(hits[0].CreatedAt.UTC())
232
        return since
233
}
+ +
func Checkin.Create
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
154
func (c *Checkin) Create() (int64, error) {
155
        c.ApiKey = utils.RandomString(7)
156
        row := checkinDB().Create(&c)
157
        c.Start()
158
        go c.Routine()
159
        if row.Error != nil {
160
                utils.Log(2, row.Error)
161
                return 0, row.Error
162
        }
163
        return c.Id, row.Error
164
}
+ +
func Service.index
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
325
func (s *Service) index() int {
326
        for k, service := range CoreApp.Services {
327
                if s.Id == service.(*Service).Id {
328
                        return k
329
                }
330
        }
331
        return 0
332
}
func SelectService
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

45
func SelectService(id int64) *Service {
46
        for _, s := range CoreApp.Services {
47
                if s.Select().Id == id {
48
                        return s.(*Service)
49
                }
50
        }
51
        return nil
52
}
-
func Service.index
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
305
func (s *Service) index() int {
306
        for k, service := range CoreApp.Services {
307
                if s.Id == service.(*Service).Id {
308
                        return k
309
                }
310
        }
311
        return 0
312
}
- -
func Service.checkHttp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
151
func (s *Service) checkHttp(record bool) *Service {
152
        dnsLookup, err := s.dnsCheck()
153
        if err != nil {
154
                if record {
155
                        recordFailure(s, fmt.Sprintf("Could not get IP address for domain %v, %v", s.Domain, err))
156
                }
157
                return s
158
        }
159
        s.PingTime = dnsLookup
160
        t1 := time.Now()
161
        timeout := time.Duration(s.Timeout)
162
        client := http.Client{
163
                Timeout: timeout * time.Second,
164
        }
165
166
        var response *http.Response
167
        if s.Method == "POST" {
168
                response, err = client.Post(s.Domain, "application/json", bytes.NewBuffer([]byte(s.PostData)))
169
        } else {
170
                response, err = client.Get(s.Domain)
171
        }
172
        if err != nil {
173
                if record {
174
                        recordFailure(s, fmt.Sprintf("HTTP Error %v", err))
175
                }
176
                return s
177
        }
178
        response.Header.Set("Connection", "close")
179
        response.Header.Set("user-Agent", "StatupMonitor")
180
        t2 := time.Now()
181
        s.Latency = t2.Sub(t1).Seconds()
182
        if err != nil {
183
                if record {
184
                        recordFailure(s, fmt.Sprintf("HTTP Error %v", err))
185
                }
186
                return s
187
        }
188
        defer response.Body.Close()
189
        contents, err := ioutil.ReadAll(response.Body)
190
        s.LastResponse = string(contents)
191
        s.LastStatusCode = response.StatusCode
192
193
        if s.Expected != "" {
194
                if err != nil {
195
                        utils.Log(2, err)
196
                }
197
                match, err := regexp.MatchString(s.Expected, string(contents))
198
                if err != nil {
199
                        utils.Log(2, err)
200
                }
201
                if !match {
202
                        if record {
203
                                recordFailure(s, fmt.Sprintf("HTTP Response Body did not match '%v'", s.Expected))
204
                        }
205
                        return s
206
                }
207
        }
208
        if s.ExpectedStatus != response.StatusCode {
209
                if record {
210
                        recordFailure(s, fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
211
                }
212
                return s
213
        }
214
        s.Online = true
215
        if record {
216
                recordSuccess(s)
217
        }
218
        return s
219
}
-
func user.Create
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

64
func (u *user) Create() (int64, error) {
65
        u.CreatedAt = time.Now()
66
        u.Password = utils.HashPassword(u.Password)
67
        u.ApiKey = utils.NewSHA1Hash(5)
68
        u.ApiSecret = utils.NewSHA1Hash(10)
69
        db := usersDB().Create(u)
70
        if db.Error != nil {
71
                return 0, db.Error
72
        }
73
        if u.Id == 0 {
74
                utils.Log(3, fmt.Sprintf("Failed to create user %v. %v", u.Username, db.Error))
75
                return 0, db.Error
76
        }
77
        return u.Id, db.Error
78
}
@@ -585,14 +595,17 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func DbConfig.Save
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

286
func (db *DbConfig) Save() (*DbConfig, error) {
287
        var err error
288
        config, err := os.Create(utils.Directory + "/config.yml")
289
        if err != nil {
290
                utils.Log(4, err)
291
                return nil, err
292
        }
293
        db.ApiKey = utils.NewSHA1Hash(16)
294
        db.ApiSecret = utils.NewSHA1Hash(16)
295
        data, err := yaml.Marshal(db)
296
        if err != nil {
297
                utils.Log(3, err)
298
                return nil, err
299
        }
300
        config.WriteString(string(data))
301
        defer config.Close()
302
        return db, err
303
}
-
func AuthUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

-
92
func AuthUser(username, password string) (*user, bool) {
93
        user, err := SelectUsername(username)
94
        if err != nil {
95
                utils.Log(2, err)
96
                return nil, false
97
        }
98
        if CheckHash(password, user.Password) {
99
                return user, true
100
        }
101
        return nil, false
102
}
-
func Service.CreateFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

32
func (s *Service) CreateFailure(f *types.Failure) (int64, error) {
33
        f.Service = s.Id
34
        s.Failures = append(s.Failures, f)
35
        row := failuresDB().Create(f)
36
        if row.Error != nil {
37
                utils.Log(3, row.Error)
38
                return 0, row.Error
39
        }
40
        return f.Id, row.Error
41
}
+
func AuthUser
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/users.go:

+
92
func AuthUser(username, password string) (*user, bool) {
93
        user, err := SelectUsername(username)
94
        if err != nil {
95
                utils.Log(2, err)
96
                return nil, false
97
        }
98
        if CheckHash(password, user.Password) {
99
                return user, true
100
        }
101
        return nil, false
102
}
+
func SelectCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
136
func SelectCore() (*Core, error) {
137
        if DbSession == nil {
138
                return nil, errors.New("database has not been initiated yet.")
139
        }
140
        exists := DbSession.HasTable("core")
141
        if !exists {
142
                return nil, errors.New("core database has not been setup yet.")
143
        }
144
        db := coreDB().First(&CoreApp)
145
        if db.Error != nil {
146
                return nil, db.Error
147
        }
148
        CoreApp.DbConnection = Configs.DbConn
149
        CoreApp.Version = VERSION
150
        if os.Getenv("USE_CDN") == "true" {
151
                CoreApp.UseCdn = true
152
        }
153
        //store = sessions.NewCookieStore([]byte(core.ApiSecret))
154
        return CoreApp, db.Error
155
}
+136
func SelectCore() (*Core, error) {
137
        if DbSession == nil {
138
                return nil, errors.New("database has not been initiated yet.")
139
        }
140
        exists := DbSession.HasTable("core")
141
        if !exists {
142
                return nil, errors.New("core database has not been setup yet.")
143
        }
144
        db := coreDB().First(&CoreApp)
145
        if db.Error != nil {
146
                return nil, db.Error
147
        }
148
        CoreApp.DbConnection = Configs.DbConn
149
        CoreApp.Version = VERSION
150
        if os.Getenv("USE_CDN") == "true" {
151
                CoreApp.UseCdn = true
152
        }
153
        return CoreApp, db.Error
154
}
+ +
func Service.checkHttp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
151
func (s *Service) checkHttp(record bool) *Service {
152
        dnsLookup, err := s.dnsCheck()
153
        if err != nil {
154
                if record {
155
                        recordFailure(s, fmt.Sprintf("Could not get IP address for domain %v, %v", s.Domain, err))
156
                }
157
                return s
158
        }
159
        s.PingTime = dnsLookup
160
        t1 := time.Now()
161
        timeout := time.Duration(s.Timeout)
162
        client := http.Client{
163
                Timeout: timeout * time.Second,
164
        }
165
166
        var response *http.Response
167
        if s.Method == "POST" {
168
                response, err = client.Post(s.Domain, "application/json", bytes.NewBuffer([]byte(s.PostData)))
169
        } else {
170
                response, err = client.Get(s.Domain)
171
        }
172
        if err != nil {
173
                if record {
174
                        recordFailure(s, fmt.Sprintf("HTTP Error %v", err))
175
                }
176
                return s
177
        }
178
        response.Header.Set("Connection", "close")
179
        response.Header.Set("user-Agent", "StatupMonitor")
180
        t2 := time.Now()
181
        s.Latency = t2.Sub(t1).Seconds()
182
        if err != nil {
183
                if record {
184
                        recordFailure(s, fmt.Sprintf("HTTP Error %v", err))
185
                }
186
                return s
187
        }
188
        defer response.Body.Close()
189
        contents, err := ioutil.ReadAll(response.Body)
190
        s.LastResponse = string(contents)
191
        s.LastStatusCode = response.StatusCode
192
193
        if s.Expected != "" {
194
                if err != nil {
195
                        utils.Log(2, err)
196
                }
197
                match, err := regexp.MatchString(s.Expected, string(contents))
198
                if err != nil {
199
                        utils.Log(2, err)
200
                }
201
                if !match {
202
                        if record {
203
                                recordFailure(s, fmt.Sprintf("HTTP Response Body did not match '%v'", s.Expected))
204
                        }
205
                        return s
206
                }
207
        }
208
        if s.ExpectedStatus != response.StatusCode {
209
                if record {
210
                        recordFailure(s, fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
211
                }
212
                return s
213
        }
214
        s.Online = true
215
        if record {
216
                recordSuccess(s)
217
        }
218
        return s
219
}
func LoadConfig
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/configs.go:

34
func LoadConfig(directory string) (*DbConfig, error) {
35
        var configs *DbConfig
36
        if os.Getenv("DB_CONN") != "" {
37
                utils.Log(1, "DB_CONN environment variable was found, waiting for database...")
38
                return LoadUsingEnv()
39
        }
40
        file, err := ioutil.ReadFile(directory + "/config.yml")
41
        if err != nil {
42
                return nil, errors.New("config.yml file not found at " + directory + "/config.yml - starting in setup mode")
43
        }
44
        err = yaml.Unmarshal(file, &configs)
45
        if err != nil {
46
                return nil, err
47
        }
48
        Configs = configs
49
        return Configs, err
50
}
@@ -600,8 +613,8 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func DbConfig.MigrateDatabase
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

359
func (db *DbConfig) MigrateDatabase() error {
360
        utils.Log(1, "Migrating Database Tables...")
361
362
        tx := DbSession.Begin()
363
        defer func() {
364
                if r := recover(); r != nil {
365
                        tx.Rollback()
366
                }
367
        }()
368
        if tx.Error != nil {
369
                return tx.Error
370
        }
371
        tx = tx.AutoMigrate(&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Checkin{}, &types.CheckinHit{}, &notifier.Notification{}).Table("core").AutoMigrate(&types.Core{})
372
        if tx.Error != nil {
373
                tx.Rollback()
374
                utils.Log(3, fmt.Sprintf("Statup Database could not be migrated: %v", tx.Error))
375
                return tx.Error
376
        }
377
        utils.Log(1, "Statup Database Migrated")
378
        return tx.Commit().Error
379
}
-
func checkin.Create
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
92
func (c *checkin) Create() (int64, error) {
93
        c.ApiKey = utils.RandomString(7)
94
        row := checkinDB().Create(&c)
95
        if row.Error != nil {
96
                utils.Log(2, row.Error)
97
                return 0, row.Error
98
        }
99
        return c.Id, row.Error
100
}
+
func Service.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
155
func (s *Service) BeforeCreate() (err error) {
156
        if s.CreatedAt.IsZero() {
157
                s.CreatedAt = time.Now().UTC()
158
        }
159
        return
160
}
func user.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

147
func (u *user) BeforeCreate() (err error) {
148
        if u.CreatedAt.IsZero() {
149
                u.CreatedAt = time.Now().UTC()
150
        }
151
        return
152
}
@@ -609,20 +622,17 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func checkinHit.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

171
func (c *checkinHit) BeforeCreate() (err error) {
172
        if c.CreatedAt.IsZero() {
173
                c.CreatedAt = time.Now().UTC()
174
        }
175
        return
176
}
-
func Service.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
155
func (s *Service) BeforeCreate() (err error) {
156
        if s.CreatedAt.IsZero() {
157
                s.CreatedAt = time.Now().UTC()
158
        }
159
        return
160
}
-
func Service.CreateHit
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/hits.go:

-
29
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
30
        db := hitsDB().Create(h)
31
        if db.Error != nil {
32
                utils.Log(2, db.Error)
33
                return 0, db.Error
34
        }
35
        return h.Id, db.Error
36
}
+29
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
30
        db := hitsDB().Create(&h)
31
        if db.Error != nil {
32
                utils.Log(2, db.Error)
33
                return 0, db.Error
34
        }
35
        return h.Id, db.Error
36
}
-
func checkin.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
103
func (c *checkin) Update() (int64, error) {
104
        row := checkinDB().Update(c)
105
        if row.Error != nil {
106
                utils.Log(2, row.Error)
107
                return 0, row.Error
108
        }
109
        return c.Id, row.Error
110
}
+
func Checkin.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
167
func (c *Checkin) Update() (int64, error) {
168
        row := checkinDB().Update(c)
169
        if row.Error != nil {
170
                utils.Log(2, row.Error)
171
                return 0, row.Error
172
        }
173
        return c.Id, row.Error
174
}
func checkinHit.Create
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
113
func (c *checkinHit) Create() (int64, error) {
114
        if c.CreatedAt.IsZero() {
115
                c.CreatedAt = time.Now()
116
        }
117
        row := checkinHitsDB().Create(c)
118
        if row.Error != nil {
119
                utils.Log(2, row.Error)
120
                return 0, row.Error
121
        }
122
        return c.Id, row.Error
123
}
+177
func (c *checkinHit) Create() (int64, error) {
178
        if c.CreatedAt.IsZero() {
179
                c.CreatedAt = time.Now()
180
        }
181
        row := checkinHitsDB().Create(c)
182
        if row.Error != nil {
183
                utils.Log(2, row.Error)
184
                return 0, row.Error
185
        }
186
        return c.Id, row.Error
187
}
func Service.SmallText
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
154
func (s *Service) SmallText() string {
155
        last := s.LimitedFailures()
156
        hits, _ := s.LimitedHits()
157
        zone := CoreApp.Timezone
158
        if s.Online {
159
                if len(last) == 0 {
160
                        return fmt.Sprintf("Online since %v", utils.Timezoner(s.CreatedAt, zone).Format("Monday 3:04:05PM, Jan _2 2006"))
161
                } else {
162
                        return fmt.Sprintf("Online, last failure was %v", utils.Timezoner(hits[0].CreatedAt, zone).Format("Monday 3:04:05PM, Jan _2 2006"))
163
                }
164
        }
165
        if len(last) > 0 {
166
                lastFailure := s.lastFailure()
167
                got, _ := timeago.TimeAgoWithTime(time.Now().Add(s.Downtime()), time.Now())
168
                return fmt.Sprintf("Reported offline %v, %v", got, lastFailure.ParseError())
169
        } else {
170
                return fmt.Sprintf("%v is currently offline", s.Name)
171
        }
172
}
+172
func (s *Service) SmallText() string {
173
        last := s.LimitedFailures()
174
        hits, _ := s.LimitedHits()
175
        zone := CoreApp.Timezone
176
        if s.Online {
177
                if len(last) == 0 {
178
                        return fmt.Sprintf("Online since %v", utils.Timezoner(s.CreatedAt, zone).Format("Monday 3:04:05PM, Jan _2 2006"))
179
                } else {
180
                        return fmt.Sprintf("Online, last failure was %v", utils.Timezoner(hits[0].CreatedAt, zone).Format("Monday 3:04:05PM, Jan _2 2006"))
181
                }
182
        }
183
        if len(last) > 0 {
184
                lastFailure := s.lastFailure()
185
                got, _ := timeago.TimeAgoWithTime(time.Now().Add(s.Downtime()), time.Now())
186
                return fmt.Sprintf("Reported offline %v, %v", got, lastFailure.ParseError())
187
        } else {
188
                return fmt.Sprintf("%v is currently offline", s.Name)
189
        }
190
}
func insertNotifierDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

70
func insertNotifierDB() error {
71
        if DbSession == nil {
72
                err := Configs.Connect(false, utils.Directory)
73
                if err != nil {
74
                        return errors.New("database connection has not been created")
75
                }
76
        }
77
        notifier.SetDB(DbSession)
78
        return nil
79
}
@@ -637,112 +647,130 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37 53
func LoadUsingEnv() (*DbConfig, error) {
54
        Configs = new(DbConfig)
55
        if os.Getenv("DB_CONN") == "" {
56
                return nil, errors.New("Missing DB_CONN environment variable")
57
        }
58
        if os.Getenv("DB_HOST") == "" {
59
                return nil, errors.New("Missing DB_HOST environment variable")
60
        }
61
        if os.Getenv("DB_USER") == "" {
62
                return nil, errors.New("Missing DB_USER environment variable")
63
        }
64
        if os.Getenv("DB_PASS") == "" {
65
                return nil, errors.New("Missing DB_PASS environment variable")
66
        }
67
        if os.Getenv("DB_DATABASE") == "" {
68
                return nil, errors.New("Missing DB_DATABASE environment variable")
69
        }
70
        Configs.DbConn = os.Getenv("DB_CONN")
71
        Configs.DbHost = os.Getenv("DB_HOST")
72
        Configs.DbPort = int(utils.StringInt(os.Getenv("DB_PORT")))
73
        Configs.DbUser = os.Getenv("DB_USER")
74
        Configs.DbPass = os.Getenv("DB_PASS")
75
        Configs.DbData = os.Getenv("DB_DATABASE")
76
        CoreApp.DbConnection = os.Getenv("DB_CONN")
77
        CoreApp.Name = os.Getenv("NAME")
78
        CoreApp.Domain = os.Getenv("DOMAIN")
79
        if os.Getenv("USE_CDN") == "true" {
80
                CoreApp.UseCdn = true
81
        }
82
83
        dbConfig := &DbConfig{
84
                DbConn:      os.Getenv("DB_CONN"),
85
                DbHost:      os.Getenv("DB_HOST"),
86
                DbUser:      os.Getenv("DB_USER"),
87
                DbPass:      os.Getenv("DB_PASS"),
88
                DbData:      os.Getenv("DB_DATABASE"),
89
                DbPort:      5432,
90
                Project:     "Statup - " + os.Getenv("NAME"),
91
                Description: "New Statup Installation",
92
                Domain:      os.Getenv("DOMAIN"),
93
                Username:    "admin",
94
                Password:    "admin",
95
                Email:       "info@localhost.com",
96
        }
97
98
        err := dbConfig.Connect(true, utils.Directory)
99
        if err != nil {
100
                utils.Log(4, err)
101
                return nil, err
102
        }
103
104
        exists := DbSession.HasTable("core")
105
        if !exists {
106
                utils.Log(1, fmt.Sprintf("Core database does not exist, creating now!"))
107
                dbConfig.DropDatabase()
108
                dbConfig.CreateDatabase()
109
110
                CoreApp, err = dbConfig.InsertCore()
111
                if err != nil {
112
                        utils.Log(3, err)
113
                }
114
115
                admin := &types.User{
116
                        Username: "admin",
117
                        Password: "admin",
118
                        Email:    "info@admin.com",
119
                        Admin:    true,
120
                }
121
                admin.Create()
122
123
                InsertSampleData()
124
125
                return Configs, err
126
127
        }
128
129
        return Configs, nil
130
}
func failure.ParseError
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

-
132
func (f *failure) ParseError() string {
133
        err := strings.Contains(f.Issue, "connection reset by peer")
134
        if err {
135
                return fmt.Sprintf("Connection Reset")
136
        }
137
        err = strings.Contains(f.Issue, "operation timed out")
138
        if err {
139
                return fmt.Sprintf("HTTP Request Timed Out")
140
        }
141
        err = strings.Contains(f.Issue, "x509: certificate is valid")
142
        if err {
143
                return fmt.Sprintf("SSL Certificate invalid")
144
        }
145
        err = strings.Contains(f.Issue, "Client.Timeout exceeded while awaiting headers")
146
        if err {
147
                return fmt.Sprintf("Connection Timed Out")
148
        }
149
        err = strings.Contains(f.Issue, "no such host")
150
        if err {
151
                return fmt.Sprintf("Domain is offline or not found")
152
        }
153
        err = strings.Contains(f.Issue, "HTTP Status Code")
154
        if err {
155
                return fmt.Sprintf("Incorrect HTTP Status Code")
156
        }
157
        err = strings.Contains(f.Issue, "connection refused")
158
        if err {
159
                return fmt.Sprintf("Connection Failed")
160
        }
161
        err = strings.Contains(f.Issue, "can't assign requested address")
162
        if err {
163
                return fmt.Sprintf("Unable to Request Address")
164
        }
165
        err = strings.Contains(f.Issue, "no route to host")
166
        if err {
167
                return fmt.Sprintf("Domain is offline or not found")
168
        }
169
        return f.Issue
170
}
+132
func (f *failure) ParseError() string {
133
        if f.Method == "checkin" {
134
                return fmt.Sprintf("Checkin is Offline")
135
        }
136
        err := strings.Contains(f.Issue, "connection reset by peer")
137
        if err {
138
                return fmt.Sprintf("Connection Reset")
139
        }
140
        err = strings.Contains(f.Issue, "operation timed out")
141
        if err {
142
                return fmt.Sprintf("HTTP Request Timed Out")
143
        }
144
        err = strings.Contains(f.Issue, "x509: certificate is valid")
145
        if err {
146
                return fmt.Sprintf("SSL Certificate invalid")
147
        }
148
        err = strings.Contains(f.Issue, "Client.Timeout exceeded while awaiting headers")
149
        if err {
150
                return fmt.Sprintf("Connection Timed Out")
151
        }
152
        err = strings.Contains(f.Issue, "no such host")
153
        if err {
154
                return fmt.Sprintf("Domain is offline or not found")
155
        }
156
        err = strings.Contains(f.Issue, "HTTP Status Code")
157
        if err {
158
                return fmt.Sprintf("Incorrect HTTP Status Code")
159
        }
160
        err = strings.Contains(f.Issue, "connection refused")
161
        if err {
162
                return fmt.Sprintf("Connection Failed")
163
        }
164
        err = strings.Contains(f.Issue, "can't assign requested address")
165
        if err {
166
                return fmt.Sprintf("Unable to Request Address")
167
        }
168
        err = strings.Contains(f.Issue, "no route to host")
169
        if err {
170
                return fmt.Sprintf("Domain is offline or not found")
171
        }
172
        return f.Issue
173
}
func ExportIndexHTML
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

31
func ExportIndexHTML() string {
32
        source.Assets()
33
        injectDatabase()
34
        CoreApp.SelectAllServices()
35
        CoreApp.UseCdn = true
36
        for _, srv := range CoreApp.Services {
37
                service := srv.(*Service)
38
                service.Check(true)
39
                fmt.Println(service.Name, service.Online, service.Latency)
40
        }
41
        nav, _ := source.TmplBox.String("nav.html")
42
        footer, _ := source.TmplBox.String("footer.html")
43
        render, err := source.TmplBox.String("index.html")
44
        if err != nil {
45
                utils.Log(3, err)
46
        }
47
48
        t := template.New("message")
49
        t.Funcs(template.FuncMap{
50
                "js": func(html string) template.JS {
51
                        return template.JS(html)
52
                },
53
                "safe": func(html string) template.HTML {
54
                        return template.HTML(html)
55
                },
56
                "VERSION": func() string {
57
                        return VERSION
58
                },
59
                "CoreApp": func() *Core {
60
                        return CoreApp
61
                },
62
                "USE_CDN": func() bool {
63
                        return CoreApp.UseCdn
64
                },
65
                "underscore": func(html string) string {
66
                        return utils.UnderScoreString(html)
67
                },
68
                "URL": func() string {
69
                        return "/"
70
                },
71
                "CHART_DATA": func() string {
72
                        return ExportChartsJs()
73
                },
74
        })
75
        t, _ = t.Parse(nav)
76
        t, _ = t.Parse(footer)
77
        t.Parse(render)
78
        var tpl bytes.Buffer
79
        if err := t.Execute(&tpl, CoreApp); err != nil {
80
                utils.Log(3, err)
81
        }
82
        result := tpl.String()
83
        return result
84
}
func GraphDataRaw
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
216
func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group string, column string) *DateScanObj {
217
        var d []DateScan
218
        model := service.(*Service).HitsBetween(start, end, group, column)
219
        rows, _ := model.Rows()
220
        for rows.Next() {
221
                var gd DateScan
222
                var createdAt string
223
                var value float64
224
                var createdTime time.Time
225
                rows.Scan(&createdAt, &value)
226
                createdTime, _ = time.Parse(types.TIME, createdAt)
227
                if CoreApp.DbConnection == "postgres" {
228
                        createdTime, _ = time.Parse(types.TIME_NANO, createdAt)
229
                }
230
                gd.CreatedAt = utils.Timezoner(createdTime, CoreApp.Timezone).Format(types.TIME)
231
                gd.Value = int64(value * 1000)
232
                d = append(d, gd)
233
        }
234
        return &DateScanObj{d}
235
}
+236
func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group string, column string) *DateScanObj {
237
        var d []DateScan
238
        model := service.(*Service).HitsBetween(start, end, group, column)
239
        rows, _ := model.Rows()
240
        for rows.Next() {
241
                var gd DateScan
242
                var createdAt string
243
                var value float64
244
                var createdTime time.Time
245
                rows.Scan(&createdAt, &value)
246
                createdTime, _ = time.Parse(types.TIME, createdAt)
247
                if CoreApp.DbConnection == "postgres" {
248
                        createdTime, _ = time.Parse(types.TIME_NANO, createdAt)
249
                }
250
                gd.CreatedAt = utils.Timezoner(createdTime, CoreApp.Timezone).Format(types.TIME)
251
                gd.Value = int64(value * 1000)
252
                d = append(d, gd)
253
        }
254
        return &DateScanObj{d}
255
}
func InsertSampleHits
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/sample.go:

124
func InsertSampleHits() error {
125
        since := time.Now().Add((-24 * 7) * time.Hour).UTC()
126
        for i := int64(1); i <= 5; i++ {
127
                service := SelectService(i)
128
                utils.Log(1, fmt.Sprintf("Adding %v sample hit records to service %v", 360, service.Name))
129
                createdAt := since
130
                alpha := float64(1.05)
131
132
                for hi := int64(1); hi <= 168; hi++ {
133
                        alpha += 0.01
134
                        rand.Seed(time.Now().UnixNano())
135
                        latency := rand.Float64() * alpha
136
                        createdAt = createdAt.Add(1 * time.Hour)
137
                        hit := &types.Hit{
138
                                Service:   service.Id,
139
                                CreatedAt: createdAt,
140
                                Latency:   latency,
141
                        }
142
                        service.CreateHit(hit)
143
                }
144
        }
145
        return nil
146
}
+
func Dbtimestamp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
200
func Dbtimestamp(group string, column string) string {
201
        seconds := 60
202
        if group == "second" {
203
                seconds = 60
204
        } else if group == "hour" {
205
                seconds = 3600
206
        } else if group == "day" {
207
                seconds = 86400
208
        }
209
        switch CoreApp.DbConnection {
210
        case "mysql":
211
                return fmt.Sprintf("CONCAT(date_format(created_at, '%%Y-%%m-%%d %%H:00:00')) AS timeframe, AVG(%v) AS value", column)
212
        case "sqlite":
213
                return fmt.Sprintf("datetime((strftime('%%s', created_at) / %v) * %v, 'unixepoch') AS timeframe, AVG(%v) as value", seconds, seconds, column)
214
        case "postgres":
215
                return fmt.Sprintf("date_trunc('%v', created_at) AS timeframe, AVG(%v) AS value", group, column)
216
        default:
217
                return ""
218
        }
219
}
+
func DbConfig.Update
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

268
func (db *DbConfig) Update() error {
269
        var err error
270
        config, err := os.Create(utils.Directory + "/config.yml")
271
        if err != nil {
272
                utils.Log(4, err)
273
                return err
274
        }
275
        data, err := yaml.Marshal(db)
276
        if err != nil {
277
                utils.Log(3, err)
278
                return err
279
        }
280
        config.WriteString(string(data))
281
        config.Close()
282
        return err
283
}
-
func Dbtimestamp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
180
func Dbtimestamp(group string, column string) string {
181
        seconds := 60
182
        if group == "second" {
183
                seconds = 60
184
        } else if group == "hour" {
185
                seconds = 3600
186
        } else if group == "day" {
187
                seconds = 86400
188
        }
189
        switch CoreApp.DbConnection {
190
        case "mysql":
191
                return fmt.Sprintf("CONCAT(date_format(created_at, '%%Y-%%m-%%d %%H:00:00')) AS timeframe, AVG(%v) AS value", column)
192
        case "sqlite":
193
                return fmt.Sprintf("datetime((strftime('%%s', created_at) / %v) * %v, 'unixepoch') AS timeframe, AVG(%v) as value", seconds, seconds, column)
194
        case "postgres":
195
                return fmt.Sprintf("date_trunc('%v', created_at) AS timeframe, AVG(%v) AS value", group, column)
196
        default:
197
                return ""
198
        }
199
}
-
func ExportChartsJs
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

87
func ExportChartsJs() string {
88
        render, err := source.JsBox.String("charts.js")
89
        if err != nil {
90
                utils.Log(4, err)
91
        }
92
        t := template.New("charts")
93
        t.Funcs(template.FuncMap{
94
                "safe": func(html string) template.HTML {
95
                        return template.HTML(html)
96
                },
97
        })
98
        t.Parse(render)
99
        var tpl bytes.Buffer
100
        if err := t.Execute(&tpl, CoreApp.Services); err != nil {
101
                utils.Log(3, err)
102
        }
103
        result := tpl.String()
104
        return result
105
}
func Service.TotalUptime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
289
func (s *Service) TotalUptime() string {
290
        hits, _ := s.TotalHits()
291
        failures, _ := s.TotalFailures()
292
        percent := float64(failures) / float64(hits) * 100
293
        percent = 100 - percent
294
        if percent < 0 {
295
                percent = 0
296
        }
297
        amount := fmt.Sprintf("%0.2f", percent)
298
        if amount == "100.00" {
299
                amount = "100"
300
        }
301
        return amount
302
}
+309
func (s *Service) TotalUptime() string {
310
        hits, _ := s.TotalHits()
311
        failures, _ := s.TotalFailures()
312
        percent := float64(failures) / float64(hits) * 100
313
        percent = 100 - percent
314
        if percent < 0 {
315
                percent = 0
316
        }
317
        amount := fmt.Sprintf("%0.2f", percent)
318
        if amount == "100.00" {
319
                amount = "100"
320
        }
321
        return amount
322
}
+ +
func Checkin.RecheckCheckinFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
196
func (c *Checkin) RecheckCheckinFailure(guard chan struct{}) {
197
        between := time.Now().Sub(time.Now()).Seconds()
198
        if between > float64(c.Interval) {
199
                fmt.Println("rechecking every 15 seconds!")
200
                time.Sleep(15 * time.Second)
201
                guard <- struct{}{}
202
                c.RecheckCheckinFailure(guard)
203
        } else {
204
                fmt.Println("i recovered!!")
205
        }
206
        <-guard
207
}
func DbConfig.CreateCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

306
func (c *DbConfig) CreateCore() *Core {
307
        newCore := &types.Core{
308
                Name:        c.Project,
309
                Description: c.Description,
310
                Config:      "config.yml",
311
                ApiKey:      c.ApiKey,
312
                ApiSecret:   c.ApiSecret,
313
                Domain:      c.Domain,
314
                MigrationId: time.Now().Unix(),
315
        }
316
        db := coreDB().Create(&newCore)
317
        if db.Error == nil {
318
                CoreApp = &Core{Core: newCore}
319
        }
320
        CoreApp, err := SelectCore()
321
        if err != nil {
322
                utils.Log(4, err)
323
        }
324
        return CoreApp
325
}
-
func checkin.RecheckCheckinFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
132
func (c *checkin) RecheckCheckinFailure(guard chan struct{}) {
133
        between := time.Now().Sub(time.Now()).Seconds()
134
        if between > float64(c.Interval) {
135
                fmt.Println("rechecking every 15 seconds!")
136
                time.Sleep(15 * time.Second)
137
                guard <- struct{}{}
138
                c.RecheckCheckinFailure(guard)
139
        } else {
140
                fmt.Println("i recovered!!")
141
        }
142
        <-guard
143
}
+
func Service.AvgTime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
108
func (s *Service) AvgTime() float64 {
109
        total, _ := s.TotalHits()
110
        if total == 0 {
111
                return float64(0)
112
        }
113
        sum, _ := s.Sum()
114
        avg := sum / float64(total) * 100
115
        amount := fmt.Sprintf("%0.0f", avg*10)
116
        val, _ := strconv.ParseFloat(amount, 10)
117
        return val
118
}
func Service.GraphData
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
248
func (s *Service) GraphData() string {
249
        start := time.Now().Add((-24 * 7) * time.Hour)
250
        end := time.Now()
251
        obj := GraphDataRaw(s, start, end, "hour", "latency")
252
        data, err := json.Marshal(obj)
253
        if err != nil {
254
                utils.Log(2, err)
255
                return ""
256
        }
257
        return string(data)
258
}
- -
func Service.AvgTime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
92
func (s *Service) AvgTime() float64 {
93
        total, _ := s.TotalHits()
94
        if total == 0 {
95
                return float64(0)
96
        }
97
        sum, _ := s.Sum()
98
        avg := sum / float64(total) * 100
99
        amount := fmt.Sprintf("%0.0f", avg*10)
100
        val, _ := strconv.ParseFloat(amount, 10)
101
        return val
102
}
- -
func InitApp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
60
func InitApp() {
61
        SelectCore()
62
        insertNotifierDB()
63
        CoreApp.SelectAllServices()
64
        checkServices()
65
        CoreApp.Notifications = notifier.Load()
66
        go DatabaseMaintence()
67
}
+268
func (s *Service) GraphData() string {
269
        start := time.Now().Add((-24 * 7) * time.Hour)
270
        end := time.Now()
271
        obj := GraphDataRaw(s, start, end, "hour", "latency")
272
        data, err := json.Marshal(obj)
273
        if err != nil {
274
                utils.Log(2, err)
275
                return ""
276
        }
277
        return string(data)
278
}
func Core.Count24HFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

88
func (c *Core) Count24HFailures() uint64 {
89
        var count uint64
90
        for _, s := range CoreApp.Services {
91
                service := s.(*Service)
92
                fails, _ := service.TotalFailures24()
93
                count += fails
94
        }
95
        return count
96
}
+
func InitApp
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
60
func InitApp() {
61
        SelectCore()
62
        insertNotifierDB()
63
        CoreApp.SelectAllServices()
64
        checkServices()
65
        CoreApp.Notifications = notifier.Load()
66
        go DatabaseMaintence()
67
}
+
func CountFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

99
func CountFailures() uint64 {
100
        var count uint64
101
        err := failuresDB().Count(&count)
102
        if err.Error != nil {
103
                utils.Log(2, err.Error)
104
                return 0
105
        }
106
        return count
107
}
-
func Service.lastFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
144
func (s *Service) lastFailure() *failure {
145
        limited := s.LimitedFailures()
146
        if len(limited) == 0 {
147
                return nil
148
        }
149
        last := limited[len(limited)-1]
150
        return last
151
}
+
func recordFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
247
func recordFailure(s *Service, issue string) {
248
        s.Online = false
249
        fail := &types.Failure{
250
                Service:   s.Id,
251
                Issue:     issue,
252
                PingTime:  s.PingTime,
253
                CreatedAt: time.Now(),
254
        }
255
        utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000))
256
        s.CreateFailure(fail)
257
        notifier.OnFailure(s.Service, fail)
258
}
func DateScanObj.ToString
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
238
func (d *DateScanObj) ToString() string {
239
        data, err := json.Marshal(d.Array)
240
        if err != nil {
241
                utils.Log(2, err)
242
                return "{}"
243
        }
244
        return string(data)
245
}
+258
func (d *DateScanObj) ToString() string {
259
        data, err := json.Marshal(d.Array)
260
        if err != nil {
261
                utils.Log(2, err)
262
                return "{}"
263
        }
264
        return string(data)
265
}
+ +
func Service.lastFailure
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
160
func (s *Service) lastFailure() *failure {
161
        limited := s.LimitedFailures()
162
        if len(limited) == 0 {
163
                return nil
164
        }
165
        last := limited[len(limited)-1]
166
        return last
167
}
func DatabaseMaintence
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

249
func DatabaseMaintence() {
250
        for range time.Tick(60 * time.Minute) {
251
                utils.Log(1, "Checking for database records older than 3 months...")
252
                since := time.Now().AddDate(0, -3, 0).UTC()
253
                DeleteAllSince("failures", since)
254
                DeleteAllSince("hits", since)
255
        }
256
}
-
func Core.CurrentTime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
88
func (c Core) CurrentTime() string {
89
        t := time.Now().UTC()
90
        current := utils.Timezoner(t, c.Timezone)
91
        ansic := "Monday 03:04:05 PM"
92
        return current.Format(ansic)
93
}
- -
func DeleteAllSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
259
func DeleteAllSince(table string, date time.Time) {
260
        sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, date.Format("2006-01-02"))
261
        db := DbSession.Raw(sql)
262
        if db.Error != nil {
263
                utils.Log(2, db.Error)
264
        }
265
}
+
func Core.AllOnline
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
126
func (c Core) AllOnline() bool {
127
        for _, s := range CoreApp.Services {
128
                if !s.Select().Online {
129
                        return false
130
                }
131
        }
132
        return true
133
}
func Service.TotalFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

116
func (s *Service) TotalFailures() (uint64, error) {
117
        var count uint64
118
        rows := failuresDB().Where("service = ?", s.Id)
119
        err := rows.Count(&count)
120
        return count, err.Error
121
}
+
func DeleteAllSince
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
259
func DeleteAllSince(table string, date time.Time) {
260
        sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, date.Format("2006-01-02"))
261
        db := DbSession.Raw(sql)
262
        if db.Error != nil {
263
                utils.Log(2, db.Error)
264
        }
265
}
+
func Service.DeleteFailures
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

59
func (s *Service) DeleteFailures() {
60
        err := DbSession.Exec(`DELETE FROM failures WHERE service = ?`, s.Id)
61
        if err.Error != nil {
62
                utils.Log(3, fmt.Sprintf("failed to delete all failures: %v", err))
63
        }
64
        s.Failures = nil
65
}
func DbConfig.InsertCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

179
func (db *DbConfig) InsertCore() (*Core, error) {
180
        CoreApp = &Core{Core: &types.Core{
181
                Name:        db.Project,
182
                Description: db.Description,
183
                Config:      "config.yml",
184
                ApiKey:      utils.NewSHA1Hash(9),
185
                ApiSecret:   utils.NewSHA1Hash(16),
186
                Domain:      db.Domain,
187
                MigrationId: time.Now().Unix(),
188
        }}
189
        CoreApp.DbConnection = db.DbConn
190
        query := coreDB().Create(&CoreApp)
191
        return CoreApp, query.Error
192
}
-
func Core.AllOnline
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
126
func (c Core) AllOnline() bool {
127
        for _, s := range CoreApp.Services {
128
                if !s.Select().Online {
129
                        return false
130
                }
131
        }
132
        return true
133
}
- -
func DeleteConfig
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/configs.go:

-
133
func DeleteConfig() {
134
        err := os.Remove(utils.Directory + "/config.yml")
135
        if err != nil {
136
                utils.Log(3, err)
137
        }
138
}
- -
func Core.SassVars
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
101
func (c Core) SassVars() string {
102
        if !source.UsingAssets(utils.Directory) {
103
                return ""
104
        }
105
        return source.OpenAsset(utils.Directory, "scss/variables.scss")
106
}
- -
func Core.BaseSASS
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
109
func (c Core) BaseSASS() string {
110
        if !source.UsingAssets(utils.Directory) {
111
                return ""
112
        }
113
        return source.OpenAsset(utils.Directory, "scss/base.scss")
114
}
- -
func SelectCheckin
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
50
func SelectCheckin(api string) *checkin {
51
        var checkin checkin
52
        checkinDB().Where("api_key = ?", api).First(&checkin)
53
        return &checkin
54
}
- -
func Core.MobileSASS
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
118
func (c Core) MobileSASS() string {
119
        if !source.UsingAssets(utils.Directory) {
120
                return ""
121
        }
122
        return source.OpenAsset(utils.Directory, "scss/mobile.scss")
123
}
- -
func checkServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

-
34
func checkServices() {
35
        utils.Log(1, fmt.Sprintf("Starting monitoring process for %v Services", len(CoreApp.Services)))
36
        for _, ser := range CoreApp.Services {
37
                //go obj.StartCheckins()
38
                go ser.CheckQueue(true)
39
        }
40
}
+
func Core.CurrentTime
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
88
func (c Core) CurrentTime() string {
89
        t := time.Now().UTC()
90
        current := utils.Timezoner(t, c.Timezone)
91
        ansic := "Monday 03:04:05 PM"
92
        return current.Format(ansic)
93
}
func Hit.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

131
func (h *Hit) BeforeCreate() (err error) {
132
        if h.CreatedAt.IsZero() {
133
                h.CreatedAt = time.Now().UTC()
134
        }
135
        return
136
}
+
func SelectCheckinId
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
101
func SelectCheckinId(id int64) *Checkin {
102
        var checkin Checkin
103
        checkinDB().Where("id = ?", id).First(&checkin)
104
        return &checkin
105
}
+ +
func Core.SassVars
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
101
func (c Core) SassVars() string {
102
        if !source.UsingAssets(utils.Directory) {
103
                return ""
104
        }
105
        return source.OpenAsset(utils.Directory, "scss/variables.scss")
106
}
+ +
func SelectCheckin
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
94
func SelectCheckin(api string) *Checkin {
95
        var checkin Checkin
96
        checkinDB().Where("api_key = ?", api).First(&checkin)
97
        return &checkin
98
}
+ +
func DeleteConfig
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/configs.go:

+
133
func DeleteConfig() {
134
        err := os.Remove(utils.Directory + "/config.yml")
135
        if err != nil {
136
                utils.Log(3, err)
137
        }
138
}
+ +
func Service.LimitedCheckins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
71
func (s *Service) LimitedCheckins() []*Checkin {
72
        var checkin []*Checkin
73
        checkinDB().Where("service = ?", s.Id).Limit(10).Find(&checkin)
74
        return checkin
75
}
+ +
func Core.MobileSASS
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
118
func (c Core) MobileSASS() string {
119
        if !source.UsingAssets(utils.Directory) {
120
                return ""
121
        }
122
        return source.OpenAsset(utils.Directory, "scss/mobile.scss")
123
}
+ +
func Core.BaseSASS
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
109
func (c Core) BaseSASS() string {
110
        if !source.UsingAssets(utils.Directory) {
111
                return ""
112
        }
113
        return source.OpenAsset(utils.Directory, "scss/base.scss")
114
}
+
func failure.BeforeCreate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

139
func (f *failure) BeforeCreate() (err error) {
140
        if f.CreatedAt.IsZero() {
141
                f.CreatedAt = time.Now().UTC()
142
        }
143
        return
144
}
+
func Checkin.Delete
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
147
func (c *Checkin) Delete() error {
148
        c.Close()
149
        row := checkinDB().Delete(&c)
150
        return row.Error
151
}
+ +
func checkServices
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checker.go:

+
34
func checkServices() {
35
        utils.Log(1, fmt.Sprintf("Starting monitoring process for %v Services", len(CoreApp.Services)))
36
        for _, ser := range CoreApp.Services {
37
                //go obj.StartCheckins()
38
                go ser.CheckQueue(true)
39
        }
40
}
+ +
func Service.TotalFailures24
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

+
110
func (s *Service) TotalFailures24() (uint64, error) {
111
        ago := time.Now().Add(-24 * time.Hour)
112
        return s.TotalFailuresSince(ago)
113
}
+
func Service.Online24
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
105
func (s *Service) Online24() float32 {
106
        ago := time.Now().Add(-24 * time.Hour)
107
        return s.OnlineSince(ago)
108
}
+121
func (s *Service) Online24() float32 {
122
        ago := time.Now().Add(-24 * time.Hour)
123
        return s.OnlineSince(ago)
124
}
func Service.ToJSON
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
86
func (s *Service) ToJSON() string {
87
        data, _ := json.Marshal(s)
88
        return string(data)
89
}
+102
func (s *Service) ToJSON() string {
103
        data, _ := json.Marshal(s)
104
        return string(data)
105
}
+ +
func failure.Ago
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

+
76
func (f *failure) Ago() string {
77
        got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
78
        return got
79
}
func Service.HitsBetween
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

77
func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) *gorm.DB {
78
        selector := Dbtimestamp(group, column)
79
        return DbSession.Model(&types.Hit{}).Select(selector).Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, t1.Format(types.TIME_DAY), t2.Format(types.TIME_DAY)).Order("timeframe asc", false).Group("timeframe")
80
}
-
func failure.Ago
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

-
76
func (f *failure) Ago() string {
77
        got, _ := timeago.TimeAgoWithTime(time.Now(), f.CreatedAt)
78
        return got
79
}
+
func CloseDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
83
func CloseDB() {
84
        if DbSession != nil {
85
                DbSession.DB().Close()
86
        }
87
}
func failure.Delete
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

82
func (f *failure) Delete() error {
83
        db := failuresDB().Delete(f)
84
        return db.Error
85
}
@@ -753,68 +781,68 @@ PACKAGE:github.com/hunterlong/statup/cmd DONE:31.37
func DbConfig.waitForDb
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

242
func (db *DbConfig) waitForDb() error {
243
        time.Sleep(5 * time.Second)
244
        return db.Connect(true, utils.Directory)
245
}
-
func Service.TotalFailures24
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/failures.go:

-
110
func (s *Service) TotalFailures24() (uint64, error) {
111
        ago := time.Now().Add(-24 * time.Hour)
112
        return s.TotalFailuresSince(ago)
113
}
- -
func CloseDB
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

-
83
func CloseDB() {
84
        if DbSession != nil {
85
                DbSession.DB().Close()
86
        }
87
}
-
func Service.AvgUptime24
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
261
func (s *Service) AvgUptime24() string {
262
        ago := time.Now().Add(-24 * time.Hour)
263
        return s.AvgUptime(ago)
264
}
+281
func (s *Service) AvgUptime24() string {
282
        ago := time.Now().Add(-24 * time.Hour)
283
        return s.AvgUptime(ago)
284
}
func UpdateCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

82
func UpdateCore(c *Core) (*Core, error) {
83
        db := coreDB().Update(&c)
84
        return c, db.Error
85
}
-
func @65:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
65
func(html string) string {
66
                        return utils.UnderScoreString(html)
67
                }
- -
func Service.DowntimeText
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
175
func (s *Service) DowntimeText() string {
176
        return fmt.Sprintf("%v has been offline for %v", s.Name, utils.DurationReadable(s.Downtime()))
177
}
- -
func Service.UpdateSingle
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
337
func (s *Service) UpdateSingle(attr ...interface{}) error {
338
        return servicesDB().Model(s).Update(attr).Error
339
}
- -
func @56:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
56
func() string {
57
                        return VERSION
58
                }
- -
func @59:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
59
func() *Core {
60
                        return CoreApp
61
                }
- -
func Core.ServicesCount
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

-
377
func (c *Core) ServicesCount() int {
378
        return len(c.Services)
379
}
- -
func @62:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
62
func() bool {
63
                        return CoreApp.UseCdn
64
                }
- -
func @50:9
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
50
func(html string) template.JS {
51
                        return template.JS(html)
52
                }
- -
func Core.UsingAssets
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

-
96
func (c Core) UsingAssets() bool {
97
        return source.UsingAssets(utils.Directory)
98
}
- -
func @68:10
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
68
func() string {
69
                        return "/"
70
                }
- -
func @71:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
71
func() string {
72
                        return ExportChartsJs()
73
                }
-
func Core.ToCore
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

55
func (c *Core) ToCore() *types.Core {
56
        return c.Core
57
}
-
func @94:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
94
func(html string) template.HTML {
95
                        return template.HTML(html)
96
                }
- -
func injectDatabase
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

-
26
func injectDatabase() {
27
        Configs.Connect(false, utils.Directory)
28
}
- -
func checkin.String
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

-
35
func (c *checkin) String() string {
36
        return c.ApiKey
37
}
-
func @53:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

53
func(html string) template.HTML {
54
                        return template.HTML(html)
55
                }
+
func DbConfig.Close
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/database.go:

+
90
func (db *DbConfig) Close() error {
91
        return DbSession.DB().Close()
92
}
+ +
func Core.UsingAssets
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/core.go:

+
96
func (c Core) UsingAssets() bool {
97
        return source.UsingAssets(utils.Directory)
98
}
+ +
func Service.UpdateSingle
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
357
func (s *Service) UpdateSingle(attr ...interface{}) error {
358
        return servicesDB().Model(s).Update(attr).Error
359
}
+ +
func Service.DowntimeText
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
195
func (s *Service) DowntimeText() string {
196
        return fmt.Sprintf("%v has been offline for %v", s.Name, utils.DurationReadable(s.Downtime()))
197
}
+ +
func injectDatabase
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
26
func injectDatabase() {
27
        Configs.Connect(false, utils.Directory)
28
}
+ +
func Core.ServicesCount
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/services.go:

+
397
func (c *Core) ServicesCount() int {
398
        return len(c.Services)
399
}
+ +
func @94:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
94
func(html string) template.HTML {
95
                        return template.HTML(html)
96
                }
+ +
func @71:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
71
func() string {
72
                        return ExportChartsJs()
73
                }
+ +
func @68:10
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
68
func() string {
69
                        return "/"
70
                }
+ +
func @65:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
65
func(html string) string {
66
                        return utils.UnderScoreString(html)
67
                }
+ +
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
135
func (c *Checkin) Link() string {
136
        return fmt.Sprintf("%v/checkin/%v", CoreApp.Domain, c.ApiKey)
137
}
+ +
func @62:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
62
func() bool {
63
                        return CoreApp.UseCdn
64
                }
+ +
func @59:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
59
func() *Core {
60
                        return CoreApp
61
                }
+ +
func Checkin.String
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/checkin.go:

+
61
func (c *Checkin) String() string {
62
        return c.ApiKey
63
}
+ +
func @56:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
56
func() string {
57
                        return VERSION
58
                }
+ +
func @50:9
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/core/export.go:

+
50
func(html string) template.JS {
51
                        return template.JS(html)
52
                }
+
Package Overview: github.com/hunterlong/statup/core/notifier 72.73%

This is a coverage report created after analysis of the github.com/hunterlong/statup/core/notifier package. It @@ -1022,9 +1050,9 @@ PACKAGE:github.com/hunterlong/statup/core DONE:54.09 PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 --> -

Package Overview: github.com/hunterlong/statup/handlers 68.52%

This is a coverage report created after analysis of the github.com/hunterlong/statup/handlers package. It +

Package Overview: github.com/hunterlong/statup/handlers 67.61%

This is a coverage report created after analysis of the github.com/hunterlong/statup/handlers package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/handlers | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

- + @@ -1045,20 +1073,20 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 - - + + - + + - @@ -1077,8 +1105,8 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 - + @@ -1086,38 +1114,40 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 - - + + - + + + - - - + + - + + - - - + + +
Router(...)github.com/hunterlong/statup/handlers/routes.go100.00%67/67
Router(...)github.com/hunterlong/statup/handlers/routes.go100.00%68/68
prometheusHandler(...)github.com/hunterlong/statup/handlers/prometheus.go100.00%22/22
exportHandler(...)github.com/hunterlong/statup/handlers/dashboard.go100.00%18/18
saveSASSHandler(...)github.com/hunterlong/statup/handlers/settings.go100.00%13/13
error404Handler(...)github.com/hunterlong/statup/handlers/handlers.go100.00%2/2
parseForm(...)github.com/hunterlong/statup/handlers/settings.go100.00%2/2
parseGet(...)github.com/hunterlong/statup/handlers/settings.go100.00%2/2
@135:12(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@157:14(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@126:17(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@138:15(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@135:12(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@151:15(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@88:20(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@138:15(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@129:10(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@93:11(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@96:11(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@99:14(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@102:14(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@105:15(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@108:14(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@126:17(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@154:17(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
@129:10(...)github.com/hunterlong/statup/handlers/handlers.go100.00%1/1
saveSettingsHandler(...)github.com/hunterlong/statup/handlers/settings.go96.15%25/26
servicesUpdateHandler(...)github.com/hunterlong/statup/handlers/services.go93.55%29/31
loginHandler(...)github.com/hunterlong/statup/handlers/dashboard.go92.86%13/14
executeJSResponse(...)github.com/hunterlong/statup/handlers/handlers.go72.73%8/11
reorderServiceHandler(...)github.com/hunterlong/statup/handlers/services.go72.73%8/11
saveAssetsHandler(...)github.com/hunterlong/statup/handlers/settings.go71.43%10/14
apiServiceUpdateHandler(...)github.com/hunterlong/statup/handlers/api.go70.00%14/20
updateUserHandler(...)github.com/hunterlong/statup/handlers/users.go70.00%14/20
apiServiceUpdateHandler(...)github.com/hunterlong/statup/handlers/api.go70.00%14/20
apiRenewHandler(...)github.com/hunterlong/statup/handlers/api.go70.00%7/10
apiUserUpdateHandler(...)github.com/hunterlong/statup/handlers/api.go68.42%13/19
IsAuthenticated(...)github.com/hunterlong/statup/handlers/handlers.go66.67%8/12
processSetupHandler(...)github.com/hunterlong/statup/handlers/setup.go66.07%37/56
apiCreateUsersHandler(...)github.com/hunterlong/statup/handlers/api.go64.71%11/17
apiCreateServiceHandler(...)github.com/hunterlong/statup/handlers/api.go62.50%10/16
apiUserDeleteHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%9/15
apiServiceDeleteHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%9/15
apiServiceHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%6/10
apiUserDeleteHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%9/15
apiUserHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%6/10
apiServiceHandler(...)github.com/hunterlong/statup/handlers/api.go60.00%6/10
dashboardHandler(...)github.com/hunterlong/statup/handlers/dashboard.go60.00%3/5
indexHandler(...)github.com/hunterlong/statup/handlers/index.go50.00%2/4
isAPIAuthorized(...)github.com/hunterlong/statup/handlers/api.go28.57%2/7
testNotificationHandler(...)github.com/hunterlong/statup/handlers/settings.go0.00%0/46
DesktopInit(...)github.com/hunterlong/statup/handlers/index.go0.00%0/42
checkinCreateUpdateHandler(...)github.com/hunterlong/statup/handlers/services.go0.00%0/13
checkinCreateHandler(...)github.com/hunterlong/statup/handlers/services.go0.00%0/13
apiServicePingDataHandler(...)github.com/hunterlong/statup/handlers/api.go0.00%0/12
checkinHitHandler(...)github.com/hunterlong/statup/handlers/services.go0.00%0/10
checkinDeleteHandler(...)github.com/hunterlong/statup/handlers/services.go0.00%0/9
pluginSavedHandler(...)github.com/hunterlong/statup/handlers/plugins.go0.00%0/9
@111:11(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/8
checkinUpdateHandler(...)github.com/hunterlong/statup/handlers/services.go0.00%0/7
apiCheckinHandler(...)github.com/hunterlong/statup/handlers/api.go0.00%0/7
pluginsDownloadHandler(...)github.com/hunterlong/statup/handlers/plugins.go0.00%0/5
parseId(...)github.com/hunterlong/statup/handlers/settings.go0.00%0/2
@144:15(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/2
@122:13(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/2
trayHandler(...)github.com/hunterlong/statup/handlers/index.go0.00%0/1
@144:15(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/2
@90:9(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@148:13(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@132:17(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@232:15(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
setupResponseError(...)github.com/hunterlong/statup/handlers/setup.go0.00%0/1
@235:15(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@160:17(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@141:10(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@90:9(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
@229:11(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
github.com/hunterlong/statup/handlers68.52%642/937
trayHandler(...)github.com/hunterlong/statup/handlers/index.go0.00%0/1
@232:11(...)github.com/hunterlong/statup/handlers/handlers.go0.00%0/1
github.com/hunterlong/statup/handlers67.61%643/951
func Router
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/routes.go:

-
34
func Router() *mux.Router {
35
        dir := utils.Directory
36
        r := mux.NewRouter()
37
        r.Handle("/", http.HandlerFunc(indexHandler))
38
        if source.UsingAssets(dir) {
39
                indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
40
                r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir(dir+"/assets/css"))))
41
                r.PathPrefix("/robots.txt").Handler(indexHandler)
42
                r.PathPrefix("/favicon.ico").Handler(indexHandler)
43
                r.PathPrefix("/statup.png").Handler(indexHandler)
44
        } else {
45
                r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(source.CssBox.HTTPBox())))
46
                r.PathPrefix("/robots.txt").Handler(http.FileServer(source.TmplBox.HTTPBox()))
47
                r.PathPrefix("/favicon.ico").Handler(http.FileServer(source.TmplBox.HTTPBox()))
48
                r.PathPrefix("/statup.png").Handler(http.FileServer(source.TmplBox.HTTPBox()))
49
        }
50
        r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(source.JsBox.HTTPBox())))
51
        r.Handle("/charts.js", http.HandlerFunc(renderServiceChartsHandler))
52
        r.Handle("/setup", http.HandlerFunc(setupHandler)).Methods("GET")
53
        r.Handle("/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
54
        r.Handle("/dashboard", http.HandlerFunc(dashboardHandler)).Methods("GET")
55
        r.Handle("/dashboard", http.HandlerFunc(loginHandler)).Methods("POST")
56
        r.Handle("/logout", http.HandlerFunc(logoutHandler))
57
        r.Handle("/plugins/download/{name}", http.HandlerFunc(pluginsDownloadHandler))
58
        r.Handle("/plugins/{name}/save", http.HandlerFunc(pluginSavedHandler)).Methods("POST")
59
        r.Handle("/help", http.HandlerFunc(helpHandler))
60
        r.Handle("/logs", http.HandlerFunc(logsHandler))
61
        r.Handle("/logs/line", http.HandlerFunc(logsLineHandler))
62
63
        // USER Routes
64
        r.Handle("/users", http.HandlerFunc(usersHandler)).Methods("GET")
65
        r.Handle("/users", http.HandlerFunc(createUserHandler)).Methods("POST")
66
        r.Handle("/user/{id}", http.HandlerFunc(usersEditHandler)).Methods("GET")
67
        r.Handle("/user/{id}", http.HandlerFunc(updateUserHandler)).Methods("POST")
68
        r.Handle("/user/{id}/delete", http.HandlerFunc(usersDeleteHandler)).Methods("GET")
69
70
        // SETTINGS Routes
71
        r.Handle("/settings", http.HandlerFunc(settingsHandler)).Methods("GET")
72
        r.Handle("/settings", http.HandlerFunc(saveSettingsHandler)).Methods("POST")
73
        r.Handle("/settings/css", http.HandlerFunc(saveSASSHandler)).Methods("POST")
74
        r.Handle("/settings/build", http.HandlerFunc(saveAssetsHandler)).Methods("GET")
75
        r.Handle("/settings/delete_assets", http.HandlerFunc(deleteAssetsHandler)).Methods("GET")
76
        r.Handle("/settings/notifier/{method}", http.HandlerFunc(saveNotificationHandler)).Methods("POST")
77
        r.Handle("/settings/notifier/{method}/test", http.HandlerFunc(testNotificationHandler)).Methods("POST")
78
        r.Handle("/settings/export", http.HandlerFunc(exportHandler)).Methods("GET")
79
80
        // SERVICE Routes
81
        r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
82
        r.Handle("/services", http.HandlerFunc(createServiceHandler)).Methods("POST")
83
        r.Handle("/services/reorder", http.HandlerFunc(reorderServiceHandler)).Methods("POST")
84
        r.Handle("/service/{id}", http.HandlerFunc(servicesViewHandler)).Methods("GET")
85
        r.Handle("/service/{id}", http.HandlerFunc(servicesUpdateHandler)).Methods("POST")
86
        r.Handle("/service/{id}/edit", http.HandlerFunc(servicesViewHandler))
87
        r.Handle("/service/{id}/delete", http.HandlerFunc(servicesDeleteHandler))
88
        r.Handle("/service/{id}/delete_failures", http.HandlerFunc(servicesDeleteFailuresHandler)).Methods("GET")
89
        r.Handle("/service/{id}/checkin", http.HandlerFunc(checkinCreateUpdateHandler)).Methods("POST")
90
        r.Handle("/checkin/{id}", http.HandlerFunc(checkinUpdateHandler))
91
92
        // API SERVICE Routes
93
        r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
94
        r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
95
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
96
        r.Handle("/api/services/{id}/data", http.HandlerFunc(apiServiceDataHandler)).Methods("GET")
97
        r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
98
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
99
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
100
101
        // API USER Routes
102
        r.Handle("/api/users", http.HandlerFunc(apiAllUsersHandler)).Methods("GET")
103
        r.Handle("/api/users", http.HandlerFunc(apiCreateUsersHandler)).Methods("POST")
104
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserHandler)).Methods("GET")
105
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserUpdateHandler)).Methods("POST")
106
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserDeleteHandler)).Methods("DELETE")
107
108
        // Generic API Routes
109
        r.Handle("/api", http.HandlerFunc(apiIndexHandler))
110
        r.Handle("/api/renew", http.HandlerFunc(apiRenewHandler))
111
        r.Handle("/api/checkin/{api}", http.HandlerFunc(apiCheckinHandler))
112
        r.Handle("/metrics", http.HandlerFunc(prometheusHandler))
113
        r.Handle("/tray", http.HandlerFunc(trayHandler))
114
        r.NotFoundHandler = http.HandlerFunc(error404Handler)
115
        return r
116
}
+34
func Router() *mux.Router {
35
        dir := utils.Directory
36
        r := mux.NewRouter()
37
        r.Handle("/", http.HandlerFunc(indexHandler))
38
        if source.UsingAssets(dir) {
39
                indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
40
                r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir(dir+"/assets/css"))))
41
                r.PathPrefix("/robots.txt").Handler(indexHandler)
42
                r.PathPrefix("/favicon.ico").Handler(indexHandler)
43
                r.PathPrefix("/statup.png").Handler(indexHandler)
44
        } else {
45
                r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(source.CssBox.HTTPBox())))
46
                r.PathPrefix("/robots.txt").Handler(http.FileServer(source.TmplBox.HTTPBox()))
47
                r.PathPrefix("/favicon.ico").Handler(http.FileServer(source.TmplBox.HTTPBox()))
48
                r.PathPrefix("/statup.png").Handler(http.FileServer(source.TmplBox.HTTPBox()))
49
        }
50
        r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(source.JsBox.HTTPBox())))
51
        r.Handle("/charts.js", http.HandlerFunc(renderServiceChartsHandler))
52
        r.Handle("/setup", http.HandlerFunc(setupHandler)).Methods("GET")
53
        r.Handle("/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
54
        r.Handle("/dashboard", http.HandlerFunc(dashboardHandler)).Methods("GET")
55
        r.Handle("/dashboard", http.HandlerFunc(loginHandler)).Methods("POST")
56
        r.Handle("/logout", http.HandlerFunc(logoutHandler))
57
        r.Handle("/plugins/download/{name}", http.HandlerFunc(pluginsDownloadHandler))
58
        r.Handle("/plugins/{name}/save", http.HandlerFunc(pluginSavedHandler)).Methods("POST")
59
        r.Handle("/help", http.HandlerFunc(helpHandler))
60
        r.Handle("/logs", http.HandlerFunc(logsHandler))
61
        r.Handle("/logs/line", http.HandlerFunc(logsLineHandler))
62
63
        // USER Routes
64
        r.Handle("/users", http.HandlerFunc(usersHandler)).Methods("GET")
65
        r.Handle("/users", http.HandlerFunc(createUserHandler)).Methods("POST")
66
        r.Handle("/user/{id}", http.HandlerFunc(usersEditHandler)).Methods("GET")
67
        r.Handle("/user/{id}", http.HandlerFunc(updateUserHandler)).Methods("POST")
68
        r.Handle("/user/{id}/delete", http.HandlerFunc(usersDeleteHandler)).Methods("GET")
69
70
        // SETTINGS Routes
71
        r.Handle("/settings", http.HandlerFunc(settingsHandler)).Methods("GET")
72
        r.Handle("/settings", http.HandlerFunc(saveSettingsHandler)).Methods("POST")
73
        r.Handle("/settings/css", http.HandlerFunc(saveSASSHandler)).Methods("POST")
74
        r.Handle("/settings/build", http.HandlerFunc(saveAssetsHandler)).Methods("GET")
75
        r.Handle("/settings/delete_assets", http.HandlerFunc(deleteAssetsHandler)).Methods("GET")
76
        r.Handle("/settings/notifier/{method}", http.HandlerFunc(saveNotificationHandler)).Methods("POST")
77
        r.Handle("/settings/notifier/{method}/test", http.HandlerFunc(testNotificationHandler)).Methods("POST")
78
        r.Handle("/settings/export", http.HandlerFunc(exportHandler)).Methods("GET")
79
80
        // SERVICE Routes
81
        r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
82
        r.Handle("/services", http.HandlerFunc(createServiceHandler)).Methods("POST")
83
        r.Handle("/services/reorder", http.HandlerFunc(reorderServiceHandler)).Methods("POST")
84
        r.Handle("/service/{id}", http.HandlerFunc(servicesViewHandler)).Methods("GET")
85
        r.Handle("/service/{id}", http.HandlerFunc(servicesUpdateHandler)).Methods("POST")
86
        r.Handle("/service/{id}/edit", http.HandlerFunc(servicesViewHandler))
87
        r.Handle("/service/{id}/delete", http.HandlerFunc(servicesDeleteHandler))
88
        r.Handle("/service/{id}/delete_failures", http.HandlerFunc(servicesDeleteFailuresHandler)).Methods("GET")
89
        r.Handle("/service/{id}/checkin", http.HandlerFunc(checkinCreateHandler)).Methods("POST")
90
        r.Handle("/checkin/{id}/delete", http.HandlerFunc(checkinDeleteHandler)).Methods("GET")
91
        r.Handle("/checkin/{id}", http.HandlerFunc(checkinHitHandler))
92
93
        // API SERVICE Routes
94
        r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
95
        r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
96
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
97
        r.Handle("/api/services/{id}/data", http.HandlerFunc(apiServiceDataHandler)).Methods("GET")
98
        r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
99
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
100
        r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
101
102
        // API USER Routes
103
        r.Handle("/api/users", http.HandlerFunc(apiAllUsersHandler)).Methods("GET")
104
        r.Handle("/api/users", http.HandlerFunc(apiCreateUsersHandler)).Methods("POST")
105
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserHandler)).Methods("GET")
106
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserUpdateHandler)).Methods("POST")
107
        r.Handle("/api/users/{id}", http.HandlerFunc(apiUserDeleteHandler)).Methods("DELETE")
108
109
        // Generic API Routes
110
        r.Handle("/api", http.HandlerFunc(apiIndexHandler))
111
        r.Handle("/api/renew", http.HandlerFunc(apiRenewHandler))
112
        r.Handle("/api/checkin/{api}", http.HandlerFunc(apiCheckinHandler))
113
        r.Handle("/metrics", http.HandlerFunc(prometheusHandler))
114
        r.Handle("/tray", http.HandlerFunc(trayHandler))
115
        r.NotFoundHandler = http.HandlerFunc(error404Handler)
116
        return r
117
}
func prometheusHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/prometheus.go:

36
func prometheusHandler(w http.ResponseWriter, r *http.Request) {
37
        utils.Log(1, fmt.Sprintf("Prometheus /metrics Request From IP: %v\n", r.RemoteAddr))
38
        if !isAuthorized(r) {
39
                http.Redirect(w, r, "/", http.StatusSeeOther)
40
                return
41
        }
42
        metrics := []string{}
43
        system := fmt.Sprintf("statup_total_failures %v\n", core.CountFailures())
44
        system += fmt.Sprintf("statup_total_services %v", len(core.CoreApp.Services))
45
        metrics = append(metrics, system)
46
        for _, ser := range core.CoreApp.Services {
47
                v := ser.Select()
48
                online := 1
49
                if !v.Online {
50
                        online = 0
51
                }
52
                met := fmt.Sprintf("statup_service_failures{id=\"%v\" name=\"%v\"} %v\n", v.Id, v.Name, len(v.Failures))
53
                met += fmt.Sprintf("statup_service_latency{id=\"%v\" name=\"%v\"} %0.0f\n", v.Id, v.Name, (v.Latency * 100))
54
                met += fmt.Sprintf("statup_service_online{id=\"%v\" name=\"%v\"} %v\n", v.Id, v.Name, online)
55
                met += fmt.Sprintf("statup_service_status_code{id=\"%v\" name=\"%v\"} %v\n", v.Id, v.Name, v.LastStatusCode)
56
                met += fmt.Sprintf("statup_service_response_length{id=\"%v\" name=\"%v\"} %v", v.Id, v.Name, len([]byte(v.LastResponse)))
57
                metrics = append(metrics, met)
58
        }
59
        output := strings.Join(metrics, "\n")
60
        w.WriteHeader(http.StatusOK)
61
        w.Write([]byte(output))
62
}
@@ -1168,10 +1198,10 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 62
func logoutHandler(w http.ResponseWriter, r *http.Request) {
63
        session, _ := sessionStore.Get(r, cookieKey)
64
        session.Values["authenticated"] = false
65
        session.Save(r, w)
66
        http.Redirect(w, r, "/", http.StatusSeeOther)
67
}
func resetRouter
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/routes.go:

-
118
func resetRouter() {
119
        router = Router()
120
        httpServer.Handler = router
121
}
+119
func resetRouter() {
120
        router = Router()
121
        httpServer.Handler = router
122
}
func error404Handler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
248
func error404Handler(w http.ResponseWriter, r *http.Request) {
249
        w.WriteHeader(http.StatusNotFound)
250
        executeResponse(w, r, "error_404.html", nil, nil)
251
}
+251
func error404Handler(w http.ResponseWriter, r *http.Request) {
252
        w.WriteHeader(http.StatusNotFound)
253
        executeResponse(w, r, "error_404.html", nil, nil)
254
}
func parseForm
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/settings.go:

127
func parseForm(r *http.Request) url.Values {
128
        r.ParseForm()
129
        return r.PostForm
130
}
@@ -1179,23 +1209,23 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func parseGet
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/settings.go:

132
func parseGet(r *http.Request) url.Values {
133
        r.ParseForm()
134
        return r.Form
135
}
-
func @135:12
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
135
func() string {
136
                        return ""
137
                }
-
func @157:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

157
func() *types.User {
158
                        return new(types.User)
159
                }
-
func @126:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
126
func(html string) string {
127
                        return utils.UnderScoreString(html)
128
                }
+
func @138:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
138
func(v interface{}) string {
139
                        return utils.ToString(v)
140
                }
+ +
func @135:12
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
135
func() string {
136
                        return ""
137
                }
func @151:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

151
func(t int64) string {
152
                        return utils.Timezoner(time.Unix(t, 0), core.CoreApp.Timezone).Format("Monday, January 02")
153
                }
func @88:20
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
88
func(w http.ResponseWriter, r *http.Request) template.FuncMap {
89
        return template.FuncMap{
90
                "js": func(html interface{}) template.JS {
91
                        return template.JS(utils.ToString(html))
92
                },
93
                "safe": func(html string) template.HTML {
94
                        return template.HTML(html)
95
                },
96
                "Auth": func() bool {
97
                        return IsAuthenticated(r)
98
                },
99
                "VERSION": func() string {
100
                        return core.VERSION
101
                },
102
                "CoreApp": func() *core.Core {
103
                        return core.CoreApp
104
                },
105
                "Services": func() []types.ServiceInterface {
106
                        return core.CoreApp.Services
107
                },
108
                "USE_CDN": func() bool {
109
                        return core.CoreApp.UseCdn
110
                },
111
                "Type": func(g interface{}) []string {
112
                        fooType := reflect.TypeOf(g)
113
                        var methods []string
114
                        methods = append(methods, fooType.String())
115
                        for i := 0; i < fooType.NumMethod(); i++ {
116
                                method := fooType.Method(i)
117
                                fmt.Println(method.Name)
118
                                methods = append(methods, method.Name)
119
                        }
120
                        return methods
121
                },
122
                "ToJSON": func(g interface{}) template.HTML {
123
                        data, _ := json.Marshal(g)
124
                        return template.HTML(string(data))
125
                },
126
                "underscore": func(html string) string {
127
                        return utils.UnderScoreString(html)
128
                },
129
                "URL": func() string {
130
                        return r.URL.String()
131
                },
132
                "CHART_DATA": func() string {
133
                        return ""
134
                },
135
                "Error": func() string {
136
                        return ""
137
                },
138
                "ToString": func(v interface{}) string {
139
                        return utils.ToString(v)
140
                },
141
                "Ago": func(t time.Time) string {
142
                        return utils.Timestamp(t).Ago()
143
                },
144
                "Duration": func(t time.Duration) string {
145
                        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", t.Seconds()))
146
                        return utils.FormatDuration(duration)
147
                },
148
                "ToUnix": func(t time.Time) int64 {
149
                        return t.UTC().Unix()
150
                },
151
                "FromUnix": func(t int64) string {
152
                        return utils.Timezoner(time.Unix(t, 0), core.CoreApp.Timezone).Format("Monday, January 02")
153
                },
154
                "NewService": func() *types.Service {
155
                        return new(types.Service)
156
                },
157
                "NewUser": func() *types.User {
158
                        return new(types.User)
159
                },
160
        }
161
}
+88
func(w http.ResponseWriter, r *http.Request) template.FuncMap {
89
        return template.FuncMap{
90
                "js": func(html interface{}) template.JS {
91
                        return template.JS(utils.ToString(html))
92
                },
93
                "safe": func(html string) template.HTML {
94
                        return template.HTML(html)
95
                },
96
                "Auth": func() bool {
97
                        return IsAuthenticated(r)
98
                },
99
                "VERSION": func() string {
100
                        return core.VERSION
101
                },
102
                "CoreApp": func() *core.Core {
103
                        return core.CoreApp
104
                },
105
                "Services": func() []types.ServiceInterface {
106
                        return core.CoreApp.Services
107
                },
108
                "USE_CDN": func() bool {
109
                        return core.CoreApp.UseCdn
110
                },
111
                "Type": func(g interface{}) []string {
112
                        fooType := reflect.TypeOf(g)
113
                        var methods []string
114
                        methods = append(methods, fooType.String())
115
                        for i := 0; i < fooType.NumMethod(); i++ {
116
                                method := fooType.Method(i)
117
                                fmt.Println(method.Name)
118
                                methods = append(methods, method.Name)
119
                        }
120
                        return methods
121
                },
122
                "ToJSON": func(g interface{}) template.HTML {
123
                        data, _ := json.Marshal(g)
124
                        return template.HTML(string(data))
125
                },
126
                "underscore": func(html string) string {
127
                        return utils.UnderScoreString(html)
128
                },
129
                "URL": func() string {
130
                        return r.URL.String()
131
                },
132
                "CHART_DATA": func() string {
133
                        return ""
134
                },
135
                "Error": func() string {
136
                        return ""
137
                },
138
                "ToString": func(v interface{}) string {
139
                        return utils.ToString(v)
140
                },
141
                "Ago": func(t time.Time) string {
142
                        return utils.Timestamp(t).Ago()
143
                },
144
                "Duration": func(t time.Duration) string {
145
                        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", t.Seconds()))
146
                        return utils.FormatDuration(duration)
147
                },
148
                "ToUnix": func(t time.Time) int64 {
149
                        return t.UTC().Unix()
150
                },
151
                "FromUnix": func(t int64) string {
152
                        return utils.Timezoner(time.Unix(t, 0), core.CoreApp.Timezone).Format("Monday, January 02")
153
                },
154
                "NewService": func() *types.Service {
155
                        return new(types.Service)
156
                },
157
                "NewUser": func() *types.User {
158
                        return new(types.User)
159
                },
160
                "NewCheckin": func() *types.Checkin {
161
                        return new(types.Checkin)
162
                },
163
        }
164
}
-
func @138:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
138
func(v interface{}) string {
139
                        return utils.ToString(v)
140
                }
+
func @129:10
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
129
func() string {
130
                        return r.URL.String()
131
                }
func @93:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

93
func(html string) template.HTML {
94
                        return template.HTML(html)
95
                }
@@ -1215,12 +1245,12 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func @108:14
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

108
func() bool {
109
                        return core.CoreApp.UseCdn
110
                }
+
func @126:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
126
func(html string) string {
127
                        return utils.UnderScoreString(html)
128
                }
+
func @154:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

154
func() *types.Service {
155
                        return new(types.Service)
156
                }
-
func @129:10
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
129
func() string {
130
                        return r.URL.String()
131
                }
-
func saveSettingsHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/settings.go:

38
func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
39
        if !IsAuthenticated(r) {
40
                http.Redirect(w, r, "/", http.StatusSeeOther)
41
                return
42
        }
43
        r.ParseForm()
44
        app := core.CoreApp
45
        name := r.PostForm.Get("project")
46
        if name != "" {
47
                app.Name = name
48
        }
49
        description := r.PostForm.Get("description")
50
        if description != app.Description {
51
                app.Description = description
52
        }
53
        style := r.PostForm.Get("style")
54
        if style != app.Style {
55
                app.Style = style
56
        }
57
        footer := r.PostForm.Get("footer")
58
        if footer != app.Footer {
59
                app.Footer = footer
60
        }
61
        domain := r.PostForm.Get("domain")
62
        if domain != app.Domain {
63
                app.Domain = domain
64
        }
65
        timezone := r.PostForm.Get("timezone")
66
        timeFloat, _ := strconv.ParseFloat(timezone, 10)
67
        app.Timezone = float32(timeFloat)
68
69
        app.UseCdn = (r.PostForm.Get("enable_cdn") == "on")
70
        core.CoreApp, _ = core.UpdateCore(app)
71
        //notifiers.OnSettingsSaved(core.CoreApp.ToCore())
72
        executeResponse(w, r, "settings.html", core.CoreApp, "/settings")
73
}
@@ -1255,7 +1285,7 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 28
func setupHandler(w http.ResponseWriter, r *http.Request) {
29
        if core.CoreApp.Services != nil {
30
                http.Redirect(w, r, "/", http.StatusSeeOther)
31
                return
32
        }
33
        w.WriteHeader(http.StatusOK)
34
        port := 5432
35
        if os.Getenv("DB_CONN") == "mysql" {
36
                port = 3306
37
        }
38
        var data interface{}
39
        if os.Getenv("DB_CONN") != "" {
40
                data = &types.DbConfig{
41
                        DbConn:      os.Getenv("DB_CONN"),
42
                        DbHost:      os.Getenv("DB_HOST"),
43
                        DbUser:      os.Getenv("DB_USER"),
44
                        DbPass:      os.Getenv("DB_PASS"),
45
                        DbData:      os.Getenv("DB_DATABASE"),
46
                        DbPort:      port,
47
                        Project:     os.Getenv("NAME"),
48
                        Description: os.Getenv("DESCRIPTION"),
49
                        Email:       "",
50
                        Username:    "admin",
51
                        Password:    "",
52
                }
53
        }
54
        executeResponse(w, r, "setup.html", data, nil)
55
}
func executeResponse
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
166
func executeResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}, redirect interface{}) {
167
        utils.Http(r)
168
        if url, ok := redirect.(string); ok {
169
                http.Redirect(w, r, url, http.StatusSeeOther)
170
                return
171
        }
172
173
        templates := []string{"base.html", "head.html", "nav.html", "footer.html", "scripts.html", "form_service.html", "form_notifier.html", "form_user.html", "form_checkin.html"}
174
175
        javascripts := []string{"charts.js", "chart_index.js"}
176
177
        render, err := source.TmplBox.String(file)
178
        if err != nil {
179
                utils.Log(4, err)
180
        }
181
182
        // setup the main template and handler funcs
183
        t := template.New("main")
184
        t.Funcs(handlerFuncs(w, r))
185
        t, err = t.Parse(mainTmpl)
186
        if err != nil {
187
                utils.Log(4, err)
188
        }
189
190
        // render all templates
191
        for _, temp := range templates {
192
                tmp, _ := source.TmplBox.String(temp)
193
                t, err = t.Parse(tmp)
194
                if err != nil {
195
                        utils.Log(4, err)
196
                }
197
        }
198
199
        // render all javascript files
200
        for _, temp := range javascripts {
201
                tmp, _ := source.JsBox.String(temp)
202
                t, err = t.Parse(tmp)
203
                if err != nil {
204
                        utils.Log(4, err)
205
                }
206
        }
207
208
        // render the page requested
209
        _, err = t.Parse(render)
210
        if err != nil {
211
                utils.Log(4, err)
212
        }
213
214
        // execute the template
215
        err = t.Execute(w, data)
216
        if err != nil {
217
                utils.Log(4, err)
218
        }
219
}
+169
func executeResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}, redirect interface{}) {
170
        utils.Http(r)
171
        if url, ok := redirect.(string); ok {
172
                http.Redirect(w, r, url, http.StatusSeeOther)
173
                return
174
        }
175
176
        templates := []string{"base.html", "head.html", "nav.html", "footer.html", "scripts.html", "form_service.html", "form_notifier.html", "form_user.html", "form_checkin.html"}
177
178
        javascripts := []string{"charts.js", "chart_index.js"}
179
180
        render, err := source.TmplBox.String(file)
181
        if err != nil {
182
                utils.Log(4, err)
183
        }
184
185
        // setup the main template and handler funcs
186
        t := template.New("main")
187
        t.Funcs(handlerFuncs(w, r))
188
        t, err = t.Parse(mainTmpl)
189
        if err != nil {
190
                utils.Log(4, err)
191
        }
192
193
        // render all templates
194
        for _, temp := range templates {
195
                tmp, _ := source.TmplBox.String(temp)
196
                t, err = t.Parse(tmp)
197
                if err != nil {
198
                        utils.Log(4, err)
199
                }
200
        }
201
202
        // render all javascript files
203
        for _, temp := range javascripts {
204
                tmp, _ := source.JsBox.String(temp)
205
                t, err = t.Parse(tmp)
206
                if err != nil {
207
                        utils.Log(4, err)
208
                }
209
        }
210
211
        // render the page requested
212
        _, err = t.Parse(render)
213
        if err != nil {
214
                utils.Log(4, err)
215
        }
216
217
        // execute the template
218
        err = t.Execute(w, data)
219
        if err != nil {
220
                utils.Log(4, err)
221
        }
222
}
func servicesDeleteHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

124
func servicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
125
        if !IsAuthenticated(r) {
126
                http.Redirect(w, r, "/", http.StatusSeeOther)
127
                return
128
        }
129
        vars := mux.Vars(r)
130
        service := core.SelectService(utils.StringInt(vars["id"]))
131
        if service == nil {
132
                w.WriteHeader(http.StatusNotFound)
133
                return
134
        }
135
        service.Delete()
136
        executeResponse(w, r, "services.html", core.CoreApp.Services, "/services")
137
}
@@ -1264,10 +1294,10 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73 100
func usersDeleteHandler(w http.ResponseWriter, r *http.Request) {
101
        if !IsAuthenticated(r) {
102
                http.Redirect(w, r, "/", http.StatusSeeOther)
103
                return
104
        }
105
        vars := mux.Vars(r)
106
        id, _ := strconv.Atoi(vars["id"])
107
        user, _ := core.SelectUser(int64(id))
108
109
        users, _ := core.SelectAllUsers()
110
        if len(users) == 1 {
111
                utils.Log(2, "cannot delete the only user in the system")
112
                http.Redirect(w, r, "/users", http.StatusSeeOther)
113
                return
114
        }
115
        user.Delete()
116
        http.Redirect(w, r, "/users", http.StatusSeeOther)
117
}
func resetCookies
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/routes.go:

-
123
func resetCookies() {
124
        if core.CoreApp != nil {
125
                cookie := fmt.Sprintf("%v_%v", core.CoreApp.ApiSecret, time.Now().Nanosecond())
126
                sessionStore = sessions.NewCookieStore([]byte(cookie))
127
        } else {
128
                sessionStore = sessions.NewCookieStore([]byte("secretinfo"))
129
        }
130
}
+124
func resetCookies() {
125
        if core.CoreApp != nil {
126
                cookie := fmt.Sprintf("%v_%v", core.CoreApp.ApiSecret, time.Now().Nanosecond())
127
                sessionStore = sessions.NewCookieStore([]byte(cookie))
128
        } else {
129
                sessionStore = sessions.NewCookieStore([]byte("secretinfo"))
130
        }
131
}
func executeJSResponse
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
222
func executeJSResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}) {
223
        render, err := source.JsBox.String(file)
224
        if err != nil {
225
                utils.Log(4, err)
226
        }
227
        t := template.New("charts")
228
        t.Funcs(template.FuncMap{
229
                "safe": func(html string) template.HTML {
230
                        return template.HTML(html)
231
                },
232
                "Services": func() []types.ServiceInterface {
233
                        return core.CoreApp.Services
234
                },
235
        })
236
        _, err = t.Parse(render)
237
        if err != nil {
238
                utils.Log(4, err)
239
        }
240
241
        err = t.Execute(w, data)
242
        if err != nil {
243
                utils.Log(4, err)
244
        }
245
}
+225
func executeJSResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}) {
226
        render, err := source.JsBox.String(file)
227
        if err != nil {
228
                utils.Log(4, err)
229
        }
230
        t := template.New("charts")
231
        t.Funcs(template.FuncMap{
232
                "safe": func(html string) template.HTML {
233
                        return template.HTML(html)
234
                },
235
                "Services": func() []types.ServiceInterface {
236
                        return core.CoreApp.Services
237
                },
238
        })
239
        _, err = t.Parse(render)
240
        if err != nil {
241
                utils.Log(4, err)
242
        }
243
244
        err = t.Execute(w, data)
245
        if err != nil {
246
                utils.Log(4, err)
247
        }
248
}
func reorderServiceHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

65
func reorderServiceHandler(w http.ResponseWriter, r *http.Request) {
66
        if !IsAuthenticated(r) {
67
                http.Redirect(w, r, "/", http.StatusSeeOther)
68
                return
69
        }
70
        var newOrder []*serviceOrder
71
        decoder := json.NewDecoder(r.Body)
72
        decoder.Decode(&newOrder)
73
        for _, s := range newOrder {
74
                service := core.SelectService(s.Id)
75
                service.Order = s.Order
76
                service.Update(false)
77
        }
78
        w.WriteHeader(http.StatusOK)
79
}
@@ -1275,12 +1305,12 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func saveAssetsHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/settings.go:

92
func saveAssetsHandler(w http.ResponseWriter, r *http.Request) {
93
        if !IsAuthenticated(r) {
94
                http.Redirect(w, r, "/", http.StatusSeeOther)
95
                return
96
        }
97
        dir := utils.Directory
98
        err := source.CreateAllAssets(dir)
99
        if err != nil {
100
                utils.Log(3, err)
101
                return
102
        }
103
        err = source.CompileSASS(dir)
104
        if err != nil {
105
                source.CopyToPublic(source.CssBox, dir+"/assets/css", "base.css")
106
                utils.Log(2, "Default 'base.css' was insert because SASS did not work.")
107
        }
108
        resetRouter()
109
        executeResponse(w, r, "settings.html", core.CoreApp, "/settings")
110
}
-
func apiServiceUpdateHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

-
153
func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
154
        if !isAPIAuthorized(r) {
155
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
156
                return
157
        }
158
        vars := mux.Vars(r)
159
        service := core.SelectService(utils.StringInt(vars["id"]))
160
        if service == nil {
161
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
162
                return
163
        }
164
        var updatedService *types.Service
165
        decoder := json.NewDecoder(r.Body)
166
        decoder.Decode(&updatedService)
167
        updatedService.Id = service.Id
168
        service = core.ReturnService(updatedService)
169
        err := service.Update(true)
170
        if err != nil {
171
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
172
                return
173
        }
174
        service.Check(true)
175
        w.Header().Set("Content-Type", "application/json")
176
        json.NewEncoder(w).Encode(service)
177
}
-
func updateUserHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/users.go:

48
func updateUserHandler(w http.ResponseWriter, r *http.Request) {
49
        if !IsAuthenticated(r) {
50
                http.Redirect(w, r, "/", http.StatusSeeOther)
51
                return
52
        }
53
        r.ParseForm()
54
        vars := mux.Vars(r)
55
        id, _ := strconv.Atoi(vars["id"])
56
        user, err := core.SelectUser(int64(id))
57
        if err != nil {
58
                utils.Log(3, fmt.Sprintf("user error: %v", err))
59
                w.WriteHeader(http.StatusInternalServerError)
60
                return
61
        }
62
63
        user.Username = r.PostForm.Get("username")
64
        user.Email = r.PostForm.Get("email")
65
        user.Admin = (r.PostForm.Get("admin") == "on")
66
        password := r.PostForm.Get("password")
67
        if password != "##########" {
68
                user.Password = utils.HashPassword(password)
69
        }
70
        user.Update()
71
        users, _ := core.SelectAllUsers()
72
        executeResponse(w, r, "users.html", users, "/users")
73
}
+
func apiServiceUpdateHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

+
153
func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
154
        if !isAPIAuthorized(r) {
155
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
156
                return
157
        }
158
        vars := mux.Vars(r)
159
        service := core.SelectService(utils.StringInt(vars["id"]))
160
        if service == nil {
161
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
162
                return
163
        }
164
        var updatedService *types.Service
165
        decoder := json.NewDecoder(r.Body)
166
        decoder.Decode(&updatedService)
167
        updatedService.Id = service.Id
168
        service = core.ReturnService(updatedService)
169
        err := service.Update(true)
170
        if err != nil {
171
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
172
                return
173
        }
174
        service.Check(true)
175
        w.Header().Set("Content-Type", "application/json")
176
        json.NewEncoder(w).Encode(service)
177
}
+
func apiRenewHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

54
func apiRenewHandler(w http.ResponseWriter, r *http.Request) {
55
        if !isAPIAuthorized(r) {
56
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
57
                return
58
        }
59
        var err error
60
        core.CoreApp.ApiKey = utils.NewSHA1Hash(40)
61
        core.CoreApp.ApiSecret = utils.NewSHA1Hash(40)
62
        core.CoreApp, err = core.UpdateCore(core.CoreApp)
63
        if err != nil {
64
                utils.Log(3, err)
65
        }
66
        http.Redirect(w, r, "/settings", http.StatusSeeOther)
67
}
@@ -1302,18 +1332,18 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func apiCreateServiceHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

131
func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
132
        if !isAPIAuthorized(r) {
133
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
134
                return
135
        }
136
        var service *types.Service
137
        decoder := json.NewDecoder(r.Body)
138
        err := decoder.Decode(&service)
139
        if err != nil {
140
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
141
                return
142
        }
143
        newService := core.ReturnService(service)
144
        _, err = newService.Create(true)
145
        if err != nil {
146
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
147
                return
148
        }
149
        w.Header().Set("Content-Type", "application/json")
150
        json.NewEncoder(w).Encode(service)
151
}
-
func apiUserDeleteHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

-
261
func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
262
        if !isAPIAuthorized(r) {
263
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
264
                return
265
        }
266
        vars := mux.Vars(r)
267
        user, err := core.SelectUser(utils.StringInt(vars["id"]))
268
        if err != nil {
269
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
270
                return
271
        }
272
        err = user.Delete()
273
        if err != nil {
274
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
275
                return
276
        }
277
        output := apiResponse{
278
                Object: "user",
279
                Method: "delete",
280
                Id:     user.Id,
281
                Status: "success",
282
        }
283
        w.Header().Set("Content-Type", "application/json")
284
        json.NewEncoder(w).Encode(output)
285
}
-
func apiServiceDeleteHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

179
func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
180
        if !isAPIAuthorized(r) {
181
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
182
                return
183
        }
184
        vars := mux.Vars(r)
185
        service := core.SelectService(utils.StringInt(vars["id"]))
186
        if service == nil {
187
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
188
                return
189
        }
190
        err := service.Delete()
191
        if err != nil {
192
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
193
                return
194
        }
195
        output := apiResponse{
196
                Object: "service",
197
                Method: "delete",
198
                Id:     service.Id,
199
                Status: "success",
200
        }
201
        w.Header().Set("Content-Type", "application/json")
202
        json.NewEncoder(w).Encode(output)
203
}
-
func apiServiceHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

-
115
func apiServiceHandler(w http.ResponseWriter, r *http.Request) {
116
        if !isAPIAuthorized(r) {
117
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
118
                return
119
        }
120
        vars := mux.Vars(r)
121
        service := core.SelectService(utils.StringInt(vars["id"]))
122
        if service == nil {
123
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
124
                return
125
        }
126
127
        w.Header().Set("Content-Type", "application/json")
128
        json.NewEncoder(w).Encode(service)
129
}
+
func apiUserDeleteHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

+
261
func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
262
        if !isAPIAuthorized(r) {
263
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
264
                return
265
        }
266
        vars := mux.Vars(r)
267
        user, err := core.SelectUser(utils.StringInt(vars["id"]))
268
        if err != nil {
269
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
270
                return
271
        }
272
        err = user.Delete()
273
        if err != nil {
274
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
275
                return
276
        }
277
        output := apiResponse{
278
                Object: "user",
279
                Method: "delete",
280
                Id:     user.Id,
281
                Status: "success",
282
        }
283
        w.Header().Set("Content-Type", "application/json")
284
        json.NewEncoder(w).Encode(output)
285
}
func apiUserHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

221
func apiUserHandler(w http.ResponseWriter, r *http.Request) {
222
        if !isAPIAuthorized(r) {
223
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
224
                return
225
        }
226
        vars := mux.Vars(r)
227
        user, err := core.SelectUser(utils.StringInt(vars["id"]))
228
        if err != nil {
229
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
230
                return
231
        }
232
        w.Header().Set("Content-Type", "application/json")
233
        json.NewEncoder(w).Encode(user)
234
}
+
func apiServiceHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

+
115
func apiServiceHandler(w http.ResponseWriter, r *http.Request) {
116
        if !isAPIAuthorized(r) {
117
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
118
                return
119
        }
120
        vars := mux.Vars(r)
121
        service := core.SelectService(utils.StringInt(vars["id"]))
122
        if service == nil {
123
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
124
                return
125
        }
126
127
        w.Header().Set("Content-Type", "application/json")
128
        json.NewEncoder(w).Encode(service)
129
}
+
func dashboardHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/dashboard.go:

32
func dashboardHandler(w http.ResponseWriter, r *http.Request) {
33
        fmt.Println()
34
        if !IsAuthenticated(r) {
35
                err := core.ErrorResponse{}
36
                executeResponse(w, r, "login.html", err, nil)
37
        } else {
38
                executeResponse(w, r, "dashboard.html", core.CoreApp, nil)
39
        }
40
}
@@ -1329,21 +1359,24 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func DesktopInit
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/index.go:

38
func DesktopInit(ip string, port int) {
39
        var err error
40
        exists := utils.FileExists(utils.Directory + "/statup.db")
41
        if exists {
42
                core.Configs, err = core.LoadConfig(utils.Directory)
43
                if err != nil {
44
                        utils.Log(3, err)
45
                        return
46
                }
47
                err = core.Configs.Connect(false, utils.Directory)
48
                if err != nil {
49
                        utils.Log(3, err)
50
                        return
51
                }
52
                core.InitApp()
53
                RunHTTPServer(ip, port)
54
        }
55
56
        config := &core.DbConfig{
57
                DbConn:      "sqlite",
58
                Project:     "Statup",
59
                Description: "Statup running as an App!",
60
                Domain:      "http://localhost",
61
                Username:    "admin",
62
                Password:    "admin",
63
                Email:       "user@email.com",
64
                Error:       nil,
65
                Location:    utils.Directory,
66
        }
67
68
        config, err = config.Save()
69
        if err != nil {
70
                utils.Log(4, err)
71
        }
72
73
        config.DropDatabase()
74
        config.CreateDatabase()
75
        core.CoreApp = config.CreateCore()
76
77
        if err != nil {
78
                utils.Log(3, err)
79
                return
80
        }
81
82
        core.Configs, err = core.LoadConfig(utils.Directory)
83
        if err != nil {
84
                utils.Log(3, err)
85
                config.Error = err
86
                return
87
        }
88
89
        err = core.Configs.Connect(false, utils.Directory)
90
        if err != nil {
91
                utils.Log(3, err)
92
                core.DeleteConfig()
93
                config.Error = err
94
                return
95
        }
96
97
        admin := core.ReturnUser(&types.User{
98
                Username: config.Username,
99
                Password: config.Password,
100
                Email:    config.Email,
101
                Admin:    true,
102
        })
103
        admin.Create()
104
105
        core.InsertSampleData()
106
107
        config.ApiKey = core.CoreApp.ApiKey
108
        config.ApiSecret = core.CoreApp.ApiSecret
109
        config.Update()
110
111
        core.InitApp()
112
        RunHTTPServer(ip, port)
113
}
-
func checkinCreateUpdateHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

-
220
func checkinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) {
221
        if !IsAuthenticated(r) {
222
                http.Redirect(w, r, "/", http.StatusSeeOther)
223
                return
224
        }
225
        vars := mux.Vars(r)
226
        service := core.SelectService(utils.StringInt(vars["id"]))
227
        api := r.PostForm.Get("api")
228
        checkin := core.SelectCheckin(api)
229
230
        interval := utils.StringInt(r.PostForm.Get("interval"))
231
        grace := utils.StringInt(r.PostForm.Get("grace"))
232
        checkin.Interval = interval
233
        checkin.GracePeriod = grace
234
        checkin.Update()
235
        executeResponse(w, r, "service.html", service, fmt.Sprintf("/service/%v", service.Id))
236
}
+
func checkinCreateHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

+
233
func checkinCreateHandler(w http.ResponseWriter, r *http.Request) {
234
        if !IsAuthenticated(r) {
235
                http.Redirect(w, r, "/", http.StatusSeeOther)
236
                return
237
        }
238
        vars := mux.Vars(r)
239
        r.ParseForm()
240
        service := core.SelectService(utils.StringInt(vars["id"]))
241
        fmt.Println(service.Name)
242
        name := r.PostForm.Get("name")
243
        interval := utils.StringInt(r.PostForm.Get("interval"))
244
        grace := utils.StringInt(r.PostForm.Get("grace"))
245
        checkin := core.ReturnCheckin(&types.Checkin{
246
                Name:        name,
247
                ServiceId:   service.Id,
248
                Interval:    interval,
249
                GracePeriod: grace,
250
        })
251
        checkin.Create()
252
        executeResponse(w, r, "service.html", service, fmt.Sprintf("/service/%v", service.Id))
253
}
func apiServicePingDataHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

98
func apiServicePingDataHandler(w http.ResponseWriter, r *http.Request) {
99
        vars := mux.Vars(r)
100
        service := core.SelectService(utils.StringInt(vars["id"]))
101
        if service == nil {
102
                http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
103
                return
104
        }
105
        fields := parseGet(r)
106
        grouping := fields.Get("group")
107
        startField := utils.StringInt(fields.Get("start"))
108
        endField := utils.StringInt(fields.Get("end"))
109
        obj := core.GraphDataRaw(service, time.Unix(startField, 0), time.Unix(endField, 0), grouping, "ping_time")
110
111
        w.Header().Set("Content-Type", "application/json")
112
        json.NewEncoder(w).Encode(obj)
113
}
+
func checkinHitHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

+
255
func checkinHitHandler(w http.ResponseWriter, r *http.Request) {
256
        vars := mux.Vars(r)
257
        checkin := core.SelectCheckin(vars["id"])
258
        ip, _, _ := net.SplitHostPort(r.RemoteAddr)
259
        checkinHit := core.ReturnCheckinHit(&types.CheckinHit{
260
                Checkin:   checkin.Id,
261
                From:      ip,
262
                CreatedAt: time.Now().UTC(),
263
        })
264
        if checkin.Last() == nil {
265
                checkin.Start()
266
                go checkin.Routine()
267
        }
268
        checkinHit.Create()
269
        w.Write([]byte("ok"))
270
        w.WriteHeader(http.StatusOK)
271
}
+ +
func checkinDeleteHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

+
220
func checkinDeleteHandler(w http.ResponseWriter, r *http.Request) {
221
        if !IsAuthenticated(r) {
222
                http.Redirect(w, r, "/", http.StatusSeeOther)
223
                return
224
        }
225
        vars := mux.Vars(r)
226
        checkin := core.SelectCheckinId(utils.StringInt(vars["id"]))
227
        service := core.SelectService(checkin.ServiceId)
228
        fmt.Println(checkin, service)
229
        checkin.Delete()
230
        executeResponse(w, r, "service.html", service, fmt.Sprintf("/service/%v", service.Id))
231
}
+
func pluginSavedHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/plugins.go:

29
func pluginSavedHandler(w http.ResponseWriter, r *http.Request) {
30
        auth := IsAuthenticated(r)
31
        if !auth {
32
                http.Redirect(w, r, "/", http.StatusSeeOther)
33
                return
34
        }
35
        r.ParseForm()
36
        //vars := mux.Vars(router)
37
        //plug := SelectPlugin(vars["name"])
38
        data := make(map[string]string)
39
        for k, v := range r.PostForm {
40
                data[k] = strings.Join(v, "")
41
        }
42
        //plug.OnSave(structs.Map(data))
43
        http.Redirect(w, r, "/settings", http.StatusSeeOther)
44
}
func @111:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

111
func(g interface{}) []string {
112
                        fooType := reflect.TypeOf(g)
113
                        var methods []string
114
                        methods = append(methods, fooType.String())
115
                        for i := 0; i < fooType.NumMethod(); i++ {
116
                                method := fooType.Method(i)
117
                                fmt.Println(method.Name)
118
                                methods = append(methods, method.Name)
119
                        }
120
                        return methods
121
                }
-
func checkinUpdateHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/services.go:

-
238
func checkinUpdateHandler(w http.ResponseWriter, r *http.Request) {
239
        vars := mux.Vars(r)
240
        checkin := core.SelectCheckin(vars["id"])
241
        ip, _, _ := net.SplitHostPort(r.RemoteAddr)
242
        checkinHit := core.ReturnCheckinHit(&types.CheckinHit{
243
                Checkin:   checkin.Id,
244
                From:      ip,
245
                CreatedAt: time.Now().UTC(),
246
        })
247
        checkinHit.Create()
248
        w.Write([]byte("ok"))
249
        w.WriteHeader(http.StatusOK)
250
}
-
func apiCheckinHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/api.go:

69
func apiCheckinHandler(w http.ResponseWriter, r *http.Request) {
70
        if !isAPIAuthorized(r) {
71
                http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
72
                return
73
        }
74
        vars := mux.Vars(r)
75
        checkin := core.SelectCheckin(vars["api"])
76
        //checkin.Receivehit()
77
        w.WriteHeader(http.StatusOK)
78
        json.NewEncoder(w).Encode(checkin)
79
}
@@ -1353,14 +1386,14 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func parseId
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/settings.go:

122
func parseId(r *http.Request) int64 {
123
        vars := mux.Vars(r)
124
        return utils.StringInt(vars["id"])
125
}
-
func @144:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
144
func(t time.Duration) string {
145
                        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", t.Seconds()))
146
                        return utils.FormatDuration(duration)
147
                }
-
func @122:13
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

122
func(g interface{}) template.HTML {
123
                        data, _ := json.Marshal(g)
124
                        return template.HTML(string(data))
125
                }
-
func trayHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/index.go:

-
33
func trayHandler(w http.ResponseWriter, r *http.Request) {
34
        executeResponse(w, r, "tray.html", core.CoreApp, nil)
35
}
+
func @144:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
144
func(t time.Duration) string {
145
                        duration, _ := time.ParseDuration(fmt.Sprintf("%vs", t.Seconds()))
146
                        return utils.FormatDuration(duration)
147
                }
+ +
func @90:9
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
90
func(html interface{}) template.JS {
91
                        return template.JS(utils.ToString(html))
92
                }
func @148:13
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

148
func(t time.Time) int64 {
149
                        return t.UTC().Unix()
150
                }
@@ -1368,26 +1401,29 @@ PACKAGE:github.com/hunterlong/statup/core/notifier DONE:72.73
func @132:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

132
func() string {
133
                        return ""
134
                }
-
func @232:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
232
func() []types.ServiceInterface {
233
                        return core.CoreApp.Services
234
                }
-
func setupResponseError
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/setup.go:

152
func setupResponseError(w http.ResponseWriter, r *http.Request, a interface{}) {
153
        executeResponse(w, r, "setup.html", a, nil)
154
}
+
func @235:15
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
235
func() []types.ServiceInterface {
236
                        return core.CoreApp.Services
237
                }
+ +
func @160:17
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
160
func() *types.Checkin {
161
                        return new(types.Checkin)
162
                }
+
func @141:10
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

141
func(t time.Time) string {
142
                        return utils.Timestamp(t).Ago()
143
                }
-
func @90:9
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
90
func(html interface{}) template.JS {
91
                        return template.JS(utils.ToString(html))
92
                }
+
func trayHandler
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/index.go:

+
33
func trayHandler(w http.ResponseWriter, r *http.Request) {
34
        executeResponse(w, r, "tray.html", core.CoreApp, nil)
35
}
-
func @229:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

-
229
func(html string) template.HTML {
230
                        return template.HTML(html)
231
                }
+
func @232:11
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/handlers/handlers.go:

+
232
func(html string) template.HTML {
233
                        return template.HTML(html)
234
                }
-
Package Overview: github.com/hunterlong/statup/notifiers 7.03%

This is a coverage report created after analysis of the github.com/hunterlong/statup/notifiers package. It +

Package Overview: github.com/hunterlong/statup/notifiers 7.00%

This is a coverage report created after analysis of the github.com/hunterlong/statup/notifiers package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/notifiers | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

@@ -1409,8 +1445,8 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52 + - @@ -1438,7 +1474,7 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52 - +
twilio.Select(...)github.com/hunterlong/statup/notifiers/twilio.go100.00%1/1
lineNotifier.Select(...)github.com/hunterlong/statup/notifiers/line_notify.go100.00%1/1
emailTemplate(...)github.com/hunterlong/statup/notifiers/email.go0.00%0/9
webhooker.OnTest(...)github.com/hunterlong/statup/notifiers/webhook.go0.00%0/9
slack.OnTest(...)github.com/hunterlong/statup/notifiers/slack.go0.00%0/9
email.OnTest(...)github.com/hunterlong/statup/notifiers/email.go0.00%0/8
discord.Send(...)github.com/hunterlong/statup/notifiers/discord.go0.00%0/8
email.OnTest(...)github.com/hunterlong/statup/notifiers/email.go0.00%0/7
replaceBodyText(...)github.com/hunterlong/statup/notifiers/webhook.go0.00%0/7
slack.Send(...)github.com/hunterlong/statup/notifiers/slack.go0.00%0/7
parseSlackMessage(...)github.com/hunterlong/statup/notifiers/slack.go0.00%0/7
email.OnSave(...)github.com/hunterlong/statup/notifiers/email.go0.00%0/2
twilio.OnSave(...)github.com/hunterlong/statup/notifiers/twilio.go0.00%0/2
webhooker.OnSave(...)github.com/hunterlong/statup/notifiers/webhook.go0.00%0/1
github.com/hunterlong/statup/notifiers7.03%18/256
github.com/hunterlong/statup/notifiers7.00%18/257
func twilio.Select
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/twilio.go:

@@ -1490,10 +1526,10 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52
59
func (u *lineNotifier) Send(msg interface{}) error {
60
        message := msg.(string)
61
        client := new(http.Client)
62
        v := url.Values{}
63
        v.Set("message", message)
64
        req, err := http.NewRequest("POST", "https://notify-api.line.me/api/notify", strings.NewReader(v.Encode()))
65
        if err != nil {
66
                return err
67
        }
68
        req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", u.GetValue("api_secret")))
69
        req.Header.Add("Accept", "application/json")
70
        req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
71
        _, err = client.Do(req)
72
        if err != nil {
73
                return err
74
        }
75
        return nil
76
}
func email.dialSend
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

-
232
func (u *email) dialSend(email *emailOutgoing) error {
233
        mailer = mail.NewDialer(emailer.Host, emailer.Port, emailer.Username, emailer.Password)
234
        mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
235
        emailSource(email)
236
        m := mail.NewMessage()
237
        m.SetHeader("From", email.From)
238
        m.SetHeader("To", email.To)
239
        m.SetHeader("Subject", email.Subject)
240
        m.SetBody("text/html", email.Source)
241
        if err := mailer.DialAndSend(m); err != nil {
242
                utils.Log(3, fmt.Sprintf("email '%v' sent to: %v using the %v template (size: %v) %v", email.Subject, email.To, email.Template, len([]byte(email.Source)), err))
243
                return err
244
        }
245
        return nil
246
}
+233
func (u *email) dialSend(email *emailOutgoing) error {
234
        mailer = mail.NewDialer(emailer.Host, emailer.Port, emailer.Username, emailer.Password)
235
        mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
236
        emailSource(email)
237
        m := mail.NewMessage()
238
        m.SetHeader("From", email.From)
239
        m.SetHeader("To", email.To)
240
        m.SetHeader("Subject", email.Subject)
241
        m.SetBody("text/html", email.Source)
242
        if err := mailer.DialAndSend(m); err != nil {
243
                utils.Log(3, fmt.Sprintf("email '%v' sent to: %v using the %v template (size: %v) %v", email.Subject, email.To, email.Template, len([]byte(email.Source)), err))
244
                return err
245
        }
246
        return nil
247
}
func emailTemplate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

-
253
func emailTemplate(contents string, data interface{}) string {
254
        t := template.New("email")
255
        t, err := t.Parse(contents)
256
        if err != nil {
257
                utils.Log(3, err)
258
        }
259
        var tpl bytes.Buffer
260
        if err := t.Execute(&tpl, data); err != nil {
261
                utils.Log(2, err)
262
        }
263
        result := tpl.String()
264
        return result
265
}
+254
func emailTemplate(contents string, data interface{}) string {
255
        t := template.New("email")
256
        t, err := t.Parse(contents)
257
        if err != nil {
258
                utils.Log(3, err)
259
        }
260
        var tpl bytes.Buffer
261
        if err := t.Execute(&tpl, data); err != nil {
262
                utils.Log(2, err)
263
        }
264
        result := tpl.String()
265
        return result
266
}
func webhooker.OnTest
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/webhook.go:

143
func (w *webhooker) OnTest() error {
144
        service := &types.Service{
145
                Id:             1,
146
                Name:           "Interpol - All The Rage Back Home",
147
                Domain:         "https://www.youtube.com/watch?v=-u6DvRyyKGU",
148
                ExpectedStatus: 200,
149
                Interval:       30,
150
                Type:           "http",
151
                Method:         "GET",
152
                Timeout:        20,
153
                LastStatusCode: 404,
154
                Expected:       "test example",
155
                LastResponse:   "<html>this is an example response</html>",
156
                CreatedAt:      time.Now().Add(-24 * time.Hour),
157
        }
158
        body := replaceBodyText(w.Var2, service, nil)
159
        resp, err := w.run(body)
160
        if err != nil {
161
                return err
162
        }
163
        defer resp.Body.Close()
164
        content, err := ioutil.ReadAll(resp.Body)
165
        utils.Log(1, fmt.Sprintf("webhook notifier received: '%v'", string(content)))
166
        return err
167
}
@@ -1501,12 +1537,12 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52
func slack.OnTest
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/slack.go:

101
func (u *slack) OnTest() error {
102
        client := new(http.Client)
103
        res, err := client.Post(u.Host, "application/json", bytes.NewBuffer([]byte(`{"text":"testing message"}`)))
104
        if err != nil {
105
                return err
106
        }
107
        defer res.Body.Close()
108
        contents, _ := ioutil.ReadAll(res.Body)
109
        if string(contents) != "ok" {
110
                return errors.New("The slack response was incorrect, check the URL")
111
        }
112
        return err
113
}
+
func email.OnTest
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

+
221
func (u *email) OnTest() error {
222
        host := fmt.Sprintf("%v:%v", u.Host, u.Port)
223
        dial, err := smtp.Dial(host)
224
        dial.StartTLS(&tls.Config{InsecureSkipVerify: true})
225
        if err != nil {
226
                utils.Log(3, err)
227
                return err
228
        }
229
        auth := smtp.PlainAuth("", u.Username, u.Password, host)
230
        return dial.Auth(auth)
231
}
+
func discord.Send
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/discord.go:

59
func (u *discord) Send(msg interface{}) error {
60
        message := msg.(string)
61
        req, _ := http.NewRequest("POST", discorder.GetValue("host"), bytes.NewBuffer([]byte(message)))
62
        req.Header.Set("Content-Type", "application/json")
63
        client := &http.Client{}
64
        resp, err := client.Do(req)
65
        if err != nil {
66
                return err
67
        }
68
        return resp.Body.Close()
69
}
-
func email.OnTest
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

-
221
func (u *email) OnTest() error {
222
        host := fmt.Sprintf("%v:%v", u.Host, u.Port)
223
        dial, err := smtp.Dial(host)
224
        if err != nil {
225
                utils.Log(3, err)
226
                return err
227
        }
228
        auth := smtp.PlainAuth("", u.Username, u.Password, host)
229
        return dial.Auth(auth)
230
}
-
func replaceBodyText
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/webhook.go:

101
func replaceBodyText(body string, s *types.Service, f *types.Failure) string {
102
        if s != nil {
103
                body = strings.Replace(body, "%service.Name", s.Name, -1)
104
                body = strings.Replace(body, "%service.Id", utils.ToString(s.Id), -1)
105
                body = strings.Replace(body, "%service.Online", utils.ToString(s.Online), -1)
106
        }
107
        if f != nil {
108
                body = strings.Replace(body, "%failure.Issue", f.Issue, -1)
109
        }
110
        return body
111
}
@@ -1577,7 +1613,7 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52 99
func (u *lineNotifier) OnSave() error {
100
        utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
101
        // Do updating stuff here
102
        return nil
103
}
func emailSource
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

-
248
func emailSource(email *emailOutgoing) {
249
        source := emailTemplate(email.Template, email.Data)
250
        email.Source = source
251
}
+249
func emailSource(email *emailOutgoing) {
250
        source := emailTemplate(email.Template, email.Data)
251
        email.Source = source
252
}
func email.OnSave
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/notifiers/email.go:

214
func (u *email) OnSave() error {
215
        utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
216
        // Do updating stuff here
217
        return nil
218
}
@@ -1589,32 +1625,36 @@ PACKAGE:github.com/hunterlong/statup/handlers DONE:68.52 186
func (w *webhooker) OnSave() error {
187
        return nil
188
}
-
Package Overview: github.com/hunterlong/statup/plugin 33.33%

This is a coverage report created after analysis of the github.com/hunterlong/statup/plugin package. It +

Package Overview: github.com/hunterlong/statup/plugin 25.58%

This is a coverage report created after analysis of the github.com/hunterlong/statup/plugin package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/plugin | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

+ - + - +
init(...)github.com/hunterlong/statup/plugin/main.go100.00%2/2
Add(...)github.com/hunterlong/statup/plugin/main.go100.00%1/1
SetDatabase(...)github.com/hunterlong/statup/plugin/main.go0.00%0/1
LoadPlugins(...)github.com/hunterlong/statup/plugin/main.go20.51%8/39
PluginInfo.Form(...)github.com/hunterlong/statup/plugin/main.go0.00%0/1
PluginObject.AddRoute(...)github.com/hunterlong/statup/plugin/main.go0.00%0/0
github.com/hunterlong/statup/plugin33.33%1/3
github.com/hunterlong/statup/plugin25.58%11/43
-
func Add
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

-
42
func Add(p Pluginer) *PluginObject {
43
        return &PluginObject{}
44
}
+
func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

+
48
func init() {
49
        utils.InitLogs()
50
        dir = utils.Directory
51
}
-
func SetDatabase
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

-
107
func SetDatabase(database *gorm.DB) {
108
        DB = database
109
}
+
func Add
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

+
53
func Add(p Pluginer) *PluginObject {
54
        return &PluginObject{}
55
}
+ +
func LoadPlugins
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

+
65
func LoadPlugins(debug bool) {
66
        pluginDir := dir + "/plugins"
67
        utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
68
        if _, err := os.Stat(pluginDir); os.IsNotExist(err) {
69
                os.Mkdir(pluginDir, os.ModePerm)
70
        }
71
72
        //ForEachPlugin()
73
        files, err := ioutil.ReadDir(pluginDir)
74
        if err != nil {
75
                utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
76
                return
77
        }
78
        for _, f := range files {
79
                utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
80
                ext := strings.Split(f.Name(), ".")
81
                if len(ext) != 2 {
82
                        utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
83
                        continue
84
                }
85
                if ext[1] != "so" {
86
                        utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
87
                        continue
88
                }
89
                plug, err := plugin.Open("plugins/" + f.Name())
90
                if err != nil {
91
                        utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
92
                        continue
93
                }
94
                symPlugin, err := plug.Lookup("Plugin")
95
                if err != nil {
96
                        utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
97
                        continue
98
                }
99
100
                if debug {
101
                        utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
102
                        utils.Log(1, structs.Map(symPlugin))
103
                }
104
105
                var plugActions types.PluginActions
106
                plugActions, ok := symPlugin.(types.PluginActions)
107
                if !ok {
108
                        utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
109
                        if debug {
110
                                //fmt.Println(symPlugin.(plugin.PluginActions))
111
                        }
112
                        continue
113
                }
114
115
                plugActions.OnLoad(*core.DbSession)
116
                core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
117
                core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
118
        }
119
        if !debug {
120
                utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
121
        }
122
}
func PluginInfo.Form
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

-
111
func (p *PluginInfo) Form() string {
112
        return "okkokokkok"
113
}
+61
func (p *PluginInfo) Form() string {
62
        return "okkokokkok"
63
}
func PluginObject.AddRoute
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/plugin/main.go:

-
46
func (p *PluginObject) AddRoute(s string, i string, f http.HandlerFunc) {
47
48
}
+57
func (p *PluginObject) AddRoute(s string, i string, f http.HandlerFunc) {
58
59
}
Package Overview: github.com/hunterlong/statup/source 77.71%

This is a coverage report created after analysis of the github.com/hunterlong/statup/source package. It @@ -1640,7 +1680,7 @@ PACKAGE:github.com/hunterlong/statup/plugin DONE:33.33

func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/source/rice-box.go:

-
204
func init() {
205
206
        // define files
207
        filel := &embedded.EmbeddedFile{
208
                Filename:    "base.html",
209
                FileModTime: time.Unix(1538458071, 0),
210
                Content:     string("{{ define \"base\" }}\n<!doctype html>\n<html lang=\"en\">\n{{block \"head\" .}} {{end}}\n<body>\n    {{template \"content\" .}}\n</body>\n<footer>{{template \"footer\" .}}</footer>\n{{template \"scripts\" .}}\n</html>\n{{end}}\n"),
211
        }
212
        filem := &embedded.EmbeddedFile{
213
                Filename:    "dashboard.html",
214
                FileModTime: time.Unix(1538459427, 0),
215
                Content:     string("{{define \"title\"}}Statup | Dashboard{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\" }}\n    <div class=\"col-12 mt-3\">\n        <div class=\"row stats_area mb-5\">\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.ServicesCount }}</span>\n                Total Services\n            </div>\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.Count24HFailures }}</span>\n                Failures last 24 Hours\n            </div>\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.CountOnline }}</span>\n                Online Services\n            </div>\n        </div>\n        <div class=\"row mt-4\">\n            <div class=\"col-12\">\n                <h3>Services</h3>\n                <div class=\"list-group mb-5 mt-3\">\n                {{ range Services }}\n                    <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                        <div class=\"d-flex w-100 justify-content-between\">\n                            <h5 class=\"mb-1\">{{.Name}}</h5>\n                            <small>{{if .Online}} <span class=\"badge badge-success\">ONLINE</span> {{else}} <span class=\"badge badge-danger\">OFFLINE</span> {{end}}</small>\n                        </div>\n                        <p class=\"mb-1\">{{.SmallText}}</p>\n                    </a>\n                {{ end }}\n                </div>\n\n            {{ range Services }}\n            {{ if .LimitedFailures }}\n                <h4 class=\"text-truncate\">{{.Name}} Failures</h4>\n                <div class=\"list-group mt-3 mb-4\">\n                {{ range .LimitedFailures }}\n                    <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                        <div class=\"d-flex w-100 justify-content-between\">\n                            <h5 class=\"mb-1\">{{.ParseError}}</h5>\n                            <small>{{.Ago}}</small>\n                        </div>\n                        <p class=\"mb-1\">{{.Issue}}</p>\n                    </a>\n                {{ end }}\n                </div>\n            {{ end }}\n            {{ end }}\n\n\n            </div>\n        </div>\n    </div>\n</div>\n{{end}}\n"),
216
        }
217
        filen := &embedded.EmbeddedFile{
218
                Filename:    "error_404.html",
219
                FileModTime: time.Unix(1538457906, 0),
220
                Content:     string("{{define \"title\"}}Statup Page Not Found{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-12 mt-3\">\n        <div class=\"alert alert-danger\" role=\"alert\">\n            Sorry, this page doesn't seem to exist.\n        </div>\n    </div>\n</div>\n{{end}}\n"),
221
        }
222
        fileo := &embedded.EmbeddedFile{
223
                Filename:    "favicon.ico",
224
                FileModTime: time.Unix(1530546686, 0),
225
                Content:     string("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00@\x00\x00\x00@\b\x06\x00\x00\x00\xaaiq\xde\x00\x00\v\x92IDATx\x9c\xed\x9ak\x8c]Wu\xc7\u007fk\xed3w\xc6\xf3\xcexb\x1c)\t\x89\x89\xa8\t\xe6!C\xa3\xc8T\xd8q\x1d\x9a\x84\x14\xd1\b\x10\xad\xd4\x12\xb5\xa9P\x15\x12\xd3Z\x15TBB\x15\x1f\xe8\a\xaa\xe0\x98\xb4*\x16n\xfb\xa1T\x05җ҄\x94ď@R\nI_\xaa\"\xd7\x19\x9c4$\xe0Lf\xfc\x18\xcf\xe3νg\xaf\xd5\x0f\xe7\xee9\xe7\x9a\xca\xe9=3\xa6\xa8\x9d\xbfd\xcd\xf8\xdes\xd6\xde\xeb?k\xaf\xbd\xd6\u007foX\xc7:ֱ\x8eu\xac\xe3\xff-\xe4R\x0f\xf0\x86\u007f\x19gff\xeez\x11\xb9!\x04\xdeb\xe6W\xbb\xfb\xa6\x10t\xd0\xddUU\x9af,\xaa\xca)w^t\xb7\xe7@\x9f\x0e\xc1\x9e}\xf5\xddf\x97z~\x97\x84\x80\x81\xbf\x83\x91\x91\xb0Ý_\x8e\xd1\xdf\x0fl\x16\x01\x11\x05\fw\x10\x11D\x84\x18\rUp\aU!\xcf\x1dU\x018\v<\f<\xb8\xbc\xec\x0f-\xdcb\xadK1\xd75'`\xec1\xb9-\x04\xf9\x8c\x88l7s\n\xc7\x05w/\x06\x14A\xa4pجpֽ\xf8\x19\xa3\x93e\x82\x99\xe3^<g愠/\xb9\xfb\x01\x11\xff\xc2\xccN[\\\xcb\xf9\xae\x19\x01\x93\xc7t،\x83\xaa\xfaaw\xa7\xf0\xd7W\x9c\x17QD\x9c\x18\x8bϒ\xe3\xe9YU\xc1\xcd\xe1\x02\xc2\x121\xaa\x82\b/\xba\xf3볻\xe2߯ռׄ\x80\x8dG\xc3f3\xff\x06\xb0\r\x04\x91\xc2Ʉ\x14\t@\x85\x90\xee\xa8\x00V\xc8\bA\xc8s#\x04튒\xc26\x06\xfe\x89\xd9]\xf6\xb9\xb5\x98\xfb\xaa\t\x988\"\xa3\xaa\xe1Iw\xdf\xd6\xf1\a\x91\x14\x01e\xb8\x83\xaf\xbc\xa3\xaa]\xa4T\x89\xb0hhЕg\xdd\x1cQ\xadDDa\xcf\xdd\xef>}\x93\xfd\xc1j篯\xfd\xc8kA\x0e\xba\xfb\xb6\x18\x9d\"\xe4\x93äd\x86j\xf1\xbb H\x14l\xc9\xf0%\xc7\xe6\x1d_\x04\x96\x81\b\xe0\x1d\xe7\v\x03f\x8e(\xb8[\xc7\x06\xc4\xe8)\x89\xde7y,\xbb~\xb5\xb3\xcfV\xf3\xf2\xc4\x11\xbd͝\x0f\x81w&\xa8\xb8\x17;WJrn\x0e\x8b\x82\x9dwdA\x88MC\\P\x8adg\xe6H\x00\xed\x13\x18pd\xd4\xd1\x11\xa0Q,\x85\xb4\xfe\xcb\xe8\x12\n\x82\xa4a\xe6\a\x80\x9f]\x8d\x0f\xb5\x97\xc0\xa6o\x06b\xe4\x19w\xdf^]\xef\xe5\xfa\x06o9\xfeC!N;~\x8e\xdcs\x9e\x15\x93g\x89\x9cr\xf3y\\\x16\xdc=C٨\r\xb6H\x9f\xdc\xe0\xfd\xbeY& \\\x01ac\x99\x1b\xca\xe9zW\xceP\x95\x9f\x9e\xd9\x19\x9f\xae\xebG\xed\b\xc8snHΧDU\x9d\x1c9ؔ\xd0\xfe\xbeOiS>\xdb^\xb6\xbf\\\xfeC?{1\x9bW|jT\xcfN\x9f\xbf1\x9b\xd7}\xf1<wp\xad\xa3\xaf\x832\x978\xa1\x93\x1fR\x84\x89\xc8G\x81\xda\x04Ԏ\x80\x89#\xfa\x19U\xf9T\xda\xe2ܽ+c\xe7ρMɟ\xd8R\xfc\x8d\xc5\x034{\xb5?\xb8Wo\xd7I\xfe,\xbc\x99Q\x1d\xa7\xb3#XW\x01\x15\x82`\xe6\xd3ͦ]\xb1x+\xb5\xaa\xc6\xfaI\xd0y\xa7Y\xb15%\xe7W\xfe\xfam!\xfe'_c\xd9~\xad\x8e\xf3\x00\x8b\xfb\xed!='\xb7\xda\U000f4534\xee\v\x98\x19\xaa\xa9`b\xd3\xc0\x80\xbe\xb5\xae\x1b\xb5\t\x10\x917v\x19R]\xd9\xd6X\xa4is~\xf7\xfc~_U-?\xf7\xb9\xf8\x14\xb3\xf2i;\xeb\x95$\xd8]Mv\x8a\xaaw\xd6\x1d\xa36\x01\x16}2msE\x92\xaaD\xc1\b'\x96\x0e\xf8t]\xdbU\xc8R\xf6\xf98\xe3\xd3\ue38a\xe0m\xf0&\xe4s\x8e\x9e\x17|\xd6\xf1i\xa9\x9d\xcb\xeaG\x80\xc9p\n\xfd\xea\xbeo\xe6\xb8\xf8\xb6\xb1Ǻ#\xa4.\xe6\xee[n\xb2(_\xb1\xef\v\xed\x13N<\x01\xf19\x88\xff\x01\xf9\xb3\xd0\xfaWh\xfes\xfd@\xab͜\xb7ܤ!Z\x84\xa4w\xd6e\xc1\xa7\b\x1a\x82|i\xec1n>\xb7\xc7k\xe5\x80*\xe2)9\x12_\xf1;1Nb~\x92\\\xa6<\xe7{&\x9c\xcc\xdb~\xb2\u007f@_\xa8k\xbb\xf6.0\xf6U\xfda\xdf&ٜ\x12\xa1H\x99\x10)\x93\xd6S\xaa\xfa\x91\x99\x9d\xf9T\xddq\x00\x86\xf7\x065\x8b\xb6x`5V\xfe{\xd4&`\xfc\x90>\xa9\xd7ʎ\xb4?\v\x82h\x91\x94R##\x021ZKD\xbel\xc6_\x80\x1d>\xb3\xdb/I__\x17\xf5\x93\xe0\f\xdf\xf1\x96w\x1a\x13\xb0N'\x97j\x013'FÝ\x86\x88\xdc\t\xfe\x88\xaa\xbe:y,{p\xe3\xd1p\xd7ƣ\xe1\xea5\xf4\xa36jG\xc0\xd0o\xeb\x8e\xec-<\x19\xae\xaaV\x82\x1d\xa3\x9dv\xb8\xf8\xfcG;\xbfJ+|\x1c\xf8z\x9e\xfb\xa3\xfd\xfd}O\xbc\xfa\xee֚\x8a\x1d\xff\x13\xd4'\xe0^T^\xa7\xcf\xf4\xbd\x8d\xb73HE\xe0(\xbeO\xff/\x9dMy\x02̊F'EO\xa7\xa6o\xba\xfb\xb7@\x1e\rA\x1e\nA\x8e\x9fzW{-|\xbc(V\xa5\a\f\xed\xd3[\xb2k\xe5\x11\xbdΡ\xd1MB\x8a\b\x8b\xa9\xa5M\xe5l\xec\xa8Ct%\xcc\xd4@%\xb8\xfbT\b\xf2\x90\x88<\xe8nO]*\x81tՂ\xc8\xd0'\xc2\xc1\xf0z\xbf\xab\xefZ\x85\r\x85\a\xd5\xee-\xe9}E\xd5FWEW\n%\x82j\x91?\xd2;\xd5g\x81\x1f\xa8\xcaWD\xf8\xd2\xcc\xce\xf8\ufadds\x15\xab&`|_\u007f#\xcf\xda\u007f\xc5f\xbf-\xbbJ\xd0\xcb\x04\x94ʚ/\x15\xa2\xa2\x89)\xf3Ez&\xe9~\xd5ϊ(*\x96K\xf1\xcc\xca\xefG\xf3<~z\xeef\x9eX\xed\xdca\x8d4\xc1\xa1{\xa5a\x81\xcf\xf6]\xae\xbfŤ\xa1\x1b\x05\x19\x06\xfa\xca\xeaP\xb5\x9b\x80\xaa\xe8ٵd\xec\xc2(J\xd3,e\xb3N\xde8$\x12\xf6\x9e\xbe\xa9=\xbf\x9a\xb9\xaf\xa9,\xbe\xe1c\xb2+\x1b\xd1\xdf\xf7!߮\x97\x81\x8c\x03CN6\xac+5gW\xd7\b\x95\xa6\xa6\x9a\x13\xa0\xaa('hG\x1bL\x89S\x84\xa7ݹ\xf5\xccn\x9b\xa9;\xe75?\x17\x90\xbb\xd0\xc1\xc1\xb0\x9b\x86\xdf\x1d\x06\xf5\xb68\x18\x1b:\x02:&\x84\x11\xc1\xfb\x9d\xb0\xa1\x94\xca\xd3_<EE\xe7\x1c\xa0\xd3cx\xea\xf9\xbbT \x11%\xc6H\x96\x05\xdc\xfd;ͦ\xef\\\xb8\xc5j\x95ܗ\xf4hlxo\x98p\xfc\x0e\xe9烞\xb1+\x8cJC\x86\x81\r\x8e\x8c\x00\x03\x10\x06\x05\x0f\xdd\x11\xb0R]J\x99+RM\x01t\x91\xe3\xee\xe49\xf7\x9f\xdbc{\xeb\xcc\xf1\x92\x9f\r&\f\xef\r\xc3\xc0{\xa2\xda{À\xbc\x87\x86\\)#^\b\xa1C\x82\x8e\x80n\x10d\x03\x18\xa9p\xea^\xfbi\xb9T\x97Lg\x99\xe4\xaa\xfa晝\xf9\x89^\xe7\xf5c#\xa0\x8a\xf1}}\xb4Z\xf1\x8d\x1adO\f~s6 \xbb\xe8\xf7q\x86\x05\x19tt\ftX`\xb0P\x8c\x13\x11\xee\xe9g\xf1Yyt&\xb8\xf3\xf9\xd37\xc5\xdf\xecu.\xff+\x04\\\x88ὒ\xb9\xcbvT\xf6Ȁ\xbfW\x1ar#\xa3\xae:\n:)\xc8\x18H\xf0\xea\x0e\xb0\x92 \xdd%-\x85\x93\xb3\xbb\xe2\x1bz\x1d\xfb'\x82\x80\v1t\xaflr\xe4\x03\xb2\x81\x8f\xe8\xa8\xdc\x10\xae\x84p\x15H\xe8.\xaf/(\x960\xb3\xcb\xcf\xec\xf6\x9ev\x845!`\xfcq\xc9D\xe4:U\xb6\xba3\u007f\xfa&{l-\xec\x02\f~,\xec\x961?ط\x8d-\xe1\x8ab\t\x98\x91\x0eK+J4\x80\xbfcv\x97\xfdS/\xf6{V\x846\x1e\x95a\xd5pG\x9eۛTe\xab\x9bo\x15\x95-f\xde\xe8\x1ci\x1f\x06\u058c\x80\xc5/\xc4Ã\xf7\xe8\xbb\xecE\xf9G\xb9ܯ\x96\xd0\xddHA\x99\x18C\xd0qzT\xc7{\xd6\x03\xe24ט\xf1\xa7\"|\xd2\xdd\xdf/*[E\xa4Q\xa8\u008e\x99\xdf8yL\x1b\xbdڽ\x18\x16\x0f\xd8);\xeb\xfb\xc8\xcbJP\xe8V\x88͌<\x8f=\xfb\xd3\xf3\v\xf6\xbc\x8c\xd3N\xc5K\xd9\xd5\x15g\x82\x82\b\x831rK\xafv_\v}\xed\xeco\x05ZЩ\x17\xa4\xac\a@\bAɖC\xcfjS\xcf\x04\xb4Oq\"\x9e\xabfa*\xe1X$&U\xa9U\x94\\\f\xfd\xbf\xc0\x80\xf4\x17\",\xa4\xf3\x00\xed\x12bZ\xcf\xf9\\\xafv{&`\xe9>\x9b\xb63L\xa5s\x80\x94\x8d\x81\xce>-\x98\xf9\xee\xcb\x0e\xeb\xfbz\xb5}1\xb4Z\xf1W\xcc=+\x1a'\xa5\xdd6܍\x18;\xd2\xdb\"ė\xfd\a\xbdڭ\xa5\t\xda,\x0f{[:엵z\xa7RM\xa75\a'\x8fe\xd7Ա\u007f!&\x8f\x85+U\xf9\xdd2\xf9yg\xac\"\xf4C\x10\xec\f\xd3\xf9\xbc\xf5|\x18S\x8b\x00\x9f\xe5\xab6\x93z\xfcB\xe9Iˡ\x88\x86\xe2\xcc\xceݏ\x8c?.[댑0\xfe\xb8n\x06\x1e\x01&R\xe3\x94\bOw\x8cp\xb0i?\xdc|\xa0w\xfb\xb5\b\x90\x96\u007f\xcb^⸵|\xe5\x92C\xb5\x9bK\n\x8f;\xd7\x00\u07fd\xfc\x89\xec\xe3C_g\xa0\x971&\x8e\xc0\xe4\xb1p{\b\xf2]3\xb6\xa5\xc6\xc8\xccȲ\xf2ʌ\b\xe4\xaf:>-\u007f^˗:/\x01\f}R\xef\xcc\xde\xc4\x1fg\xaf\xaf^\x86\xb2\xceQ9+ˡli\x99v\xf7/\x8b\xf0h\x9e\xf3\xf4\xb9=?\xda\xc3O\x1e\xcb\x06\xddm\x9b;\xbb\xdc\xf9EUy{\xfa\xaej\xb3\x18\xabs_\xa8\r\xadg|\xca^\xe6\xa7\x16\xee\xef]7\xacM\x80\xfe*\xd9\xf0\x96\xf0\x8c^\xefo\xcd6\n\xee\xd2!\xa0HR\xc5\x05\xc8R\xe8\xac\\n\xa2\x13!s\xc0\f\xd02#\x13\xf1q\x90\t@c,[ݴ\xac\ne\xa9T\x8aB\x10<B{\xca\xe1\xa4~p\xee\xf7\xf2\xaf\xd5\xf2\xa3.\x01v\x88<\x9f\xf5\x8f\xdaIr\x9b\x87\xe2\x9eP)kU\xf5\xbej4\xa4\x9b$\xee\x8c\xc6\xe8[\xcc|\xab\b\xd7\x01\x93\x80V5\x80t\x9f\xb0\x10JS\x84\x15\xdf\xc7\xdc\xc9_r\xe2\v\xfc\xb57\xad\x96\xf3\x00\xa1\xee\x8b\x00\xedo\xfbK\xd9\xdbd\x816?'C \xfd\xc9\xd1\xf22S٬$ŷ\xbc\x17X\xaa<\x90\xda\xdbR-\x93\x15\x87S\xd4dY\x87\xc9\x1c\xece\xb0\xef\xc9q\x9f\x93\x9f\x9f\xdf_O\r\x82U\x12\x000\xfa3\xfd\xffО\xb3a_b\a}\x10\x86\x04\x87\x15\xf5&9\x9e\bIW\\\xca\x1dC\xaa\xcd\f\x89\x88\xf4Nq\xbeXl{n\x8e/\x80\xbd\b\xf6\xbc\x1c\x97\xf3z\xf3\xfc\xfe|U\xf7\x10VM\xc0ғ9}\xef\xf0o\xb0\xa4\v\xb2(\xbbc\xcbU3\x90\x06H\xa5.\x80R!N[e\xf1\x1d$\xa7˪N\xa8\n\xa7\xaa\x02K`\xaf@|\x1e\xe2\xcb<\xec\vr\xfb\xfc\xfe\xfc\x95\xd5\xce\u007fM\xf5\x80Ꮗ\x1d>\xe0\u007f\xa4\x97\xb1MƁq'\x1b\x16\xe8\x17\b\xddjpB\xb5vH\xe7\x88f\xc5m\x10ZB>op\x0e\xec4pF\xa6m\xc1\u007f\a\xb3C\v\xf7\xaf͜\xd7\\\x10\x19\xbc\x87LC\xf6Kް\xbd:\xc8v\x19\x13\xe8wd\x03ſ\x06H\x80N\xd5\fBq\xb4\xee\xe0\x06\x9e\x83-9>_\\\x85a\x1eX\x90\x93\xb6\xc4\x03\xb1\x1d\xbf\xd8|\x80U\x9d\x03\\\x88K\xaa\b\rݫף\xbcO\xfae'ʍ\x1e|\\\xfa:$\xf4\t\x8e\xa3\x01,\a\x8f\xa0.X\xd3\xf16-\"\xff\xe6\xcb\x1c&\xf27\xcb\xcb\xf6\xed\xf8\xc5z\xd7\xe0^\v?6Il\xf0\x1eȲl\xb3\xbbl\x01\xdfdf\x138\x03\x0e\x99Eoj\x90y\x119kf/4\x17}\xca\x0f\xf1\x13u\x91b\x1d\xebX\xc7:\xd6\xf1\u007f\x11\xff\x05\x1f2t\x13ȇz\xd2\x00\x00\x00\x00IEND\xaeB`\x82"),
226
        }
227
        filep := &embedded.EmbeddedFile{
228
                Filename:    "footer.html",
229
                FileModTime: time.Unix(1538458476, 0),
230
                Content:     string("{{ define \"footer\"}}\n<div class=\"footer text-center mb-4\">\n{{ if CoreApp.Footer}}\n    {{ CoreApp.Footer }}\n{{ else }}\n    <a href=\"https://github.com/hunterlong/statup\" target=\"_blank\">Statup {{VERSION}} made with ❤️</a> | <a href=\"/dashboard\">Dashboard</a>\n{{ end }}\n</div>\n{{ end }}\n"),
231
        }
232
        fileq := &embedded.EmbeddedFile{
233
                Filename:    "form_checkin.html",
234
                FileModTime: time.Unix(1538707029, 0),
235
                Content:     string("{{define \"form_checkin\"}}\n<form action=\"/checkin/{{.Id}}\" method=\"POST\">\n    <div class=\"form-group row\">\n        <div class=\"col-md-4 col-sm-4\">\n            <label for=\"checkin_interval\" class=\"col-form-label\">Check Interval (in seconds)</label>\n            <input type=\"number\" name=\"interval\" class=\"form-control\" id=\"checkin_interval\" value=\"{{.Interval}}\" placeholder=\"60\">\n        </div>\n        <div class=\"col-md-4 col-sm-4\">\n            <label for=\"grace_period\" class=\"col-form-label\">Grace Period</label>\n            <input type=\"number\" name=\"grace\" class=\"form-control\" id=\"grace_period\" value=\"{{.GracePeriod}}\" placeholder=\"60\">\n        </div>\n        <div class=\"col-md-4 col-sm-4\">\n            <label for=\"checkin_interval\" class=\"col-form-label\"></label>\n            <button type=\"submit\" class=\"btn btn-success d-block\">Save Checkin</button>\n        </div>\n    </div>\n</form>\n{{end}}\n"),
236
        }
237
        filer := &embedded.EmbeddedFile{
238
                Filename:    "form_notifier.html",
239
                FileModTime: time.Unix(1538552384, 0),
240
                Content:     string("{{define \"form_notifier\"}}\n{{$n := .Select}}\n<form method=\"POST\" class=\"{{underscore $n.Method }}\" action=\"/settings/notifier/{{ $n.Method }}\">\n{{if $n.Title}}<h4>{{$n.Title}}</h4>{{end}}\n{{if $n.Description}}<p class=\"small text-muted\">{{$n.Description}}</p>{{end}}\n\n{{range $n.Form}}\n    <div class=\"form-group\">\n            <label class=\"text-capitalize\" for=\"{{underscore .Title}}\">{{.Title}}</label>\n        {{if eq .Type \"textarea\"}}\n            <textarea rows=\"3\" class=\"form-control\" name=\"{{underscore .DbField}}\" id=\"{{underscore .Title}}\">{{ $n.GetValue .DbField }}</textarea>\n        {{else}}\n            <input type=\"{{.Type}}\" name=\"{{underscore .DbField}}\" class=\"form-control\" value=\"{{ $n.GetValue .DbField }}\" id=\"{{underscore .Title}}\" placeholder=\"{{.Placeholder}}\" {{if .Required}}required{{end}}>\n        {{end}}\n        {{if .SmallText}}\n            <small class=\"form-text text-muted\">{{safe .SmallText}}</small>\n        {{end}}\n    </div>\n{{end}}\n\n    <div class=\"row\">\n        <div class=\"col-9 col-sm-6\">\n            <div class=\"input-group mb-2\">\n                <div class=\"input-group-prepend\">\n                    <div class=\"input-group-text\">Limit</div>\n                </div>\n                <input type=\"text\" class=\"form-control\" name=\"limits\" min=\"1\" max=\"60\" id=\"limits_per_hour_{{underscore $n.Method }}\" value=\"{{$n.Limits}}\" placeholder=\"7\">\n                <div class=\"input-group-append\">\n                    <div class=\"input-group-text\">Per Minute</div>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"col-3 col-sm-2 mt-1\">\n            <span class=\"switch\">\n                <input type=\"checkbox\" name=\"enable\" class=\"switch\" id=\"switch-{{ $n.Method }}\" {{if $n.Enabled}}checked{{end}}>\n                <label for=\"switch-{{ $n.Method }}\"></label>\n            </span>\n        </div>\n\n        <input type=\"hidden\" name=\"notifier\" value=\"{{underscore $n.Method }}\">\n\n        <div class=\"col-12 col-sm-4 mb-2 mb-sm-0 mt-2 mt-sm-0\">\n            <button type=\"submit\" class=\"btn btn-primary btn-block text-capitalize\">Save</button>\n        </div>\n\n    {{if $n.CanTest}}\n        <div class=\"col-12 col-sm-12\">\n            <button class=\"test_notifier btn btn-secondary btn-block text-capitalize col-12 float-right\">Test</button>\n        </div>\n\n        <div class=\"col-12 col-sm-12 mt-2\">\n            <div class=\"alert alert-danger d-none\" id=\"{{underscore $n.Method}}-error\" role=\"alert\">\n            {{$n.Method}} has an error!\n            </div>\n\n            <div class=\"alert alert-success d-none\" id=\"{{underscore $n.Method}}-success\" role=\"alert\">\n                The {{$n.Method}} notifier is working correctly!\n            </div>\n        </div>\n    {{end}}\n\n    </div>\n\n{{if $n.Author}}\n    <span class=\"d-block small text-center mt-3 mb-5\">\n                            {{$n.Title}} Notifier created by <a href=\"{{$n.AuthorUrl}}\" target=\"_blank\">{{$n.Author}}</a>\n                        </span>\n{{ end }}\n</form>\n{{end}}\n"),
241
        }
242
        files := &embedded.EmbeddedFile{
243
                Filename:    "form_service.html",
244
                FileModTime: time.Unix(1538894434, 0),
245
                Content:     string("{{define \"form_service\"}}\n<form action=\"{{if ne .Id 0}}/service/{{.Id}}{{else}}/services{{end}}\" method=\"POST\">\n    <div class=\"form-group row\">\n        <label for=\"service_name\" class=\"col-sm-4 col-form-label\">Service Name</label>\n        <div class=\"col-sm-8\">\n            <input type=\"text\" name=\"name\" class=\"form-control\" id=\"service_name\" value=\"{{.Name}}\" placeholder=\"Name\" required spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_type\" class=\"col-sm-4 col-form-label\">Service Check Type</label>\n        <div class=\"col-sm-8\">\n            <select name=\"check_type\" class=\"form-control\" id=\"service_type\" value=\"{{.Type}}\">\n                <option value=\"http\" {{if eq .Type \"http\"}}selected{{end}}>HTTP Service</option>\n                <option value=\"tcp\" {{if eq .Type \"tcp\"}}selected{{end}}>TCP Service</option>\n                <option value=\"udp\" {{if eq .Type \"udp\"}}selected{{end}}>UDP Service</option>\n            </select>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_url\" class=\"col-sm-4 col-form-label\">Application Endpoint (URL)</label>\n        <div class=\"col-sm-8\">\n            <input type=\"text\" name=\"domain\" class=\"form-control\" id=\"service_url\" value=\"{{.Domain}}\" placeholder=\"https://google.com\" required autocapitalize=\"false\" spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"tcp\"}} d-none{{end}}\">\n        <label for=\"service_check_type\" class=\"col-sm-4 col-form-label\">Service Check Type</label>\n        <div class=\"col-sm-8\">\n            <select name=\"method\" class=\"form-control\" id=\"service_check_type\" value=\"{{.Method}}\">\n                <option value=\"GET\" {{if eq .Method \"GET\"}}selected{{end}}>GET</option>\n                <option value=\"POST\" {{if eq .Method \"POST\"}}selected{{end}}>POST</option>\n                <option value=\"DELETE\" {{if eq .Method \"DELETE\"}}selected{{end}}>DELETE</option>\n                <option value=\"PATCH\" {{if eq .Method \"PATCH\"}}selected{{end}}>PATCH</option>\n                <option value=\"PUT\" {{if eq .Method \"PUT\"}}selected{{end}}>PUT</option>\n            </select>\n        </div>\n    </div>\n    <div class=\"form-group row{{if ne .Method \"POST\"}} d-none{{end}}\">\n        <label for=\"post_data\" class=\"col-sm-4 col-form-label\">Optional Post Data (JSON)</label>\n        <div class=\"col-sm-8\">\n            <textarea name=\"post_data\" class=\"form-control\" id=\"post_data\" rows=\"3\" autocapitalize=\"false\" spellcheck=\"false\">{{.PostData}}</textarea>\n            <small id=\"emailHelp\" class=\"form-text text-muted\">You can insert <a target=\"_blank\" href=\"https://regex101.com/r/I5bbj9/1\">Regex</a> to validate the response</small>\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"tcp\"}} d-none{{end}}\">\n        <label for=\"service_response\" class=\"col-sm-4 col-form-label\">Expected Response (Regex)</label>\n        <div class=\"col-sm-8\">\n            <textarea name=\"expected\" class=\"form-control\" id=\"service_response\" rows=\"3\" autocapitalize=\"false\" spellcheck=\"false\">{{.Expected}}</textarea>\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"tcp\"}} d-none{{end}}\">\n        <label for=\"service_response_code\" class=\"col-sm-4 col-form-label\">Expected Status Code</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"expected_status\" class=\"form-control\" value=\"{{if ne .ExpectedStatus 0}}{{.ExpectedStatus}}{{end}}\" placeholder=\"200\" id=\"service_response_code\">\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"\"}} d-none{{else if eq .Type \"http\"}} d-none{{end}}\">\n        <label id=\"service_type_label\" for=\"service_port\" class=\"col-sm-4 col-form-label\">TCP Port</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"port\" class=\"form-control\" value=\"{{if ne .Port 0}}{{.Port}}{{end}}\" id=\"service_port\" placeholder=\"8080\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_interval\" class=\"col-sm-4 col-form-label\">Check Interval (Seconds)</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"interval\" class=\"form-control\" value=\"{{if ne .Interval 0}}{{.Interval}}{{end}}\" min=\"1\" id=\"service_interval\" required>\n            <small id=\"emailHelp\" class=\"form-text text-muted\">10,000+ will be checked in Microseconds (1 millisecond = 1000 microseconds).</small>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_timeout\" class=\"col-sm-4 col-form-label\">Timeout in Seconds</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"timeout\" class=\"form-control\" value=\"{{if ne .Timeout 0}}{{.Timeout}}{{end}}\" placeholder=\"15\" id=\"service_timeout\" min=\"1\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"order\" class=\"col-sm-4 col-form-label\">List Order</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"order\" class=\"form-control\" min=\"0\" value=\"{{.Order}}\" id=\"order\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <div class=\"{{if ne .Id 0}}col-6{{else}}col-12{{end}}\">\n            <button type=\"submit\" class=\"btn btn-success btn-block\">{{if ne .Id 0}}Update Service{{else}}Create Service{{end}}</button>\n        </div>\n        {{if ne .Id 0}}\n        <div class=\"col-6\">\n            <a href=\"/service/{{ .Id }}/delete_failures\" class=\"btn btn-danger btn-block confirm-btn\">Delete All Failures</a>\n        </div>\n        {{end}}\n    </div>\n</form>\n{{end}}\n"),
246
        }
247
        filet := &embedded.EmbeddedFile{
248
                Filename:    "form_user.html",
249
                FileModTime: time.Unix(1538543370, 0),
250
                Content:     string("{{define \"form_user\"}}\n<form action=\"{{if ne .Id 0}}/user/{{.Id}}{{else}}/users{{end}}\" method=\"POST\">\n    <div class=\"form-group row\">\n        <label for=\"username\" class=\"col-sm-4 col-form-label\">Username</label>\n        <div class=\"col-6 col-md-4\">\n            <input type=\"text\" name=\"username\" class=\"form-control\" value=\"{{.Username}}\" id=\"username\" placeholder=\"Username\" required>\n        </div>\n        <div class=\"col-6 col-md-4\">\n          <span class=\"switch\">\n            <input type=\"checkbox\" name=\"admin\" class=\"switch\" id=\"switch-normal\"{{if .Admin}} checked{{end}}>\n            <label for=\"switch-normal\">Administrator</label>\n          </span>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"email\" class=\"col-sm-4 col-form-label\">Email Address</label>\n        <div class=\"col-sm-8\">\n            <input type=\"email\" name=\"email\" class=\"form-control\" id=\"email\" value=\"{{.Email}}\" placeholder=\"user@domain.com\" required autocapitalize=\"false\" spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"password\" class=\"col-sm-4 col-form-label\">Password</label>\n        <div class=\"col-sm-8\">\n            <input type=\"password\" name=\"password\" class=\"form-control\" id=\"password\" value=\"##########\" placeholder=\"Password\" required>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"password_confirm\" class=\"col-sm-4 col-form-label\">Confirm Password</label>\n        <div class=\"col-sm-8\">\n            <input type=\"password\" name=\"password_confirm\" class=\"form-control\" id=\"password_confirm\" value=\"##########\" placeholder=\"Confirm Password\" required>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <div class=\"col-sm-12\">\n            <button type=\"submit\" class=\"btn btn-primary btn-block\">{{if ne .Id 0}}Update User{{else}}Create User{{end}}</button>\n        </div>\n    </div>\n</form>\n{{end}}\n"),
251
        }
252
        fileu := &embedded.EmbeddedFile{
253
                Filename:    "head.html",
254
                FileModTime: time.Unix(1538459085, 0),
255
                Content:     string("{{ define \"head\"}}\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0\">\n{{if USE_CDN}}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://assets.statup.io/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css\" integrity=\"sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://assets.statup.io/base.css\">\n{{ else }}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"/css/base.css\">\n{{end}}\n{{block \"extra_css\" .}} {{end}}\n<title>{{block \"title\" .}} {{end}}</title>\n</head>\n{{end}}\n"),
256
        }
257
        filev := &embedded.EmbeddedFile{
258
                Filename:    "help.html",
259
                FileModTime: time.Unix(1538459433, 0),
260
                Content:     string("{{define \"title\"}}Statup | Help{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n    <div class=\"col-12\">\n    {{ safe . }}\n    </div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<style>\n    pre {\n        background-color: white;\n        padding: 10px 15px;\n        border: 1px solid #a2a2a233;\n        border-radius: 7px;\n    }\n    code {\n        color: #d87e1a;\n    }\n</style>\n{{end}}\n"),
261
        }
262
        filew := &embedded.EmbeddedFile{
263
                Filename:    "help.md",
264
                FileModTime: time.Unix(1536974218, 0),
265
                Content:     string("# Statup Help\nStatup is an easy to use Status Page monitor for your websites and applications. Statup is developed in Go Language and you are able to create custom plugins with it!\n\n<p>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/github/stars/hunterlong/statup.svg?style=social&label=Stars\"></a>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/docker/build/hunterlong/statup.svg\"></a>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/github/release/hunterlong/statup.svg\"></a>\n</p>\n\n# Services\nFor each website and application you want to add a new Service. Each Service will require a URL endpoint to test your applications status.\nYou can also add expected HTTP responses (regex allow), expected HTTP response codes, and other fields to make sure your service is online or offline.\n\n# Statup Settings\nYou can change multiple settings in your Statup instance.\n\n# Users\nUsers can access the Statup Dashboard to add, remove, and view services.\n\n# Notifications\n\n\n# Plugins\nCreating a plugin for Statup is not that difficult, if you know a little bit of Go Language you can create any type of application to be embedded into the Status framework.\nCheckout the example plugin that includes all the interfaces, information, and custom HTTP routing at <a href=\"https://github.com/hunterlong/statup_plugin\">https://github.com/hunterlong/statup_plugin</a>.\nAnytime there is an action on your status page, all of your plugins will be notified of the change with the values that were changed or created.\n<p></p>\nUsing the statup/plugin Golang package you can quickly implement the event listeners. Statup uses <a href=\"https://github.com/upper/db\">upper.io/db.v3</a> for the database connection.\nYou can use the database inside of your plugin to create, update, and destroy tables/data. <b>Please only use respectable plugins!</b>\n\n# Custom Stlying\nOn Statup Status Page server can you create your own custom stylesheet to be rendered on the index view of your status page. Go to <a href=\"/settings\">Settings</a> and click on Custom Styling.\n\n# API Endpoints\nStatup includes a RESTFUL API so you can view, update, and edit your services with easy to use routes. You can currently view, update and delete services, view, create, update users, and get detailed information about the Statup instance. To make life easy, try out a Postman or Swagger JSON file and use it on your Statup Server.\n\n<p align=\"center\">\n<a href=\"https://github.com/hunterlong/statup/blob/master/dev/postman.json\">Postman JSON Export</a> | <a href=\"https://github.com/hunterlong/statup/blob/master/dev/swagger.json\">Swagger Export</a>\n</p>\n\n## Authentication\nAuthentication uses the Statup API Secret to accept remote requests. You can find the API Secret in the Settings page of your Statup server. To send requests to your Statup API, include a Authorization Header when you send the request. The API will accept any one of the headers below.\n\n- HTTP Header: `Authorization: API SECRET HERE`\n- HTTP Header: `Authorization: Bearer API SECRET HERE`\n\n## Main Route `/api`\nThe main API route will show you all services and failures along with them.\n\n## Services\nThe services API endpoint will show you detailed information about services and will allow you to edit/delete services with POST/DELETE http methods.\n\n### Viewing All Services\n- Endpoint: `/api/services`\n- Method: `GET`\n- Response: Array of [Services](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Viewing Service\n- Endpoint: `/api/services/{id}`\n- Method: `GET`\n- Response: [Service](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Updating Service\n- Endpoint: `/api/services/{id}`\n- Method: `POST`\n- Response: [Service](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"name\": \"Updated Service\",\n    \"domain\": \"https://google.com\",\n    \"expected\": \"\",\n    \"expected_status\": 200,\n    \"check_interval\": 15,\n    \"type\": \"http\",\n    \"method\": \"GET\",\n    \"post_data\": \"\",\n    \"port\": 0,\n    \"timeout\": 10,\n    \"order_id\": 0\n}\n```\n\n### Deleting Service\n- Endpoint: `/api/services/{id}`\n- Method: `DELETE`\n- Response: [Object Response](https://github.com/hunterlong/statup/wiki/API#object-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nResponse:\n``` json\n{\n    \"status\": \"success\",\n    \"id\": 4,\n    \"type\": \"service\",\n    \"method\": \"delete\"\n}\n```\n\n## Users\nThe users API endpoint will show you users that are registered inside your Statup instance.\n\n### View All Users\n- Endpoint: `/api/users`\n- Method: `GET`\n- Response: Array of [Users](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Viewing User\n- Endpoint: `/api/users/{id}`\n- Method: `GET`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Creating New User\n- Endpoint: `/api/users`\n- Method: `POST`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"username\": \"newadmin\",\n    \"email\": \"info@email.com\",\n    \"password\": \"password123\",\n    \"admin\": true\n}\n```\n\n### Updating User\n- Endpoint: `/api/users/{id}`\n- Method: `POST`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"username\": \"updatedadmin\",\n    \"email\": \"info@email.com\",\n    \"password\": \"password123\",\n    \"admin\": true\n}\n```\n\n### Deleting User\n- Endpoint: `/api/services/{id}`\n- Method: `DELETE`\n- Response: [Object Response](https://github.com/hunterlong/statup/wiki/API#object-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nResponse:\n``` json\n{\n    \"status\": \"success\",\n    \"id\": 3,\n    \"type\": \"user\",\n    \"method\": \"delete\"\n}\n```\n\n# Service Response\n``` json\n{\n    \"id\": 8,\n    \"name\": \"Test Service 0\",\n    \"domain\": \"https://status.coinapp.io\",\n    \"expected\": \"\",\n    \"expected_status\": 200,\n    \"check_interval\": 1,\n    \"type\": \"http\",\n    \"method\": \"GET\",\n    \"post_data\": \"\",\n    \"port\": 0,\n    \"timeout\": 30,\n    \"order_id\": 0,\n    \"created_at\": \"2018-09-12T09:07:03.045832088-07:00\",\n    \"updated_at\": \"2018-09-12T09:07:03.046114305-07:00\",\n    \"online\": false,\n    \"latency\": 0.031411064,\n    \"24_hours_online\": 0,\n    \"avg_response\": \"\",\n    \"status_code\": 502,\n    \"last_online\": \"0001-01-01T00:00:00Z\",\n    \"dns_lookup_time\": 0.001727175,\n    \"failures\": [\n        {\n            \"id\": 5187,\n            \"issue\": \"HTTP Status Code 502 did not match 200\",\n            \"created_at\": \"2018-09-12T10:41:46.292277471-07:00\"\n        },\n        {\n            \"id\": 5188,\n            \"issue\": \"HTTP Status Code 502 did not match 200\",\n            \"created_at\": \"2018-09-12T10:41:47.337659862-07:00\"\n        }\n    ]\n}\n```\n\n# User Response\n``` json\n{\n    \"id\": 1,\n    \"username\": \"admin\",\n    \"api_key\": \"02f324450a631980121e8fd6ea7dfe4a7c685a2f\",\n    \"admin\": true,\n    \"created_at\": \"2018-09-12T09:06:53.906398511-07:00\",\n    \"updated_at\": \"2018-09-12T09:06:54.972440207-07:00\"\n}\n```\n\n# Object Response\n``` json\n{\n    \"type\": \"service\",\n    \"id\": 19,\n    \"method\": \"delete\",\n    \"status\": \"success\"\n}\n```\n\n# Main API Response\n``` json\n{\n    \"name\": \"Awesome Status\",\n    \"description\": \"An awesome status page by Statup\",\n    \"footer\": \"This is my custom footer\",\n    \"domain\": \"https://demo.statup.io\",\n    \"version\": \"v0.56\",\n    \"migration_id\": 1536768413,\n    \"created_at\": \"2018-09-12T09:06:53.905374829-07:00\",\n    \"updated_at\": \"2018-09-12T09:07:01.654201225-07:00\",\n    \"database\": \"sqlite\",\n    \"started_on\": \"2018-09-12T10:43:07.760729349-07:00\",\n    \"services\": [\n        {\n            \"id\": 1,\n            \"name\": \"Google\",\n            \"domain\": \"https://google.com\",\n            \"expected\": \"\",\n            \"expected_status\": 200,\n            \"check_interval\": 10,\n            \"type\": \"http\",\n            \"method\": \"GET\",\n            \"post_data\": \"\",\n            \"port\": 0,\n            \"timeout\": 10,\n            \"order_id\": 0,\n            \"created_at\": \"2018-09-12T09:06:54.97549122-07:00\",\n            \"updated_at\": \"2018-09-12T09:06:54.975624103-07:00\",\n            \"online\": true,\n            \"latency\": 0.09080986,\n            \"24_hours_online\": 0,\n            \"avg_response\": \"\",\n            \"status_code\": 200,\n            \"last_online\": \"2018-09-12T10:44:07.931990439-07:00\",\n            \"dns_lookup_time\": 0.005543935\n        }\n    ]\n}\n```\n\n# Prometheus Exporter\nStatup includes a prometheus exporter so you can have even more monitoring power with your services. The prometheus exporter can be seen on `/metrics`, simply create another exporter in your prometheus config. Use your Statup API Secret for the Authorization Bearer header, the `/metrics` URL is dedicated for Prometheus and requires the correct API Secret has `Authorization` header.\n\n# Grafana Dashboard\nStatup has a [Grafana Dashboard](https://grafana.com/dashboards/6950) that you can quickly implement if you've added your Statup service to Prometheus. Import Dashboard ID: `6950` into your Grafana dashboard and watch the metrics come in!\n\n<p align=\"center\"><img width=\"80%\" src=\"https://img.cjx.io/statupgrafana.png\"></p>\n\n## Basic Prometheus Exporter\nIf you have Statup and the Prometheus server in the same Docker network, you can use the yaml config below.\n``` yaml\nscrape_configs:\n  - job_name: 'statup'\n    scrape_interval: 30s\n    bearer_token: 'SECRET API KEY HERE'\n    static_configs:\n      - targets: ['statup:8080']\n```\n\n## Remote URL Prometheus Exporter\nThis exporter yaml below has `scheme: https`, which you can remove if you arn't using HTTPS.\n``` yaml\nscrape_configs:\n  - job_name: 'statup'\n    scheme: https\n    scrape_interval: 30s\n    bearer_token: 'SECRET API KEY HERE'\n    static_configs:\n      - targets: ['status.mydomain.com']\n```\n\n### `/metrics` Output\n```\nstatup_total_failures 206\nstatup_total_services 4\nstatup_service_failures{id=\"1\" name=\"Google\"} 0\nstatup_service_latency{id=\"1\" name=\"Google\"} 12\nstatup_service_online{id=\"1\" name=\"Google\"} 1\nstatup_service_status_code{id=\"1\" name=\"Google\"} 200\nstatup_service_response_length{id=\"1\" name=\"Google\"} 10777\nstatup_service_failures{id=\"2\" name=\"Statup.io\"} 0\nstatup_service_latency{id=\"2\" name=\"Statup.io\"} 3\nstatup_service_online{id=\"2\" name=\"Statup.io\"} 1\nstatup_service_status_code{id=\"2\" name=\"Statup.io\"} 200\nstatup_service_response_length{id=\"2\" name=\"Statup.io\"} 2\n```\n\n# Static HTML Exporter\nYou might have a server that won't allow you to run command that run longer for 60 seconds, or maybe you just want to export your status page to a static HTML file. Using the Statup exporter you can easily do this with 1 command.\n\n```\nstatup export\n```\n###### 'index.html' is created in current directory with static CDN url's.\n\n## Push to Github\nOnce you have the `index.html` file, you could technically send it to an FTP server, Email it, Pastebin it, or even push to your Github repo for Status updates directly from repo.\n\n```bash\ngit add index.html\ngit commit -m \"Updated Status Page\"\ngit push -u origin/master\n```\n\n# Config with .env File\nIt may be useful to load your environment using a `.env` file in the root directory of your Statup server. The .env file will be automatically loaded on startup and will overwrite all values you have in config.yml.\n\nIf you have the `DB_CONN` environment variable set Statup will bypass all values in config.yml and will require you to have the other DB_* variables in place. You can pass in these environment variables without requiring a .env file.\n\n## `.env` File\n```bash\nDB_CONN=postgres\nDB_HOST=0.0.0.0\nDB_PORT=5432\nDB_USER=root\nDB_PASS=password123\nDB_DATABASE=root\n\nNAME=Demo\nDESCRIPTION=This is an awesome page\nDOMAIN=https://domain.com\nADMIN_USER=admin\nADMIN_PASS=admin\nADMIN_EMAIL=info@admin.com\nUSE_CDN=true\n\nIS_DOCKER=false\nIS_AWS=false\nSASS=/usr/local/bin/sass\nCMD_FILE=/bin/bash\n```\nThis .env file will include additional variables in the future, subscribe to this repo to keep up-to-date with changes and updates.\n\n# Makefile\nHere's a simple list of Makefile commands you can run using `make`. The [Makefile](https://github.com/hunterlong/statup/blob/master/Makefile) may change often, so i'll try to keep this Wiki up-to-date.\n\n- Ubuntu `apt-get install build-essential`\n- MacOSX `sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer`\n- Windows [Install Guide for GNU make utility](http://gnuwin32.sourceforge.net/packages/make.htm)\n- CentOS/RedHat `yum groupinstall \"Development Tools\"`\n\n### Commands\n``` bash\nmake build                         # build the binary\nmake install\nmake run\nmake test\nmake coverage\nmake docs\n# Building Statup\nmake build-all\nmake build-alpine\nmake docker\nmake docker-run\nmake docker-dev\nmake docker-run-dev\nmake databases\nmake dep\nmake dev-deps\nmake clean\nmake compress\nmake cypress-install\nmake cypress-test\n```\n\n## Testing\n* If you want to test your updates with the current golang testing units, you can follow the guide below to run a full test process. Each test for Statup will run in MySQL, Postgres, and SQlite to make sure all database types work correctly.\n\n## Create Docker Databases\nThe easiest way to run the tests on all 3 databases is by starting temporary databases servers with Docker. Docker is available for Linux, Mac and Windows. You can download/install it by going to the [Docker Installation](https://docs.docker.com/install/) site.\n\n``` bash\ndocker run -it -d \\\n   -p 3306:3306 \\\n   -env MYSQL_ROOT_PASSWORD=password123 \\\n   -env MYSQL_DATABASE=root mysql\n```\n\n``` bash\ndocker run -it -d \\\n   -p 5432:5432 \\\n   -env POSTGRES_PASSWORD=password123 \\\n   -env POSTGRES_USER=root \\\n   -env POSTGRES_DB=root postgres\n```\n\nOnce you have MySQL and Postgres running, you can begin the testing. SQLite database will automatically create a `statup.db` file and will delete after testing.\n\n## Run Tests\nInsert the database environment variables to auto connect the the databases and run the normal test command: `go test -v`. You'll see a verbose output of each test. If all tests pass, make a push request! 💃\n``` bash\nDB_DATABASE=root \\\n   DB_USER=root \\\n   DB_PASS=password123 \\\n   DB_HOST=localhost \\\n   go test -v\n```\n"),
266
        }
267
        filex := &embedded.EmbeddedFile{
268
                Filename:    "index.html",
269
                FileModTime: time.Unix(1538522506, 0),
270
                Content:     string("{{define \"title\"}}{{CoreApp.Name}} Status{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-2 sm-container\">\n<h1 class=\"col-12 text-center mb-4 mt-sm-3 header-title\">{{.Name}}</h1>\n\n{{ if .Description }}\n<h5 class=\"col-12 text-center mb-5 header-desc\">{{ .Description }}</h5>\n{{ end }}\n\n<div class=\"col-12 full-col-12 mb-5\">\n    <div class=\"list-group online_list\">\n    {{ range Services }}\n        <a href=\"#\" class=\"service_li list-group-item list-group-item-action {{if not .Online}}bg-danger text-white{{ end }}\" data-id=\"{{.Id}}\">\n        {{ .Name }}\n        {{if .Online}}\n            <span class=\"badge bg-success float-right pulse-glow\">ONLINE</span>\n        {{ else }}\n            <span class=\"badge bg-white text-black-50 float-right pulse\">OFFLINE</span>\n        {{end}}\n        </a>\n    {{ end }}\n    </div>\n</div>\n\n<div class=\"col-12 full-col-12\">\n{{ if not Services }}\n    <div class=\"alert alert-danger\" role=\"alert\">\n        <h4 class=\"alert-heading\">No Services to Monitor!</h4>\n        <p>Your Statup Status Page is working correctly, but you don't have any services to monitor. Go to the <b>Dashboard</b> and add a website to begin really using your status page!</p>\n        <hr>\n        <p class=\"mb-0\">If this is a bug, please make an issue in the Statup Github Repo. <a href=\"https://github.com/hunterlong/statup\" class=\"btn btn-sm btn-outline-danger float-right\">Statup Github Repo</a></p>\n    </div>\n{{end}}\n{{ range Services }}\n    <div class=\"mt-4\" id=\"service_id_{{.Id}}\">\n        <div class=\"card\">\n            <div class=\"card-body\">\n                <div class=\"col-12\">\n                    <h4 class=\"mt-3\"><a href=\"/service/{{.Id}}\"{{if not .Online}} class=\"text-danger\"{{end}}>{{ .Name }}</a>\n                    {{if .Online}}\n                        <span class=\"badge bg-success float-right\">ONLINE</span>\n                    {{ else }}\n                        <span class=\"badge bg-danger float-right pulse\">OFFLINE</span>\n                    {{end}}</h4>\n\n                    <div class=\"row stats_area mt-5 mb-5\">\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.Online24}}%</span>\n                            Online last 24 Hours\n                        </div>\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.AvgTime}}ms</span>\n                            Average Response\n                        </div>\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.AvgUptime24}}%</span>\n                            Uptime last 24 Hours\n                        </div>\n                    </div>\n\n                </div>\n            </div>\n        {{ if .AvgUptime24 }}\n            <div class=\"chart-container\">\n                <canvas id=\"service_{{ .Id }}\"></canvas>\n            </div>\n        {{ end }}\n            <div class=\"row lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}\">\n                <div class=\"col-10 text-truncate\">\n                    <span class=\"d-none d-md-inline\">{{.SmallText}}</span>\n                </div>\n                <div class=\"col-sm-12 col-md-2\">\n                    <a href=\"/service/{{ .Id }}\" class=\"btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right dyn-dark btn-block\">View Service</a>\n                </div>\n            </div>\n        </div>\n    </div>\n{{ end }}\n</div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"/charts.js\"></script>\n{{end}}\n"),
271
        }
272
        filey := &embedded.EmbeddedFile{
273
                Filename:    "login.html",
274
                FileModTime: time.Unix(1538454764, 0),
275
                Content:     string("{{define \"title\"}}Statup Login{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-10 offset-1 col-md-8 offset-md-2 mt-md-2\">\n        <div class=\"col-12 col-md-8 offset-md-2 mb-4\">\n            <img class=\"col-12 mt-5 mt-md-0\" src=\"/statup.png\">\n        </div>\n    {{ if .Error }}\n        <div class=\"alert alert-danger\" role=\"alert\">\n            Incorrect login information submitted, try again.\n        </div>\n    {{ end }}\n        <form action=\"/dashboard\" method=\"POST\">\n            <div class=\"form-group row\">\n                <label for=\"username\" class=\"col-sm-2 col-form-label\">Username</label>\n                <div class=\"col-sm-10\">\n                    <input type=\"text\" name=\"username\" class=\"form-control\" id=\"username\" placeholder=\"Username\" autocapitalize=\"false\" spellcheck=\"false\">\n                </div>\n            </div>\n            <div class=\"form-group row\">\n                <label for=\"password\" class=\"col-sm-2 col-form-label\">Password</label>\n                <div class=\"col-sm-10\">\n                    <input type=\"password\" name=\"password\" class=\"form-control\" id=\"password\" placeholder=\"Password\">\n                </div>\n            </div>\n            <div class=\"form-group row\">\n                <div class=\"col-sm-12\">\n                    <button type=\"submit\" class=\"btn btn-primary btn-block\">Sign in</button>\n                </div>\n            </div>\n        </form>\n    </div>\n</div>\n{{end}}\n"),
276
        }
277
        filez := &embedded.EmbeddedFile{
278
                Filename:    "logs.html",
279
                FileModTime: time.Unix(1538460210, 0),
280
                Content:     string("{{define \"title\"}}Statup | Logs{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n<div class=\"col-12\">\n    <textarea id=\"live_logs\" class=\"form-control\" rows=\"40\" readonly>{{range .}}{{.}}{{end}}</textarea>\n</div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<style>\n    @media (max-width: 767px) {\n        #live_logs {\n            font-size: 6pt;\n        }\n    }\n</style>\n{{end}}\n"),
281
        }
282
        file10 := &embedded.EmbeddedFile{
283
                Filename:    "nav.html",
284
                FileModTime: time.Unix(1534817721, 0),
285
                Content:     string("{{define \"nav\"}}\n<nav class=\"navbar navbar-expand-lg navbar-light bg-light\">\n    <a class=\"navbar-brand\" href=\"/\">Statup</a>\n    <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarText\" aria-controls=\"navbarText\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n        <span class=\"navbar-toggler-icon\"></span>\n    </button>\n\n    <div class=\"collapse navbar-collapse\" id=\"navbarText\">\n        <ul class=\"navbar-nav mr-auto\">\n            <li class=\"nav-item{{ if eq URL \"/dashboard\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/dashboard\">Dashboard</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/services\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/services\">Services</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/users\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/users\">Users</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/settings\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/settings\">Settings</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/logs\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/logs\">Logs</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/help\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/help\">Help</a>\n            </li>\n        </ul>\n        <span class=\"navbar-text\">\n      <a class=\"nav-link\" href=\"/logout\">Logout</a>\n    </span>\n    </div>\n</nav>\n{{end}}"),
286
        }
287
        file11 := &embedded.EmbeddedFile{
288
                Filename:    "robots.txt",
289
                FileModTime: time.Unix(1530546686, 0),
290
                Content:     string("User-agent: *\nDisallow: /login\nDisallow: /dashboard"),
291
        }
292
        file12 := &embedded.EmbeddedFile{
293
                Filename:    "scripts.html",
294
                FileModTime: time.Unix(1538453657, 0),
295
                Content:     string("{{define \"scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js\" integrity=\"sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js\"></script>\n<script src=\"https://assets.statup.io/main.js\"></script>\n{{ else }}\n<script src=\"/js/jquery-3.3.1.min.js\"></script>\n<script src=\"/js/bootstrap.min.js\"></script>\n<script src=\"/js/Chart.bundle.min.js\"></script>\n<script src=\"/js/main.js\"></script>\n{{end}}\n{{block \"extra_scripts\" .}} {{end}}\n{{end}}\n"),
296
        }
297
        file13 := &embedded.EmbeddedFile{
298
                Filename:    "service.html",
299
                FileModTime: time.Unix(1538796803, 0),
300
                Content:     string("{{define \"title\"}}{{.Service.Name}} Status{{end}}\n{{ define \"content\" }}\n{{$s := .Service}}\n\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n\n    <div class=\"col-12 mb-4\">\n\n    {{if $s.Online }}\n        <span class=\"mt-3 mb-3 text-white d-md-none btn bg-success d-block d-md-none\">ONLINE</span>\n    {{ else }}\n        <span class=\"mt-3 mb-3 text-white d-md-none btn bg-danger d-block d-md-none\">OFFLINE</span>\n    {{end}}\n\n        <h4 class=\"mt-2\">{{ $s.Name }}\n        {{if $s.Online }}\n            <span class=\"badge bg-success float-right d-none d-md-block\">ONLINE</span>\n        {{ else }}\n            <span class=\"badge bg-danger float-right d-none d-md-block\">OFFLINE</span>\n        {{end}}</h4>\n\n        <div class=\"row stats_area mt-5 mb-5\">\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.Online24}}%</span>\n                Online last 24 Hours\n            </div>\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.AvgTime}}ms</span>\n                Average Response\n            </div>\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.TotalUptime}}%</span>\n                Total Uptime\n            </div>\n        </div>\n\n        <div class=\"service-chart-container\">\n            <canvas id=\"service\"></canvas>\n        </div>\n\n        <form id=\"service_date_form\" class=\"col-12 mt-2 mb-3\">\n            <span id=\"start_date\" class=\"text-muted small float-left pointer\">{{FromUnix .Start}}</span>\n            <span id=\"end_date\" class=\"text-muted small float-right pointer\" style=\"position: absolute;right: 0;\">{{FromUnix .End}}</span>\n            <input type=\"hidden\" name=\"start\" class=\"form-control\" id=\"service_start\" spellcheck=\"false\">\n            <input type=\"hidden\" name=\"end\" class=\"form-control\" id=\"service_end\" spellcheck=\"false\">\n            <button type=\"submit\" class=\"btn btn-light btn-block btn-sm mt-2\">Set Timeframe</button>\n            <div id=\"start_container\"></div>\n            <div id=\"end_container\"></div>\n        </form>\n\n    {{if not $s.Online}}\n        <div class=\"col-12 small text-center mt-3 text-muted\">{{$s.DowntimeText}}</div>\n    {{end}}\n\n    {{ if $s.LimitedFailures }}\n        <div class=\"list-group mt-3 mb-4\">\n        {{ range $s.LimitedFailures }}\n            <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                <div class=\"d-flex w-100 justify-content-between\">\n                    <h5 class=\"mb-1\">{{.ParseError}}</h5>\n                    <small>{{.Ago}}</small>\n                </div>\n                <p class=\"mb-1\">{{.Issue}}</p>\n            </a>\n        {{ end }}\n        </div>\n    {{ end }}\n\n    </div>\n\n{{if Auth}}\n\n    <div class=\"col-12 mt-4{{if ne $s.Type \"http\"}} d-none{{end}}\">\n        <h3>Last Response</h3>\n        <textarea rows=\"8\" class=\"form-control\" readonly>{{ $s.LastResponse }}</textarea>\n        <div class=\"form-group row mt-2\">\n            <label for=\"last_status_code\" class=\"col-sm-3 col-form-label\">HTTP Status Code</label>\n            <div class=\"col-sm-2\">\n                <input type=\"text\" id=\"last_status_code\" class=\"form-control\" value=\"{{ $s.LastStatusCode }}\" readonly>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"col-12 mt-4\">\n        <h3>Edit Service</h3>\n        {{template \"form_service\" $s}}\n    </div>\n\n    <div class=\"col-12 mt-4\">\n        <h3>Service Checkin</h3>\n        <table class=\"table\">\n            <thead>\n                <tr>\n                    <th scope=\"col\">Checkin</th>\n                    <th scope=\"col\">Report Period<br>Grace Period</th>\n                    <th scope=\"col\">Last Seen</th>\n                    <th scope=\"col\">Expected</th>\n                </tr>\n            </thead>\n            <tbody>\n            {{range $s.Checkins}}\n            {{ $ch := . }}\n            <tr class=\"{{ if lt $ch.Expected 0}}bg-danger text-white{{else}}bg-light{{end}}\">\n                <td>{{CoreApp.Domain}}/checkin/{{$ch.ApiKey}}</td>\n                <td>every {{Duration $ch.Period}}<br>after {{Duration $ch.Grace}}</td>\n                <td>{{Ago $ch.Last.CreatedAt}}</td>\n                <td>{{ if lt $ch.Expected 0}}{{Duration $ch.Expected}} ago{{else}}in {{Duration $ch.Expected}}{{end}}</td>\n            </tr>\n            {{template \"form_checkin\" $ch}}\n            {{end}}\n            </tbody>\n        </table>\n\n    </div>\n\n{{end}}\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://assets.statup.io/pikaday.js\"></script>\n{{ else }}\n<script src=\"/js/pikaday.js\"></script>\n{{end}}\n{{$s := .Service}}\n<script>\n\n    var ctx = document.getElementById(\"service\").getContext('2d');\n\n    var chartdata = new Chart(ctx, {\n        type: 'line',\n        data: {\n            datasets: [{\n                label: 'Response Time (Milliseconds)',\n                data: [],\n                backgroundColor: [\n                    'rgba(47, 206, 30, 0.92)'\n                ],\n                borderColor: [\n                    'rgb(47, 171, 34)'\n                ],\n                borderWidth: 1\n            }]\n        },\n        options: {\n            legend: {\n                display: false\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    },\n                    gridLines: {\n                        display: true\n                    }\n                }],\n                xAxes: [{\n                    type: 'time',\n                    distribution: 'series',\n                    time: {\n                        displayFormats: {\n                            'millisecond': 'MMM DD',\n                            'second': 'MMM DD',\n                            'minute': 'MMM DD',\n                            'hour': 'MMM DD hA',\n                            'day': 'MMM DD',\n                            'week': 'MMM DD',\n                            'month': 'MMM DD',\n                            'quarter': 'MMM DD',\n                            'year': 'MMM DD',\n                        }\n                    },\n                    gridLines: {\n                        display: true\n                    },\n                    ticks: {\n                        source: 'auto'\n                    }\n                }],\n            },\n            elements: {\n                point: {\n                    radius: 0\n                }\n            }\n        }\n    });\n\n\n    var startPick = new Pikaday({\n        field: $('#service_start')[0],\n        bound: false,\n        trigger: $(\"#start_date\"),\n        container: $(\"#start_container\")[0],\n        maxDate: new Date(),\n        onSelect: function(date) {\n            $('#service_start')[0].value = Math.round(date.getTime() / 1000);\n            this.hide();\n        }\n    });\n\n    var endPick = new Pikaday({\n        field: $('#service_end')[0],\n        bound: false,\n        trigger: $(\"#end_date\"),\n        container: $(\"#end_container\")[0],\n        maxDate: new Date(),\n        onSelect: function(date) {\n            $('#service_end')[0].value = Math.round(date.getTime() / 1000);\n            this.hide();\n        }\n    });\n\n    startPick.setDate(new Date({{.Start}}*1000));\n    endPick.setDate(new Date({{.End}}*1000));\n\n    startPick.hide()\n    endPick.hide()\n\n    $(\"#start_date\").click(function(e) {\n        startPick.show()\n    })\n\n    $(\"#end_date\").click(function(e) {\n        endPick.show()\n    })\n\n    AjaxChart(chartdata,{{$s.Id}},{{.Start}},{{.End}},\"hour\");\n\n</script>\n{{end}}\n"),
301
        }
302
        file14 := &embedded.EmbeddedFile{
303
                Filename:    "services.html",
304
                FileModTime: time.Unix(1538459465, 0),
305
                Content:     string("{{define \"title\"}}Statup | Services{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n\n    <div class=\"col-12\">\n\n        <h3>Services</h3>\n\n        <table class=\"table\">\n            <thead>\n            <tr>\n                <th scope=\"col\">Name</th>\n                <th scope=\"col\" class=\"d-none d-md-table-cell\">Status</th>\n                <th scope=\"col\"></th>\n            </tr>\n            </thead>\n            <tbody class=\"sortable\">\n            {{range .}}\n            <tr id=\"{{.Id}}\">\n                <td><span class=\"drag_icon d-none d-md-inline\">&#9776;</span> {{.Name}}</td>\n                <td class=\"d-none d-md-table-cell\">{{if .Online}}<span class=\"badge badge-success\">ONLINE</span>{{else}}<span class=\"badge badge-danger\">OFFLINE</span>{{end}} </td>\n                <td class=\"text-right\">\n                    <div class=\"btn-group\">\n                        <a href=\"/service/{{.Id}}\" class=\"btn btn-primary\">View</a>\n                        <a href=\"/service/{{.Id}}/delete\" class=\"btn btn-danger confirm-btn\">Delete</a>\n                    </div>\n                </td>\n            </tr>\n            {{end}}\n            </tbody>\n        </table>\n\n        <h3>Create Service</h3>\n\n        {{template \"form_service\" NewService}}\n\n    </div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://assets.statup.io/sortable.min.js\"></script>\n{{ else }}\n<script src=\"/js/sortable.min.js\"></script>\n{{end}}\n<script>\n    sortable('.sortable', {\n        forcePlaceholderSize: true,\n        hoverClass: 'sortable_drag',\n        handle: '.drag_icon'\n    });\n    sortable('.sortable')[0].addEventListener('sortupdate', function(e) {\n        var i = 0;\n        var newOrder = [];\n        var dest = e.detail.destination.items;\n        dest.forEach(function(d) {\n            i++;\n            var o = {service: parseInt(d.id), order: i}\n            newOrder.push(o);\n        });\n        $.post(\"/services/reorder\", JSON.stringify(newOrder), function(data, status){\n        });\n    });\n</script>\n{{end}}\n"),
306
        }
307
        file15 := &embedded.EmbeddedFile{
308
                Filename:    "settings.html",
309
                FileModTime: time.Unix(1538459624, 0),
310
                Content:     string("{{define \"title\"}}Statup | Settings{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <div class=\"row\">\n            <div class=\"col-md-3 col-sm-12 mb-4 mb-md-0\">\n                <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n                    <a class=\"nav-link active\" id=\"v-pills-home-tab\" data-toggle=\"pill\" href=\"#v-pills-home\" role=\"tab\" aria-controls=\"v-pills-home\" aria-selected=\"true\">Settings</a>\n                    <a class=\"nav-link\" id=\"v-pills-style-tab\" data-toggle=\"pill\" href=\"#v-pills-style\" role=\"tab\" aria-controls=\"v-pills-style\" aria-selected=\"false\">Theme Editor</a>\n                {{ range .Notifications }}\n                    <a class=\"nav-link text-capitalize\" id=\"v-pills-{{underscore .Select.Method}}-tab\" data-toggle=\"pill\" href=\"#v-pills-{{underscore .Select.Method}}\" role=\"tab\" aria-controls=\"v-pills-{{underscore .Select.Method}}\" aria-selected=\"false\">{{.Select.Method}} <span class=\"badge badge-pill badge-secondary\"></span></a>\n                {{ end }}\n                    <a class=\"nav-link\" id=\"v-pills-browse-tab\" data-toggle=\"pill\" href=\"#v-pills-browse\" role=\"tab\" aria-controls=\"v-pills-home\" aria-selected=\"false\">Browse Plugins</a>\n                    <a class=\"nav-link d-none\" id=\"v-pills-backups-tab\" data-toggle=\"pill\" href=\"#v-pills-backups\" role=\"tab\" aria-controls=\"v-pills-backups\" aria-selected=\"false\">Backups</a>\n                {{ range .Plugins }}\n                    <a class=\"nav-link text-capitalize\" id=\"v-pills-{{underscore .Name}}-tab\" data-toggle=\"pill\" href=\"#v-pills-{{underscore .Name}}\" role=\"tab\" aria-controls=\"v-pills-profile\" aria-selected=\"false\">{{.Name}}</a>\n                {{end}}\n                </div>\n            </div>\n            <div class=\"col-md-8 col-sm-12\">\n            {{if Error}}\n                <div class=\"alert alert-danger\" role=\"alert\">{{Error}}</div>\n            {{end}}\n                <div class=\"tab-content\" id=\"v-pills-tabContent\">\n                    <div class=\"tab-pane fade show active\" id=\"v-pills-home\" role=\"tabpanel\" aria-labelledby=\"v-pills-home-tab\">\n                        <h3>Settings</h3>\n\n                        <form method=\"POST\" action=\"/settings\">\n\n                            <div class=\"form-group\">\n                                <label for=\"project\">Project Name</label>\n                                <input type=\"text\" name=\"project\" class=\"form-control\" value=\"{{ .Name }}\" id=\"project\" placeholder=\"Great Uptime\">\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"description\">Project Description</label>\n                                <input type=\"text\" name=\"description\" class=\"form-control\" value=\"{{ .Description }}\" id=\"description\" placeholder=\"Great Uptime\">\n                            </div>\n\n                            <div class=\"form-group row\">\n                                <div class=\"col-8 col-sm-9\">\n                                    <label for=\"domain\">Domain</label>\n                                    <input type=\"text\" name=\"domain\" class=\"form-control\" value=\"{{ .Domain }}\" id=\"domain\">\n                                </div>\n                                <div class=\"col-4 col-sm-3 mt-sm-1 mt-0\">\n                                    <label for=\"enable_cdn\" class=\"d-inline d-sm-none\">Enable CDN</label>\n                                    <label for=\"enable_cdn\" class=\"d-none d-sm-block\">Enable CDN</label>\n                                    <span class=\"switch\">\n                                <input type=\"checkbox\" name=\"enable_cdn\" class=\"switch\" id=\"switch-normal\" {{if USE_CDN}}checked{{end}}{{if .UsingAssets}} disabled{{end}}>\n                                <label for=\"switch-normal\" class=\"mt-2 mt-sm-0\"></label>\n                              </span>\n                                </div>\n\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"footer\">Custom Footer</label>\n                                <textarea rows=\"4\" name=\"footer\" class=\"form-control\" id=\"footer\">{{ .Footer }}</textarea>\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"timezone\">Timezone</label><span class=\"mt-1 small float-right\">Current: {{.CurrentTime}}</span>\n                                <select class=\"form-control\" name=\"timezone\" id=\"timezone\">\n                                    <option value=\"-12.0\" {{if eq (ToString .Timezone) \"-12\"}}selected{{end}}>(GMT -12:00) Eniwetok, Kwajalein</option>\n                                    <option value=\"-11.0\" {{if eq (ToString .Timezone) \"-11\"}}selected{{end}}>(GMT -11:00) Midway Island, Samoa</option>\n                                    <option value=\"-10.0\" {{if eq (ToString .Timezone) \"-10\"}}selected{{end}}>(GMT -10:00) Hawaii</option>\n                                    <option value=\"-9.0\" {{if eq (ToString .Timezone) \"-9\"}}selected{{end}}>(GMT -9:00) Alaska</option>\n                                    <option value=\"-8.0\" {{if eq (ToString .Timezone) \"-8\"}}selected{{end}}>(GMT -8:00) Pacific Time (US &amp; Canada)</option>\n                                    <option value=\"-7.0\" {{if eq (ToString .Timezone) \"-7\"}}selected{{end}}>(GMT -7:00) Mountain Time (US &amp; Canada)</option>\n                                    <option value=\"-6.0\" {{if eq (ToString .Timezone) \"-6\"}}selected{{end}}>(GMT -6:00) Central Time (US &amp; Canada), Mexico City</option>\n                                    <option value=\"-5.0\" {{if eq (ToString .Timezone) \"-5\"}}selected{{end}}>(GMT -5:00) Eastern Time (US &amp; Canada), Bogota, Lima</option>\n                                    <option value=\"-4.0\" {{if eq (ToString .Timezone) \"-4\"}}selected{{end}}>(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option>\n                                    <option value=\"-3.5\" {{if eq (ToString .Timezone) \"-3.5\"}}selected{{end}}>(GMT -3:30) Newfoundland</option>\n                                    <option value=\"-3.0\" {{if eq (ToString .Timezone) \"-3\"}}selected{{end}}>(GMT -3:00) Brazil, Buenos Aires, Georgetown</option>\n                                    <option value=\"-2.0\" {{if eq (ToString .Timezone) \"-2\"}}selected{{end}}>(GMT -2:00) Mid-Atlantic</option>\n                                    <option value=\"-1.0\" {{if eq (ToString .Timezone) \"-1\"}}selected{{end}}>(GMT -1:00 hour) Azores, Cape Verde Islands</option>\n                                    <option value=\"0.0\" {{if eq (ToString .Timezone) \"0\"}}selected{{end}}>(GMT) Western Europe Time, London, Lisbon, Casablanca</option>\n                                    <option value=\"1.0\" {{if eq (ToString .Timezone) \"1\"}}selected{{end}}>(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris</option>\n                                    <option value=\"2.0\" {{if eq (ToString .Timezone) \"2\"}}selected{{end}}>(GMT +2:00) Kaliningrad, South Africa</option>\n                                    <option value=\"3.0\" {{if eq (ToString .Timezone) \"3\"}}selected{{end}}>(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option>\n                                    <option value=\"3.5\" {{if eq (ToString .Timezone) \"3.5\"}}selected{{end}}>(GMT +3:30) Tehran</option>\n                                    <option value=\"4.0\" {{if eq (ToString .Timezone) \"4\"}}selected{{end}}>(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option>\n                                    <option value=\"4.5\" {{if eq (ToString .Timezone) \"4.5\"}}selected{{end}}>(GMT +4:30) Kabul</option>\n                                    <option value=\"5.0\" {{if eq (ToString .Timezone) \"5\"}}selected{{end}}>(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option>\n                                    <option value=\"5.5\" {{if eq (ToString .Timezone) \"5.5\"}}selected{{end}}>(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option>\n                                    <option value=\"5.75\" {{if eq (ToString .Timezone) \"5.75\"}}selected{{end}}>(GMT +5:45) Kathmandu</option>\n                                    <option value=\"6.0\" {{if eq (ToString .Timezone) \"6\"}}selected{{end}}>(GMT +6:00) Almaty, Dhaka, Colombo</option>\n                                    <option value=\"7.0\" {{if eq (ToString .Timezone) \"7\"}}selected{{end}}>(GMT +7:00) Bangkok, Hanoi, Jakarta</option>\n                                    <option value=\"8.0\" {{if eq (ToString .Timezone) \"8\"}}selected{{end}}>(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option>\n                                    <option value=\"9.0\" {{if eq (ToString .Timezone) \"9\"}}selected{{end}}>(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option>\n                                    <option value=\"9.5\" {{if eq (ToString .Timezone) \"9.5\"}}selected{{end}}>(GMT +9:30) Adelaide, Darwin</option>\n                                    <option value=\"10.0\" {{if eq (ToString .Timezone) \"10.5\"}}selected{{end}}>(GMT +10:00) Eastern Australia, Guam, Vladivostok</option>\n                                    <option value=\"11.0\" {{if eq (ToString .Timezone) \"11\"}}selected{{end}}>(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option>\n                                    <option value=\"12.0\" {{if eq (ToString .Timezone) \"12\"}}selected{{end}}>(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka</option>\n                                </select>\n                            </div>\n\n                            <button type=\"submit\" class=\"btn btn-primary btn-block\">Save Settings</button>\n\n                            <div class=\"form-group row mt-3\">\n                                <label for=\"api_key\" class=\"col-sm-3 col-form-label\">API Key</label>\n                                <div class=\"col-sm-9\">\n                                    <input type=\"text\" class=\"form-control select-input\" value=\"{{ .ApiKey }}\" id=\"api_key\" readonly>\n                                </div>\n                            </div>\n\n                            <div class=\"form-group row\">\n                                <label for=\"api_secret\" class=\"col-sm-3 col-form-label\">API Secret</label>\n                                <div class=\"col-sm-9\">\n                                    <input type=\"text\" class=\"form-control select-input\" value=\"{{ .ApiSecret }}\" id=\"api_secret\" readonly>\n                                    <small class=\"form-text text-muted\">You can <a href=\"/api/renew\">Regenerate API Keys</a> if you need to.</small>\n                                </div>\n                            </div>\n\n                            <div class=\"row\">\n                                <a href=\"/settings/export\" class=\"btn btn-sm btn-secondary float-right\">Export Settings</a>\n                            </div>\n\n                        </form>\n\n                    </div>\n\n                    <div class=\"tab-pane\" id=\"v-pills-style\" role=\"tabpanel\" aria-labelledby=\"v-pills-style-tab\">\n\n                    {{if not .UsingAssets }}\n                        <a href=\"/settings/build\" class=\"btn btn-primary btn-block\"{{if USE_CDN}} disabled{{end}}>Enable Local Assets</a>\n                    {{ else }}\n                        <form method=\"POST\" action=\"/settings/css\">\n                            <ul class=\"nav nav-pills mb-3\" id=\"pills-tab\" role=\"tablist\">\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link active\" id=\"pills-vars-tab\" data-toggle=\"pill\" href=\"#pills-vars\" role=\"tab\" aria-controls=\"pills-vars\" aria-selected=\"true\">Variables</a>\n                                </li>\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link\" id=\"pills-theme-tab\" data-toggle=\"pill\" href=\"#pills-theme\" role=\"tab\" aria-controls=\"pills-theme\" aria-selected=\"false\">Base Theme</a>\n                                </li>\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link\" id=\"pills-mobile-tab\" data-toggle=\"pill\" href=\"#pills-mobile\" role=\"tab\" aria-controls=\"pills-mobile\" aria-selected=\"false\">Mobile</a>\n                                </li>\n                            </ul>\n                            <div class=\"tab-content\" id=\"pills-tabContent\">\n                                <div class=\"tab-pane show active\" id=\"pills-vars\" role=\"tabpanel\" aria-labelledby=\"pills-vars-tab\">\n                                    <textarea name=\"variables\" id=\"sass_vars\">{{ .SassVars }}</textarea>\n                                </div>\n                                <div class=\"tab-pane\" id=\"pills-theme\" role=\"tabpanel\" aria-labelledby=\"pills-theme-tab\">\n                                    <textarea name=\"theme\" id=\"theme_css\">{{ .BaseSASS }}</textarea>\n                                </div>\n                                <div class=\"tab-pane\" id=\"pills-mobile\" role=\"tabpanel\" aria-labelledby=\"pills-mobile-tab\">\n                                    <textarea name=\"mobile\" id=\"mobile_css\">{{ .MobileSASS }}</textarea>\n                                </div>\n                            </div>\n                            <button type=\"submit\" class=\"btn btn-primary btn-block mt-2\">Save Style</button>\n                            <a href=\"/settings/delete_assets\" class=\"btn btn-danger btn-block confirm-btn\">Delete All Assets</a>\n                        </form>\n                    {{end}}\n                    </div>\n\n                {{ range .Notifications }}\n                {{$n := .Select}}\n                    <div class=\"tab-pane\" id=\"v-pills-{{underscore $n.Method}}\" role=\"tabpanel\" aria-labelledby=\"v-pills-{{underscore $n.Method }}-tab\">\n\n                    {{template \"form_notifier\" .}}\n\n                    {{ if $n.Logs }}\n                        Sent {{$n.SentLastHour}} in the last hour<br>\n                    {{ range $n.Logs }}\n                        <div class=\"card mt-1\">\n                            <div class=\"card-body\">\n                            {{.Message}}\n                                <p class=\"card-text\"><small class=\"text-muted\">Sent {{.Time.Ago}}</small></p>\n                            </div>\n                        </div>\n                    {{ end }}\n                    {{ end }}\n                    </div>\n                {{ end }}\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-browse\" role=\"tabpanel\" aria-labelledby=\"v-pills-browse-tab\">\n                    {{ range .Repos }}\n                        <div class=\"card col-6\" style=\"width: 18rem;\">\n                            <div class=\"card-body\">\n                                <h5 class=\"card-title\">{{ .Name }}</h5>\n                                <p class=\"card-text\">{{ .Description }}</p>\n                                <a href=\"/plugins/download/{{ .Name }}\" class=\"card-link\">Add</a>\n                            </div>\n                        </div>\n                    {{ end }}\n                    </div>\n\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-backups\" role=\"tabpanel\" aria-labelledby=\"v-pills-backups-tab\">\n                        <a href=\"/backups/create\" class=\"btn btn-primary btn-block\">Backup Database</a>\n                    </div>\n\n                {{ range .Plugins }}\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-{{underscore .Name}}\" role=\"tabpanel\" aria-labelledby=\"v-pills-{{underscore .Name}}-tab\">\n\n                        <h4 class=\"text-capitalize\">{{ .Name }}</h4>\n                        <span class=\"text-muted\">{{ .Description }}</span>\n\n                        <div class=\"mt-1\">\n                        {{ safe .Form }}\n                        </div>\n\n                    </div>\n                {{end}}\n\n                </div>\n            </div>\n\n        </div>\n    </div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<link rel=\"stylesheet\" href=\"https://assets.statup.io/codemirror.css\">\n<link rel=\"stylesheet\" href=\"https://assets.statup.io/codemirror-colorpicker.css\"/>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"https://assets.statup.io/codemirror.js\"></script>\n<script src=\"https://assets.statup.io/css.js\"></script>\n<script src=\"https://assets.statup.io/codemirror-colorpicker.min.js\"></script>\n{{end}}\n"),
311
        }
312
        file16 := &embedded.EmbeddedFile{
313
                Filename:    "setup.html",
314
                FileModTime: time.Unix(1538459628, 0),
315
                Content:     string("{{define \"title\"}}Statup | Setup{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-4 offset-4 mt-2 mb-5\"><img width=\"100%\" src=\"/statup.png\"></div>\n    <div class=\"col-12\">\n    {{ if .Error }}\n        <div class=\"alert alert-danger\" role=\"alert\">\n        {{ .Error }}\n        </div>\n    {{ end }}\n        <form method=\"POST\" id=\"setup_form\" action=\"/setup\">\n            <div class=\"row\">\n                <div class=\"col-6\">\n                    <div class=\"form-group\">\n                        <label for=\"inputState\">Database Connection</label>\n                        <select id=\"database_type\" name=\"db_connection\" class=\"form-control\">\n                            <option selected value=\"postgres\">Postgres</option>\n                            <option value=\"sqlite\">Sqlite</option>\n                            <option value=\"mysql\">MySQL</option>\n                        </select>\n                    </div>\n                    <div class=\"form-group\" id=\"db_host\">\n                        <label for=\"db_host_in\">Host</label>\n                        <input type=\"text\" name=\"db_host\" id=\"db_host_in\" class=\"form-control\" value=\"{{.DbHost}}\" placeholder=\"localhost\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_port\">\n                        <label for=\"db_port_in\">Database Port</label>\n                        <input type=\"text\" name=\"db_port\" id=\"db_port_in\" class=\"form-control\" value=\"{{.DbPort}}\" placeholder=\"localhost\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_user\">\n                        <label for=\"db_user_in\">Username</label>\n                        <input type=\"text\" name=\"db_user\" id=\"db_user_in\" class=\"form-control\" value=\"{{.DbUser}}\" placeholder=\"root\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_password\">\n                        <label for=\"db_password\">Password</label>\n                        <input type=\"password\" name=\"db_password\" class=\"form-control\" value=\"{{.DbPass}}\" id=\"db_password\" placeholder=\"password123\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_database\">\n                        <label for=\"db_database\">Database</label>\n                        <input type=\"text\" name=\"db_database\" class=\"form-control\" value=\"{{.DbData}}\" id=\"db_database\" placeholder=\"Database name\">\n                    </div>\n\n                </div>\n\n                <div class=\"col-6\">\n\n                    <div class=\"form-group\">\n                        <label for=\"project\">Project Name</label>\n                        <input type=\"text\" name=\"project\" class=\"form-control\" value=\"{{.Project}}\" id=\"project\" placeholder=\"Great Uptime\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"description\">Project Description</label>\n                        <input type=\"text\" name=\"description\" class=\"form-control\" value=\"{{.Description}}\" id=\"description\" placeholder=\"Great Uptime\">\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"domain_input\">Domain URL</label>\n                        <input type=\"text\" name=\"domain\" class=\"form-control\" value=\"{{.Domain}}\" id=\"domain_input\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"username\">Admin Username</label>\n                        <input type=\"text\" name=\"username\" class=\"form-control\" value=\"{{.Username}}\" id=\"username\" value=\"admin\" placeholder=\"admin\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"email\">Admin Email Address</label>\n                        <input type=\"email\" name=\"email\" class=\"form-control\" value=\"{{.Email}}\" id=\"email\" placeholder=\"info@admin.com\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"password\">Admin Password</label>\n                        <input type=\"password\" name=\"password\" class=\"form-control\" value=\"{{.Password}}\" id=\"password\" placeholder=\"password\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n              <span class=\"switch\">\n                <input type=\"checkbox\" name=\"sample_data\" class=\"switch\" id=\"switch-normal\" checked>\n                <label for=\"switch-normal\">Load Sample Data</label>\n              </span>\n                    </div>\n\n                </div>\n                <button id=\"setup_button\" type=\"submit\" class=\"btn btn-primary btn-block disable_click\">Save Settings</button>\n            </div>\n        </form>\n    </div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"/js/setup.js\"></script>\n{{end}}\n"),
316
        }
317
        file17 := &embedded.EmbeddedFile{
318
                Filename:    "statup.png",
319
                FileModTime: time.Unix(1533786305, 0),
320
                Content:     string("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x90\x00\x00\x00|\b\x06\x00\x00\x00GN\xe6\x81\x00\x00\x01\x83iCCPsRGB IEC61966-2.1\x00\x00(\x91u\x91\xcf+\xc3a\x1c\xc7_\xdb\xc80MqppX\x1a\x17\x9bfjqQ&\xa1\xa45S\x86\xcb\xf6\xb5\x1fj?\xbe}\xbf\x93\xe4\xaa\\\x15%.~\x1d\xf8\v\xb8*g\xa5\x88\x94\x1c\x9c\x9c\x89\v\xeb\xeb\xf3\xb5Ֆ\xec\xf3\xf4y>\xaf\xe7\xfd<\x9fO\xcf\xf3y\xc0\x1a\xc9(Y\xbd\xce\a\xd9\\A\v\x8f\a]s\xd1yW\xc3\vv\x1a\xb1ы3\xa6\xe8\xeaH(4EM\xfb\xbc\xc7b\xc6[\xafY\xab\xf6\xb9\u007f\xady)\xa1+`\xb1\v\x0f+\xaaV\x10\x9e\x10\x9eZ-\xa8&\xef\b\xb7+\xe9ؒ\xf0\x99\xb0G\x93\v\nߙz\xbcį&\xa7J\xfcm\xb2\x16\t\x8f\x82\xb5Uؕ\xaa\xe2x\x15+i-+,/ǝͬ(\xe5\xfb\x98/q$r\xb33\x12\xbb\xc4;\xd1\t3N\x10\x17\x93\x8c1J\x80~\x86d\x0e\xe0\xc5O\x9f\xac\xa8\x91\xef\xfb͟&/\xb9\x8a\xcc*kh,\x93\"M\x01\x8f\xa8+R=!1)zBF\x865\xb3\xff\u007f\xfb\xaa'\a\xfc\xa5\xea\x8e \xd4?\x1b\xc6{74lCq\xcb0\xbe\x8e\f\xa3x\f\xb6'\xb8\xccU\xf2\xf3\x870\xf8!\xfaVEs\x1f\x80s\x03ί*Z|\x17.6\xa1\xe3Q\x8di\xb1_\xc9&nM&\xe1\xed\x14Z\xa2\xd0v\x03M\v\xa5\x9e\x95\xf79y\x80Ⱥ|\xd55\xec\xedC\x8f\x9cw.\xfe\x00\x1a\x80g\xc3\x17\xe1\xe9w\x00\x00\x00\tpHYs\x00\x00=\x84\x00\x00=\x84\x01լ\xaft\x00\x00 \x00IDATx\x9c\xec\xbdy\x98$Gu/\xfa\x8b\x88\xcc\xea\x9eю\x05H,\x12\b\x8cY\xb4\x8c4\x82ь\x84a$\xb8\x86\x87\xd9\xeck\x8c\xedk??\xaf`\xf9^\x1b\x84\x04\bc\xbc\x00bF#\xd9\xc6\x12\x8b\xfd\x8cͽ6B\xba\xc6\x17\x03\xc6\xd8\x06I\xc3&\x01\x96f\x1f6\vI#\t\x8df\xba\xa7\xf7\xae\xaǎ8\uf3ec\x93\xf5\xcb\xe8\xea\x99\xea\xeej\xeb\xcd\xf7\xd5\xf9\xbe\xfe\xba\xbb\x96\xcc\x13'N\x9c\xe5wND\x02C\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4\xe5\x93y\xbc\x198\x1e\xe85\xfb~\xf6CƘ\xd7\xe9\xff\"\x82\x10\x02\x8c1\xb0\xd6BD\x00\x00\xd6Zx\xef\xe1\x9cCQ\x14\xb0\xd6\"I\x12\x84\x10 \"0\xc6T\u007f;\xe7\xb2O?\xef\x96g<^c\x1a\xd2\xd2\xe8\xaa\x03\xd7\xfe\xa8\x88l\xef\xcc\x1d\x00\xd4\xe6\xd3Z\vkm5\xef\xde\xfb\xea\xb7\xea\x00\x80\xea\xbb!\x04ա\xf7\xddx\xf6u7?n\x03\x1bҐV@\xc9\xe3\xcd\xc0\xf1@ιS\xbd\xf7g\xaa\xe3h4\x1a0\xc6\xc0{\x0fcL\xe5\x1cԸ\xa8A1\xa6\xeb\x9fE\x04\"\x82$IP\x14\x05D${\x1c\x874\xa4\xa5S\x12B8\x93\x9d\x06\xcf=P:\x05\x9d\u007f\x0e.TO\xa2\x00\x02\xd6Z\xe4y~\xc2\xe3<\xae!\ri\xd9d\x1fo\x06\x8e\a*\x8a\xa22\b\x9a]\x88H\xe5H\xf4G3\x11\xfdl\xc7@\x00@͡8窈tH\xc7\ay\xef\x01\x00IR\xc6\\:\xe7\x00\xaay\xd7\xcfāD\x92$\x95ð\xb6\\r!\x04\xe4y^]oHC:\x1ei\xa8\xbd}\x90\x88\xfc\x98F\x93j4\x8c1\xc8\xf3\xbc\x8a*\xd90(\x94\xa1\x86C\xe1\x8c\x10B\x15\x8db(\xfb㊒\x89\xe4\xc9\xe1GB\xe5,8X\x88\x03\x03\xce:4+\x01P\xe9\x80~7I\x12\xf8\xa6\u007f\xfe\xe30\x9c!\ri 44b}\xd0\xdc\xec\xec\x8f$I\x02Ai$\x9csH\x92\xa42\x1c\x9c]\xa8\xf1P\xc7a\x8c\xa9\xfeN\xd3\x14y\x9e\xab\xa1\x19f\u007f\xc7\x11\xd9Y{BvJ\x86$I\xaa\fC\xeb\x18\xaa\v\x1a4\x88H-ke\x87\xa2\xce\x04(\xf5\x06s\xf2\xc4\xc7qXC\x1aҊh\xe8@\xfa\xa0v\xbb\x8d\xf9\xf9y8\xe7*\xa8\x8a!,\xeb\x1c\x1ai\x8a$M+\x98K\xb3\x0e\xfd\xac\x1a\x11\xa0[@\x1d\xd2\xf1C>\x94\x01\x80f\x97q\x93\x04\x80\xea=\xfd[\xe7\xdd\x18S\x05\x0f\xda|\x11B(\x9d\xcc\xe39\xa8!\ri\x854t }\x90\x16\xbf\xf5oŶ\xb3,\xab \x8c\xe6\xfc|\xe5 FFF\x90$\t\xacsH\x9c\x83\xeb@YZ\x84WhkH\xc7\x17i\x10\xa0p\xa5\xbe\x06\xa0\x06m*T\xa5\r\x13\x00jP\x16\xd0u0\x90\xff\xc4\x01\fiH\x03\xa6\xa1\x03Y\"\xa9q\x00\xea\xc6B\xdfS(\xc3{\xdf\x13\xea\xb0\xd6\"IS$C\ar\\\x911\x06\x82n\xfdC\xb3L\x00\v\x1c\x05\xb7\xeer&\xa2\xef+\f*\"(\x90?>\x03\x1aҐ\x06@C\a\xd2\a\xc5\x06@\xfb\xfb\xb5\x95\x97\xb3\v\xcdV\x14\xaa\xe0V_\xed\xba)\x8ab\ba\x1dgd`\xaa \x00(;\xf3\x14\x96Ү<\xaeq\xa8\x13Q\xbdQb\xe7!\"pf\x18H\f\xe9\xf8\xa5a!\xb7\x0fR\x87\xa1\x06\x847\x8e)\xe9\xfb\xfa\x9a\x1a\x14Żոp\xf7\u0590\x8e\x1f\x1a\x97#h\x86\x16rߝ;\x9dW\x00\xd5\xdcrV\xa2\u007fk\xa6\xaa\xdf\xe1v\xdf!\r\xe9x\xa6a\x06\xd2'\xa5iZ-~\x8e.\x15\xa2`H\x83\xdbv\xf5s\\|\x8f\x9dϐ\xfe\xffO\x87\xe40\\\xbbӎ\v\x8b\x11\xdb@jR\xacIGѰ#\x18A\xa3\xca.\x14\xb2T\xa7\xa2\x1dY\xdc\xf2\x9b\xe79\x1a\x8d\x06\n\x19BXC:~i\xe8@\xfa$\ue80ak\x1f\x9ay\x84\x10*GÝ6\xfa\xbef2\x00*\xcc|H\xc7\a%6\xa9\x0e\xfe\t\x120\xef\x9bp.\xc3Ts\xba\xac}\xc1 \xb5)Fl\x03\t\x12\xa4&\xc1\t#' A\xb2\xe0T\x02\xd5\r\xef=\x02\x86P搎_\x1a:\x90>I3\x8d4MὯ\xa2J\xdeX\xc6\xd1'CV\xba{\x1d\xe8\xc2\x19C\xf8\xe2\xf8\xa2 \x01\b\xf5F\t\x0e$\xac\xb5\xc8B\x86V\xd1꾖[H\x10\x8c\xba\x11\x8c&k\x90\"A\x82\x04k\x1bk鴂\xf4\xf1\x1eڐ\x86\xb4l\x1a:\x90>H\x8b\xe3i\x9a\xd6\x1c\x06\x1b\x13\x00\v:o\xb8\xc0\xaeQ\xa7b\xe3C\ar|Q\x90\x00#\xdd#k4(\xe0ڇ\xea\x03\xeb\x00\fЖ\f\xcdv\xab\xcaB\xc3\\@b\x124L\x8a\x864\x1e\xef\xa1\riH˦\xa1\x03\xe9\x83b\x87\xa0\x99FQ\x14h4\x1a\xb5\x13w\xb9\x88\xae\u007f3|\xa1\x1bІ5\x90\xe3\x93t\x9e\xb9\xee\xa5u.\xee\xd6\xe3\xf3\xb14\v\xd5\x1d\xea\"\x82`\x02\n[`\x16s\x8f\xe7p\x864\xa4\x15\xd1Њ\xf5Aj\x04ԑp\x1dDk\x1cj<\xf8o>\xad\x95\x1d\f\x1b\x9a!\x1d\x1f$\xe8\x1d\x1c\xf0\x916\x9cyhV\x1a\x9f\xdc\xcc\xd0\xe60\x13\x1d\xd2\xf1N\xff\xe9\x19ȋ\xbf\xf2\xf2\x91\x10\xc2\x05Ƙ\x17\x8a\xc8\x19\"r\x1a\x80\xd3\x00\x9c\xea\xbd?\xcd9w\x92\x88\x8c\x8bȣ\xd6\xdaGC\b\x8f:\xe7~\b\xe0Q\x11yTD\x1e5\xc6L}\xfd\xa5\xb7\xff\xa7\xad<\xed\xedg\xe7\xc1\xce@?\xc3\xceCq\xf0\xf8\xb0\xc5\xe3\xd9y\\r\xfbKM\x92$'\x15Eq\xa61\xe6Lk\xed\x99\xde\xfb3\x00xc\xccc\x00\x1eK\x92\xe41\xe7\xdc\xc1$M'\xbf\xf8\xc2\xcf\x1e\x9f\x03\xedA\xba_\x83aHv\x1c\x9a\x85\xd4\xe0+\xa0\xb6G\x84\x03\v\xa0\xb3)uXD\x1f\xd2Q\xe8-\x0f\xbcc$M\xd33\x8a\xa28\xc3Z{f\b\xe1\f\x00'Zk\x1f\x03\xf0\xc3\xceϣ!\x84\xa9\x1bϾ\xee?}\xbd\xad\xba\x03y\xd1\xe7_|\xa2I쫌3\x1b\xad\xb3\x1bB\b\x17y\xef\x1b\\/\x887]q\xa4\xaf\xbfy\xf3\x951\xa6y\xe9\xf6+\x0e\x00\xf87c\xccg\xf2<\xdf\xfe\x8d+\xb6\xaf\xda\xf35\xd8(\xf0\xa9\xbc\xf1\x06C\xc6\xc6\xe3\xd3{\xe3\xd3[\x8f\a'r\xe9\xf6+,\x80M\"\xf2\xd3\x00^\x01\xe0,\xef\xfdZ}_\xe7%.(\x03@\xbbݞ\xdax\xc7\xe6/\x18c>k\x8c\xf9篽\xe4KG\x1e\x9fQ\f\x86\x82\x04X\xb1\xb5\xac3M\xcb\x02\xb8\xea(\x80\x05\xcf\b\x01\xea\xc1\x05?K$\xee\xce\x1aҐ\xae:p\xad\x13\x91\x17\x03\xf8i\x00\xaf\x01p\x16\x9fr\xa0\xfa\xc5[\x05:\x01n\xf3\xea\x87\u007f\xef!\x11\xf9\x17c\xcc߇\x10\xbev\xc3Y\xef\xf7\xab\xcd\xef\xaai\xef\xba[6\\h\x8c\xf9\x8d\x10\xc2/\x008\xc9Z[\x9ef\x9bZ\x88\x11\xd8\xc4\xc1&\x06\xc6Y\xd8\xd4º\xae#ᣰ\x81n\xe7\vG\xf7@w\xb3^\ba\x06\xc0\x17\x92$\xf9l\b\xe1\xf3_{ɗƗ\xca\xef\xc6;6\xbf\xd3\x18\xf3T~\x96\x03\xdd\xff\x97\xbc\xf7'\x01\xa8\x15O9\xb3\xe0\x16\xdd$I\x90eY\xf5\f\x888*\xa5M\x897\xb3c\xe1\xf3\x93\xe2'\x1d\x02@\b\xe1\xe6\xbb6\xdf\xf1\xed\xe5\xcc\xc7\x12\xe4\x90\x18c^\xe2\xbd\xff\xe9F\xa3\xf1\xfa\x10\xc2\x19*g>\a\xaa\xd7ò8\x12\x8f\x8e\xee\b\xd6گy\xefo\x01\xf0Wwm\xbe\xa3\xa7\xb3\u007f\xf9\xb7^}j\x92\xa6\xefՆ\x05v\xb6*S\x85\x8c\xf8@J6\xda\xce9\xe4y^u\xcbu\xf8\xfe\xd6\xe7\xce\xfb\xdf\x1f?\xd6\xd8_\xb3\xefg/4\xc6\xfc*\x80Z\x06)\"\xf0E\xf1\f\x01^\xa5\x87e\xea\xd8\xe2L4\xe6\x87;\xf2\xb8C\x8f\x8ev\u007f0I\x92\xcfq\r%\xbe\x16\xcb\xdc{\xff\x83ϼ\xe0\xd6\x1b\x17\x1bë\xf7\xbe\xe14\x11\xf9\xe3Z\xf3\x86\x0f\x18IF\xb0&\x19E\x82\xa4\xb3w\xa5\x01\x87\xee\xaey\x1dW\xaf\xa0\xads\xdf/\xfc\xe93\xb7|\xeeX2\\*\xbd\xed\xa1w\xfd\xa4\x88\xbc\x82\x1f\x83\xd0h4j\xf2\x8b[\xe6\xb5\xf6č-\xac\x9b\x9d\xef\xbe\xfb\x86\xb3\xde?\xb1\f~\x9e\x0e\xe0\xed\xbc\x11\xb8ױD<'|\xce\x19\xf3\xc7\xf3o\x8c\xf9\xfb\x1b\xcez\xff\x9d\x8b\xdd\xf7\xaa\x03\xd7^\x1aB\xf8ec\xcckE\xe4\x89z/\x9d\u007f\xd6i]\x0f\x00\xaa\xff{<n␈\xfc\x1f\x11\xf9\x14\x80;o<\xfb\xbaU\xd9p4\xd0\f\xe4\xfc\xbf{\xa1\xb1\xd6\xfe\xbcs\xeew\x8b\xa2\xb8\x98\x8d\xa3\x0e\xaehw\x1e\xf9\x99\x15P\xf7(\"0\xd6\xc0:\x8b\xdce0\xce\"i8\x04\blb\xe1RW\xedގ\x1f\x17\xda9!\xf5\xa4\xa2(~&˲\x9f\xb1ֆ˾\xfc\xb2\xafz\xef?+\"\x9f\xb9\xfb\xf2;\xbf\xd7'\xfbo4Ɯ\xaf]U\xec\xdd\xe33\x8d\xb8xʝV:V\xfd>\x1bY\x86<\xe8T\xdf+\xe3hU\x9d\x90^+\x8ah?\x03`U\x1c\xc8e_~\x99\r!\xfc\x82\x88\\\a\xe0\xa9\xec\x10u\x11\xa5iZ9F]б\xa2\xf3i\xb4@\xf5\x00&[\x14ŋ\x01\xbc\xd8Z\xfb֍wl~\a\x80\u007f\xb8k\xf3\x1d\xb54l~~~-\x80+yߌ\xe9\x9cd\x9bt\x1c\n\x9f\x88\xcc\xd9\x1do\xd2\xe3\xf6\xe9,\xcb\x00\xe0o\x01\x1cӁ\x88ȳ\xac\xb5W\xeai\x01z\u007fc\f\x92N\xb6\xc1N@\xef\xa5G\xf4s\xa0\xa3r\x8b\xa1K\x86\xaf:\x06\xe6l\xef\xfd\x95\xcas\xecd\xf4\xbb\xb41\xf1k\x00\x16u I\x92\x9cX\x14ŕ|?\x978\xe4\x92Wss$\xef<\x8f\xc4:\xa4&Ej\x1ah\x98\x14k\xd25\x18MF ^ju\x9a\xce؎\x00\x18\xb8\x03\t!l0\xc6\\\xa9\x81\x197\xa4\xa8\x9c8p\x8ce\xbbXSJ\b\xe1\x03\x00\x96\xec@D\xe4\x89y\x9e_\x19\xef\xe7\x8aϼ\x03P\xdbL\x1cw\xe1\xe9\xba \xe4\xe4\xbb\x00\xee\x8c\xefwՁk\x9f$\"۬\xb5\xbf\xa8\xaf\xc5M\x19\xba\x06\xd8Yęl|\xc8g\b\xe1I\x00~\xd3\x18\xf3\x9b\xde\xfb\x83W?\xfc{\xef\x12\x91\x8fo{\xfa\xfb\x06\x9a\x95\f́\xac\xbfmӳC\b\x1f5\xc6\\\x0et\x9dF\xbc0\x948z\x04\x00\b\xe0s\x0f\xeb-\U000a2342&\xa3\xed,`\x00\xd7p\x10\x03$\x8d\x04H\x05\xd6ؚ\x92w&\xda\xe6y\xfe\xe3\xd6\xda\x1fw\xce\xfdѦ;/?\xfb\xeb/\xbd\xfd\xf0\xb1\xf8W\xc3\xcfg\x15\xf1\x02\xe6\xdf\x00j\x8a\x1e;J&\x8e^\xf4\x1al\x10XI\x81\xfaa\x8d\xfa}\x8e\x86W\x83.\xdd~\xc5\x06\xef\xfd\x9f\x19c60\xb4\xc8{]4\xcaS\x83\xaa<\xb2\x93\xe1(\x8d\x1dk\xa4\xf4\xcf\x0e!\xfc}\x92$_\xbf\xec\xcb/\xbb\xea\xab?\xfeŻ\x95\x0f\x96\x1d\xcb\xc9{\x0f\x9beh\xb7\xdbUf\xa2\x11s\xa3\xd1\x00\x8cA#Ma\xe8\x18\xfd^O\x82<\x16q@\xc0\xed\xd6\xec\xfc\xf5s\\\xe3P^\xf4o5\x8414\xcb:\xc0\x0e*v.\xea\xfcT\xbe\x9c\xb1\xf43\x16\x8e\x8e\xf5\xfaz\x0e\x1b\xeb].\x82\xc2x4\xd1*\xf9\xca:|\xc2am\xba\x06#n\x04)\x12\x8c\x98\x11$f\xf5\xd0n\xd57]{\xbc\xc9V\u05f7\x8e\x8b#m\x96\v\x1bU\x96\xc1r\xa8\xd1hTs\xa7\xd7b\x9d\xd6y\xe09\xe4\xac(\xce^{\xf1\xf3\x96\a\xdea\xad\xb5\xbf\xe6\x9c\xdbR\x14ũ\xbc\xe6ئ0\"\xa1\xa4\xd7繌\xb3V\xb5g\x9d\x03\\\xcf\b!\xfc\x951淯:p\xed[n8\xeb\xfdۗ-\x9c\x88V\xac\x15\xebnِ\x1ac\xde\x1aB\xf8\x03\xe7ܨ\nZ\x15\x9d'\x9f\x85\xcf\xca͆\x9a\x0f)LӴ\x9b\x1a\xfa\x00\xdf*\xaf՜ͺ\x11\x9a\x01`\r\x92\xd4\xc1$\x16\x05\n4FS\x04/\xf0\xe2\xff\xfc\xee\xcb\xef<\xa6\xf3\xe8\xf0y\x12G]\xf1B娗\x8dk\x1c\x19\xc4Q\xa3\x8e=\xce^⬅\xe5\xc0\xd1t䐞\xb0\x94\xb99\x16]r\xfbK\x9f✻\xce{\xffKl\xf8\xd9\xc11?l4\xe3\b\x95ǯ\xaf\xf1\xd8\xe2\xa8]D6\x85\x10\xee\xbat\xfb\x15\xef,\x8ab\xcb7\xae\xd8.\"\xb2\x86#>\x951\x00dYV3\x12*\xc7N\x86Q\x9b'\x97$H\x9c\xab\x9e\xd3⒤\xaf\x876\x15Eq\xba\xf2\xaf5\x0e\xe6[\xefφCOX\xd6,\x84!P\x86?\xd4\x18\xf1w\x81\xfa\x13,\xd9\xc1\xa8#d\xdd\x01\x00\xef\xfd\xa9G\x1bC\ba-\xf3\xaa\x86.\x1e\vߋ\xb3M\x00\xf0\xf0\x98\xcef`\xed\\\xf5\xd9\"/\x9e\u070f\f\x97J\x12\u0093\x04]|_\r\xa8\xcaPu\xa9(\n\xe4y^\x83*u\x9d\xaa\x91\xe5CLMn\xd6,\x8f!\x9c\xac\xc0>w\xc9Yk+\xb8\x8c!I\x9d\x1f\x9d\xff\xc5\x1an:\x19\x01\x00\xe0w\xef\u007f\xfb\xe9Ƙ\u007f\f!l\xe2\xb5\x1e;\x1d^C\x1c\xa8\xa8L\xd8np\xe0\xa9<\xaan\x12\xfcw\xa1\x88\xdcyՁk?彿\xe6O\x9f\xb9\xe5\a˒\x11ъ\xdax\xd7ݲ\xe1\x04\x11\xf9\x17\x11\xf9\x801f\x94#\a\x1e\x98\xa6\xf7*\x98\x18\x12b\x83\xa5\xdf\xe1\xf7c\xd8@\x1d\x8b\xb5\xe5N_)\x02\xdasm\xe4\xb3\x19\xfcl\x81\xe6X\x13s\ag\xe7\xe6\x0f\xce\xdd\xd0\xefX\x9csg*\xdfqڪ\x8b_\xf9P\xc3\x16\xd7A\x98_}\x8d\x15\n@\xedh\x13&UN\xbd6;^\xfd\xed\xbd\u007f\xe6\x92&\xe8(t\xe9\xf6+^f\x8c\xf9\xb6\x88\xfc\x12G\xf5\f\x9fċ 6>\x1c\xe9ğ\xd7\xf7Y\xa9y\xfe\x81*\x8b\xbb\xceZ\xfb\x91\r_zI\"\x82\x935p\x88\x83\f\x86\vظ\xe8\xb5\xf5\x9aY\x96!\xcf24\x9bM\xcc\xcd\xce\xe2ȑ#8\xf4\xd8c\xcf\xe9K(3x\xb6\x1aw5\xaal\xfc\x95\x8e\x96MƵ\x04\xd6e\x00\xb5\xbf9\x9bS\xe3\xa7\u007f\xeb\xbc\xf7\x88d\x9f~\xb4!\x98\xc7̩U\xd6ֹ\xd7b\xcf]\xd79U\xa3\xcdđ\xbd\xf7\x1e\xe2\xe5y}\xc9p\x89df\xec\xf3u-\x03u\x990\x1fI\x92T\x0f\xf4\x8a\x8d(;\xe1ꨠ\xfb\x8b\xa3:\xda\xc5\xc8\xdf_<\x05@\xd5 \xa1\xcf\xeea\xdd\xd6\a\x8a\x01\xdd.;\xe5_y\x88\xb3E;n\x9f\v\x00o{\xe8]\xa7;\xe7\xbe\xe4\x9c\xdb\xc4\xc1\x15\xaf\x0f\xbe\x9f^Gu\"FC4@\xe0\xb5\xc0\xd7d9Қ\xfaik\xed\xfe\xab\x0e\\\xfbsˑ\x11Ӳ\x1d\xc8\xfa\xdb6\x9d`\xad\xfd\xac\xb5vs< ]\x80* \x15h/\xac\\'\n\xe8\x1aW6`l4\xf4>z\x94\bg3\xbc\xe0;\x8b\xf6\x04\xd9U\xec:\xef\xed\x17\xf6\x15}f\xb3\x19|\xdb\xc3\xe7\xdd\xe8\x93k-\xb13\xe4\xa8M\xef\xa9\xca̐]\x8cѦiZ\xdb\xd1\xceO\xb9\xd3\xcf\xe88\xb8\x96°\xd6Jiӝ\x97\xff\xb7\x10\xc2?\x1bcN\x0e! ˲ZQ\x12\xe8B\x8b\xbaX\x81n\xbb*\xcf+G\x83*\v\x9d\x13\xae\v\xb0NT\x10J\xa7\xae\xe5\x9c\xfb\x8d\xb2\x01\u009f\xc8Ή\xe1\n\xfdn\xbc\x9f\"vP\xf1\"\xeb\x05+.FM4\xd1j\xb5j\x90#G\xba<\x8e8\xc8QC\xad\xf3\xceQ!\xcf+\xcb6v\xd0lH\xf5s\f\xa3\xf43\x96\"t\x9d\xb9\xae\x11>\xccQ\xe7Q\xc7\xc1\xb5E%\xd5\xedŲ\xf1AS\xac\xdfq\xb0\t\xa0f\x94UO\xf5o\x96?G\xdc\xcb!g]Mf\f)\xe9\xcf\xc8\xc8H5\x1f\xbc^\xe2Z\t;\x06\x81\xe0\xad\x0f\xbe\xf3GD\xe4\x8b\x00\xce\u05cc\x93u6\xce^\x01\xd4\xe4\xc0\xf6Ee\x12\aW*?\xcd\xdaX\x16\x91]\x1e1\xc6|\xe2m\x0f\xbd\xeb\x9dW\x1d\xb8v\xd9\x13\xbc,\b뼿\xbd\xf8\x84\x10\xc2g\x8d1\x9b5\xfa\xd2\x01\xa8\xd1\xe3\bA\x05\xa0\x03el\x99\r\x86\xfeVAŞ\x9fa\x156(zo]\xc0E\x91\xc3}'\x81\x97l\xfbޭ;\xfb\x82\xb0\u009cG\xee\xb3\xee\x8e\xe1$\x87\x18\x81q\x06&\xb1\x90F\xa9\x04\x1e\xddT\x9f3\x0f\xfd\xcdΌ\xa3r%6\xb4lP8\x1d\xd5\x05\xa2\x8b\x86\xa3\xb3\x95\xd0\xc6;6\x1bc\xccۍ1ױ\xfc\xd9\xe8\xb3A\xe6q\xe8\xfcőN\f\x85p\xf6\xa4\xf0\x12\x1bc~\x8a#GK\xde\xfbW\x18c\x9e\xa7\x86\x8f\xf9b\xfeب\xe9\xfd\x99g\xa0\v\xb1\xa9\xbe-\x16\x81\xc74ۜ\x85mw\xe7/m4`\x00\xa4\x8d\xf2\xa4]6\x16\xb1\xb3b\xd9\xf1\xd8j\xddPqTj\xed\x02Ǡ\xbf\x19o\uf571.F\x06\xf5\xac\r\xe8\x1a2\x9e\v\x95a\xa3ѨA\x85:\xa6\x18\x8e]-\xd2:&;[\xe5=\xae\xaf\xe98\x92$Y\x00gq\xf3\x861\x06\xde,\xafV\x1c$\xc0\xc0֮\xcd\x0e\x17@m=\xb3l9ˌk\"\xb2&\x9c \x82/Zk/\xe0\x82;_\x9f\xafݫ\x99 \xceF\xf5\xf3\xecP\xb8\x19\x81\x1f\xb7\x1c##\x14$\xbc_D\x9euՁk\xdf|\xc3Y\xef_r\xa7֒\x1dȺ[6\x18\x00\u007f\x1bB\xd8ܫ@\xce\x1e\x98q\xd58Em4\x1a\v\xa2G^xz]\x1d8\x178\xb9Xɓ\xd05&\x06\u0379\xd9`\x8cyO\xbf\xe3\xf2\xde\xd7`#\xf1ݮ1\x00(L^\t=i$\x10\x03\xa4#\t\x8c\xb3\x80\x03\x04\x01I#\x05L\xd7Y2\xae\xad8tlh\xf8iv1\xcc\xc1\x11\xcdJ\x17\xf1e_~\x99\xf3\xde\xff\xb91\xe6\xcdzo\x1dw\x1c\x812\x0f\xfa\x9b\x8b\x8a1\xac\xa4\x9fS~\x19\x96\xe1\xebq$\xcc\xc1\x80R\x9a\xa6g\xab.1\x04\xa4\xf2c\xbeu.\xb8P\xcd\x19\x02;\xc8~#\xd2r\xd1w\xe7\"t\f\x80:=\x00\xb0\x1d\x9e\xd3$\x01\x8cA\x9a$H\x1b\x8dZ۰\xf2\xa7\xe3\xe0\f\x96\x03%6<\fY0\x84\xc5\xdf\xe1\xc8t1\xb2\xa6kh4\x82\xe6f\x868\x10\xd0\xf7\xf5\x01Y\xec\xb08\xf8Y\xad\"\xfa\xf7\xe5>4f\x1b\x18u#h\xd8\x06F\xd0@\xc36`Q\xdf\xf5ρ\x04\xeb%C\xc5l\x87\x96\xbb^\x12\x9b@,j\x01\xa0^OeV\xd5e\xa3\x80\x80\xf5\x9d\x83\x1c\xef=\x92\x93\x92\x9f\x00`c;\xc9\xc11;l\xce.\xb4\xf3\x91\x83(\x9eWv,\xcc7\axlsz\xac\x87_\xf5ޟuՁk\u007f憳\xde?\xb5$y-\xe5\xc3\x1dz\xad\xb5\xf6u\xbc0\xa8կbV\xb1l6\x06\xb1\xc04\xda\xe4E\xc7\xc50\x16v\f\x17\xc5\vK\x17\xbas\x16v\x9f\x83s\xee\xe3{\xb7\xee\xfc\xeeR\x06\xc6\xfc\xb2\xe1\xe1\xc5d\x8cA\x91\x95<\xb7\xb3zWF;\xb4\xe1RW\xeemI\flb\x91\xa1@\xd2H\x90&i\x8dw\x1d\xb7\x16\xdf\xd4\x10\xb2Q\x8c\xeb'쐗J!\x84\xad!\x847\xeb\xffzOv\x1c\xecLx\xaf\x8b\xce-/\x8a8\xa2\xe6T;vF\xfc\x1a\a\x00|\x1d\x86\xc1\x18\xf6\x02\xba]I,#}]\xa4\xdb\xd1\xc4\xd9@\xac\x1b\xfdP\xb9\a!\xad`\x1d\x8e\xda+\x03\xacM\x06\x1dY\xb4;\x90W9\x0e\xc1\xe8\xe8\b\xd2F\xa3ʈ\xe3\xfa\x1f\x1b:\xe6Q\r\x8a\xea \xcf\a;\xec\xb8i`\xc1<K\xa8\xb2\x90\xd8\x11\xa8>iC\x02\a\x0e*W\x96=g\x9f\x85\xac\xce\xe3\a\f\frɑ\xe5Y\xcd!\x88\x0f\x18q\xa3\xa5c)\x1a\x18q\r\x8c\xb8\x11\xf0\xc6}6\x86\xdc\xed\x16BX\xf6\x93\x1e}\xf00R\x87Kk|\x91#\xe1\xa0X\xd7\f\xf3\xa5sٙ\x03\v,\xdcT\xaa\xf3\xc2\xceA\xaf\xad\b\x04\aZ\xac\xcbl\x93b\x1b\xaa|\x18c\xaa\xeeE\xfd\x0e\a[@e\xf7^\x0e\xe0\xd3oy\xe0\x1d/\xff\x93g|\xa0\xef\xc9^\x92\x03\xb9\U000135dc\b\xe0\x83\x1c\x1drD\xc9\x11\xa8\xe2\xab\\3\x88\x05\xcc\xc50\xc6\xe05\xe2\xe3(\x83\x8d\x1d;%ƈK\x81\n|\xd6̍1\u007f\xb4\x94\xb1iZ\x1c\x17Hyc#+\x13\xf3S\x831\x8a\x00\xe3\x05E\xab\x9b=\xb4C\xe7$\xd6\xc4\xc2&\x0ebBg\u007fKRf/\xa6wʮ\x13\xad\xbc\xf5\v\xc5\xc4t\xe9\xf6+^\x1bBxk\f\x0f\xe8\xb5\xd5(\xb1\x93\x88q\xd58\x95g\xc3\xcc\xce$\x8e\xdat\x9e\xab\a(-\xb2dž#`\xcef\x18fS\b\x8c\xe7\x8a#9\xee$c\x9d\x8b3\x9d\xc5(\x86^\xe3\xc5\xca\xd1\xe6bYs\xd6i7\xe6\xef\xb03qIRe-l\xfc8[b\xf9\xf0}\xe3v\xce\xc5(\x86\xcft\xfe\xd8\x11q6\xc8|\xb2\xd3\xe0\xb9_I\xf0r4\n(\x8f\xc9g9\x02\x80q\x16mi#\x0f9\x10\x80\xa2U\xce\xe3H2\x82D\x1cF\\\xf9{M\xba\x16&ԝm\xbf\x19\xe7b\xb4\xd8<\xeb\xff\xdc\xe2\xcd\u0383\xf5\x81۸c8\x9bх8kf\xde\xd9\xd6\xf0\\\xe9{\x1c\x000\xcc\xc7\xef\x8bH\xb51\x13\xa8;=\xe5E\xc7\"\"/M\x92\xe4}\x00\xdeޯ\xac\x96d\x91B\b\xbf/\"O\xd7>\xe9\xcek5\x85\xef\x15\xc5p\xe4\xad\x13\x12{\xc1\x18*ae\x8a\xb3\x126\xdcu\xc1\x19\x98=\x82\x10\xc2_\xec߶\xfb\x81\xa5\x8c\x8d\x05̆\x83\x17-G\x8d\xbd\xc6\x1a\x1b=6\x10\x00 ^P\x14%\x14\x13L\x807]%4\xd6@l\xb9C?i8d!C2\x92 i$5Hl\xa9\xb4\xf1\x8e\xcd\xe7x\xef?\xceВ*\x8e\x1a\xe4\xb8%PǪQT<_q\xf4\x1c;:\x96\x89\xea\x80F@\xaa+1ƫ\xf7\x89\x8d'Ϗb\xcb|\xb4\x03\xeb\x95\xf2\xc4\xd8o\xbf\xce\x03P\xc3Q_\xc4q$\xaf\xaf\xf1b\x8d[:\xbb\xd7\xea~\xbf\xd5jU\x9fU\x03\xa3rԍ\x92\x89s0\xd6VP'\u007f\x9f\xef{4r֕A\x89tk\x92:\aq\x10\x10\xcf9\as\xf1k\x82թ\x83\x88\b\x12\xb7\xb0\xb6\xa6\xe3U^T^ͬ\t\xe7\x1cf\xf2Y\x00@h\x06\x8c4F`\x83Ś\xa4\xdca\x9f\x88\xc3(F\x97ŏ5\v\x83\xa3x~Yf\x1c\fs֢\xaf\xb1\xfcy<\x9c]0\xc2\xc2\xf7c'\x04,\x84\x9bu~\xd9>\xc4\xddZ:߱\x13R\xfd\xe5\xbdA\xde{\xe4y~\xcd\xdb\x1ez\xd7\xdd۞\xfe\xbe\xffӏ\xbc\xfav \xebo\xdbt\x8a\x88\xfcN\b\xdd\x0e\x05V\xe68\x1a\x8f\x175\x80\x9a\xc1b'\xa1\xaf\xe9\xf7\xb8\xb8\xae\x1e\x94\x05\x10\xe3\x93<\x91\xde\xe7Mc\xcc\xfb\xfa\x1d\x97\x92\n_\xef\xc9J\x11Gܽ\xa05\xe6\x81qG.j\xa92h\x94\xcc\x05\xcd\xc4$\bY\x80\xe4\x02\xdf\xec\x18\xc8Y\x8f\xb6\xb4`\x9d\x85X)\xeb-K\xa0K\xb7_1\x12B\xb8\xcd\x18sJ\xafh\x9a\xf9\xe3F\b\x9e[5\xf21T\xa5\xaf\xf1\x9c\xaaSⱱAb\xb8\x92\x9d\x18GM\xcc\x1bGw\xec\x14\xb8\x16\xc3Pg|\x04\fGYK\xa18\vU\x990\xa4\xa1\x9f\xe3L\x9b\xe5\xa9\xf7\x8f`\x82\x05\v:\x84\x80v\xbb\x8d,\xcbj\x91iU\xb0\xb7\x16\x8d4\xc5\xc8\xe8h_\xe3\b\x12\x90\xd8d\x01\xfc\xa1\xc1\x19\xb0p\xad\xc6ccȮ\n\x06V\xe9\xd4#\xc1\xc2n\xbe\x18\xb7\xe7\xe3M\xb8+Nǒ\x17y'\xd3oW\xef\aY^\x16R\x84\x02\x89\xe9\xc2=q\x00\xc1\xeb\x83\x1d{\x8c\x1e\x18ӭS\xb0\xbdT=\xe1.2\xce\xca\xf5Z\x9cU\xf7ʂbć\x9dZ%\xdb\bA`\x9e\x94\xf4\x9e\x8c*y\xef?\xfe;?\xb8fߟ\x9d\xb3\xf5\x98\xa7x\xf4m\x91B\b\xaf6\xc644\xe2\x03\xba]$\xb5\vR\x04\x1b\x1b*\x8ehY\x00|\x92\xa9~\x87\r\xb3\x16Pوk4\xdà\x04\xb2\xab\x80\x88ܴ\xef\xfa]\x8f\xf6;.%^h쨀n\xbb\\\xec\f\x81z\xbb\xa9\xf6\x80\xb3\x81\xd1\xdf\x1c]k\xb4\xce\x11\x85*\x81*\x8f\xde\xd7\x18\x03_x\x84,\xa0=\xd3ZҘB\b۬\xb5\xeb\xd9\xe8뜩\xfcT\xa9\x95\xa7\xce\xf7J\xb8%\xc2^\xd9X\xb3\\\x18\xd7ey\xb0\xc1R\xa3ʑ\xa6\xfe\xcf\xc1F/Y\xf4\x8a\xc2\xf9\xfa<\x8ex\xb1\xf5\x03\xf9\x90\xbcj\xf3\xa7\xf2\xd2 G\xef\xcf\xfc\xa8q\xe09\xe3\xf9挛\r\x1f\xcf3;%5,\xedv\x1b\xedv\x1bE\x9ecvv\x16c\x87\x0f\xe3\xc8\xf88\xc6\x0e\x1f\xbd\xa9\xd0\xc0T5\x1c\xbd\x8f\x06.\x9c\xadŲd\b%\xce\xc0\x96ꀗBڅ\xd5\r\x00\xeb{(\xf4=\xae\x19\xea\xeb\xb1-\xaa\xe9\xc42k \x9a\x81(\x0f\xb1\xcd\x01\xba\x8e\x8du\x8ek\xc0\xaaì\a,\u007f\xce>\xe3\f\x9e\xff\xe6\xe0\x87u:\x86\xbf\u2004\xbf\xc7m\xc8\xec<8\x1bQ\xb9+\xefI\x92\x9c\xd4h4>\xf5\xd6\a\xdfY\x1d\x9c\xba\xa8\xbc\xfa\x16\xac\xb5\xff56p,L\xf6b\f-p\xe7\x14;\t\x15\nO\x969b`\xef\xb70\xdf5\x90\x83\x02\xe4\xa5qp֡\xf0\x05\f\xea\xfb,\xf4\x1e!\x04X\x18\xc0`\xc6Z\xbb\xa5\xdf11qD\x11\xa7\xf9l\xe0t\x12y\xf3\x95*\x89\xee\xf1P\x19\xf1be\bI\xa4[\xf8\xe5hC\xf7X\xc40\x8e^g)5\x90u\xb7lx~\xf3\xb1\xf9+[cM\xe4\xd39\x8a\xd9\x1c\xf9\\\x06\x9fy\x14y}\x13\x14G6\xca'oN\xd2\xf9\x8d\xb3K>f!\x86\xbe8\x83aGɑ\x9c\x12à*c\x95g\xec\x00\x18\xc2d\x18!\xee4\x02\xea\xb8x?\xc4Δyb\xa7\xaf\xc4u\x025\nl\x10b\xe8\x8c\xf9fc\xc1k\x06@\xed\b\x16\xbd\a\x1b*{\x8c,tR&\x91\xb5\xdbh\xb5Z\xb5\xd6V\x8e\x909ӎ\x1d\n\xebB/\x872h\nR?\xa5\x98\x91\t\xce:9\x82gx\x8dad\x1d\xebJ \xb7\t;\x8d\xe9|\xa6\x84\x97!5C\xcb끃b\xfd\x9f\rr\xec\x84y\x9d\xf3g9\x00\xe9U\xbb㌆\xe5\xc0\x8e\x8d3\xf58\xe3\xe0u\x117pp\xf0\xa0\xfa\vTs\u007f.\x80\xdf:\x96\xbc\xfa\xb2H\x17ݺ\xf1\xe4\x10\xc2+bE\x8a\x0f\u038b\xa3O\x16(\x1bPUhk,쌅\xbf?C\xde\x19|\x86N+r\x13\xc8\x1e\xcdj\x8bߍ\x8e\x00ϯwߔ\x03\a\xb2\x1d-\xb8\xc4ݸ\xfb\x03\xf7.\xf9$^\xa0\x9e\xee\xc5\xce\t\xe8\x16:u\xbc\xac(\xdc\x06\xa9r\x88k\x16z\x1d\xc679b\xe04W\xefυN\xe6\xa5Oz\x97\x811\xf0\x80\xcf\n\x14\x1d\x05\xca\xe7\xcbM\x83\x995\x80\x05\x92F\x8a\f\x19\x8c\x05\x92\x91\xb4\xdc\xf7b{w\x84\xb01W\xa5f\\=^\xf8ʷ~\x9e\xd3d\x95\x13\xcb2ލ\xcdƔ\xa1\v\xbd\x06\xef9\x8a\xb3>\x95a\xbb\xdd\xee\xbb\x0eR~\xa7,\x84s\xc1_\xbf\xaf\xfa\x16w\x83\x01ug\xa5\x06\x83\x8b\xcf<\x8f\x1c1\xea}\xd9A\xab\x03\xe7V\xf0\n\xfe;\x86]l\xa3\x85\xf6T\xab\xbav\x95\x05w\x8ew1\x1dc\xa1H\x00\xeb!\x93ʕ1\xf8\xd5 m;Vy\xb3}`\x99\xa9\xbeq\xc0\t\xd4\xe1\xb7\x1a\f\x14\x96W\xf4?\"G`2\x83\xd0*\xbb\xd9\x12\x93`\xc46\x90\x9a\x14'\xad9\x11N\x12$fak8\xaf\x95\xd89Ď\x99ǡ\xd0\x1cg5@\xfd\xa0\xc6^'_\xc4:\xa3\xf7f^\x18q\x88\xed\x98ΫfwJ\xfa\xb9\xce\xf7\xaey\xeb\x83\xef\xfc\xf0\x8dg_\xb7\xe8c3\xfb\xd2\f\x11\xd9\f`\x84\x99ӿ\x999UH.\x14\xf1\x02\x04\xba\xa7\x97Zk\x81q \u007f\xa8U\xf3\xa0\fﰑ\xca\xf3\x1c\xf3\xf330\xf7t0\xe5'\x8dB\x9e\"\U0003e034\x00\x81\x1c\xf1\xde/zJ鱈\x17;G\x87:\xae8\xfa\x88!\x13n#Աp\xd6@\x9d\x0e\vڛY\xe9z\xc1\nq\x14r,:\xefo/\xfe1k\xed\x1bC\b\xd5\xfe\x93\x98o\xef=\x9cq(\x9aye\xec\x9a\xd3\xf3\xa5l\xd3\x14\xc1\x04\xb8\xd4\x01\xae<g\xcc&\x0e\xc1\x04X\xd7M\xcf{\x9d\x89\xc50P\xaf\xc8]eƊ\xcaΘ#>}\x9f\x95<\x96\x0fG\x82\xca\a\xcbs)Et\xcel\xd8H1_\x1c\xd5)\xf1\xdf\x1c|\xb0\xb3\xe3\xcc5\xce\xce9\x10\x89\x9dp\x9c\xd9\xf4C\xb1cף7ڨפ\x9cs\x801H\x9cC\xa3\xb3\xbb\x9aO\x86й5Ƭj\x11\xddXS\v\x16t\f\xb13\xd1יB\b\xb5\xf5\xa4\xd7\\.\x05\t\xd51\xf7֕\x0f\xfc\x9a\v\xf3\b!`\x06\xb3\xe5zr)R\x93bԍ`4\x19E\x02\x87\xd1dtA\xd6\x1aג8\xe8\x89\r;\xeb\n\a\x12\x9c\x95T\xf2\"{\xa0?\xbc\x0e8\x88\xe2\xe0\x80\xef\x05\xd4\xf7\xaa\x00\xf5\xb5\xd9y\xed\x89Ƙ\xdf\x02p\xfdb\xf2\xea7\xb48\x9b\x17\xbc\xfe\xcd\a\t*\x03\x9c\xaa+C\xea\xed\x14\x9b-'\xdc\xc3?\x9c\xeb\x80\xe7\x00\xdcf\xad\xdd\x0f\xe0a\xef\xfd\x9c1\xe6\x19\xd6\xdasB\b\xe7x\xef\xcf\x01pN\x92$k\xd5@e\x8f5a\x0e\x19\xb8\xa4\x01_\x1e߰e\xef֝\xd3}\x8eg\x01ѱ\x1a\xd5k\xf1\"g\xa3\xa5\v\x9c\x8d\x03\xe3\xf9l\x84\xb8x\xacΐ\xfb\xfd\xd9X\xb2\"\xb0\x01\xd1\xeb\xf7Ci\x9a^뽷|\x1dU8\x95_|\b$\x1b\xdbv\xbb\x8d\xd1\xd1QH&\x10\t\xc8M@\b\xedr\x01x\x0f\xe3\x00\xa7N\xc5y\xd8\xc4\xc15\xea\r\a\f\x05ŝ)q\xed\x82\x17^\x9c\xd1\xe8\xf7x!p$\xcfNQI\x8b\xee\xf1\x82<\x16\xc5\x19\x13\x1b/\x86\xe4bh\x89u\x9e\x8b\xd71\xe4\xc2FB\xff\xe7{\xb3\xfcb\x98\xc2ڲX\x9f\xb8\xa3/Yk\xcag\xebą\xd9^\xf7\xaa`\xb3\x100??_s\xba\xba\x939I\x92\xf2(\xfdU*\xa2'6A\xb0ݵ\xc5G\x1c\xf11+1D\xa4\xef7\x1a\x8d\xdasb\xaa\xf1\xd9\xe5\xf1\xab\xf6*\x0e\"X\xd7\x02\x02\xda\xd2F3k\xc2\xe4]\xe7ް)\x9c8\x9c8z\"\x1a&E\xea\x1b\x18I\x1a\xb5\xb9d{\xc0\xaf\xc5YW<\xff\xfc\xd9\x18-\xe1@\x9b\xd7Y\xacwq\xbb\xb8~\x8e\xf5\x8e\xe1\xce\xce\xf5\xaf\xb9\xfa\xe1\xdf\xfb\xf0\xf5O{\xefl\xcf\xf9\xebS\xa8O\xe5\x88*\x16\x04/\xa8\x18\x8b\xe3\xc5\xcf\xe9;\xba\x86\xe1\xdd!\x84?\u07fbu\xe7Qw@>\xffm\xe7\x1b\xef\xfd\xc5\x00~\xcd9\xf7\xf3\x00N4\xc6 +2\x98\xf2q\xaa7\xf73\x96\xc5H\x05\x1e\x1b-.:1N\xa9\xef1\xac\x15w\x14\xf1\xb8{e\x141T\xa6\x0e\x83\r0˶\x1f\a\xb2\xee\x96\r\xcf.\x8a\xe2\x17\x14\x12`#\xad{\x11b\xa7\xc6FK\xff\xaf\xed\xbe\xa6\x88\xd9\x1a\x03\xf1\xe5\xf5\x8a&\xef\xeb\x11\xb8\xc4\xc2\xcd8ȴ i\xa5\x90\x86\xc0\x9dl\x11N\x15\xc8\xe9\xf5c=\xd8\x01\xf0}8\xf3d\xe3\x1fˏ\xe7\xc1{_A\x01\xfc\xb9\xd8(\x1d\x8b\xe2l\xa7\u05f58c\x8a\x1d\x8bf\x97\xedv\xbb6\xa7\xfa\xf98\x1b\x8a3\x918\n\xe5\xeb\xf7\v%\x05\t0\xd25&\xfa\xdd^\xf2fc\x19;\xb5,\xcbjYA\xbf\xc1\xcbRi\xb1\xf5\xc0\xddX\x9c\t\xda\x0e\x04\xc7ϥQY\xc7\xd9\xcarȚ\xf2\x84\xef\xb8~\xc6s\xc8\u007f\xab\xfe\x19c\xd0*\xcayo\xb5\xda]\x1e\x04\x18q#\x18u#\x18q#p\xc1bM\xba\xa6*֫\xdc\xf5\u07b2W0\xfb\xc8$\x0eO\x1f\xc6\xc4\xdc\x04N^{2N[{\x1a\x9e\xf0\x84'A~\f0\xa7\t\x80\xfaI\x10\xf1\x01\xacl\x878P\x88\x1b7X\x1fx\x1cQv\u007fz\b\xe1\xb7\x00l\xed%\xaf\xbe\x1cH\ba\x1d\x1f.\xc8Q\xa2\n\x8a\xbb\x06b\xc3ʌFQ\xe1\x9b\xf7n\xdd\xf9\x91~xؿm\xb7\x00\xf8\x16\x80o=\xef\xaa\xf3\xaeJ\x92\xe4\rEQ\xfc\x9asn#\x80\xf7\xedݺs\x13L\x85Z\x00\x00 \x00IDATQ\x9c\xae\x1f\x12\x91\xc7\xd0ɴXQX\x818\xaa\xecȥ\x06\xb7\xe9x\xe3̂\x9dO\x05I\x84z\xd6\xc6\xf0\x0f\x1bR\xbd\x8e\xb5\x16&7\x0f\x1ek\x1c!\x84\xff\x91\xa6\xa9\x8b#g.H\x16E\x81\x91\x91\x91\x05N$v\x90l88\x10\xe8f\a\x801\x16\xd8\aH\x96\xa1\x00\xd0\xee|\xbf\xa50գ]\x03\xb0fd\r\xec\xba\x14f\xd4 7\x02\x97\x96\x9b)]RO\xf5\xe3(p1lWI\x95?N\xeb\xe3(\xf2Xd\x0f\xe0\a~\x8d\x87\x85\xed\xb6\xc3v\xb0t{\x8aE\xb2\xb6[\xd7b,Y\xe7Qe\xcb\xc5\xff\x98Oկ*0\x00 \x87\x05b\x050\xa8\ueb5f/|\x81\xc4&Hl\xa7C.\v\x8f\x1cm\f\v\xe7\xa8^\xb0\xe7Z\x92\xaee\x8d\xe0\x95\u007f\xfdN\xecHW\x83\xbcxHQ\xdfx\a,\xd4\xc7ة\xc6c\u2d7a\x12\a\"(\x9f3\xc4P\x1fP߸\xd7+\xa3e\xfb\xa0<h&\x9c#GVd\xf0\xed\xc9\xf2\x1a\xb9\x85\x15\x83\xd1ξ\x95\xc6\xe1\x06\xee\xbf\xf3\xfb88y\x10@=\x83\x1e\x9b\x1dG\b\xf7\xc1\xdco\x80{\x80F\xd2\xc0\xe6\xf3^\x06\xd9X\x87\xa48Љ!W\x1e\a\xdb\xec8)\xd0\xf5\xce\x1d\xa2\x9d\xdfo{\xeb\x83\xef\xbc\xe1Ƴ\xaf[\x10E\xf4\xe5@\xd24}:+\x13G]\xbc\xa8\xf5\x86\x1c\xcdsT\x11}WҋF\x8fi\x10{ѷo\xd83\v\xe0c\x00>v\xde\xdb/<\xb7(\x8a\xef/\xe7:L\xb2\xbb\x98j\xfbv\xa5\x9c\xb9\xe4\xd5\x18\x1b\x17\xadY\x00]\xb0q\xe7l\x84?\xa7\xc4\xd9L\x95\x99H@~o\v\x85iW\x8b\x9ea\x97\xaaK\v\x1d\xf8\xa24Tc}\f\xe5\xff\x8a7/\xb1\xc3\x0f!\xd4\x1e\x19\x1a+\x1e\xd7r\x80\xfa\xde\x16\x0e\x0e\xac\xb5\xc0\xb7\r\xdas\xf3\xb5\xb1\xc5Ε\xafU\x84\x02\xfe[m\x8c4F\xe1_ (\x00X\x9b\xc3X\x83\x00\xe9<\xd3\xc5T\xe7\x8c\xe9\xfd\x95T\xb9C\xa8\x9f0\xab\xbc\xeb|pd\b\xd4O|>\x1a\x8d\xef:t(~ι1%>\xffħ\x9f\x89\xb0\xbe^\x13ӌ#\x8e\xe4E\xba]v*\v]\x13\v\"\xe4Y\xc1\xdc=S\v2\x0e\xa0\x9e\x19\xd2<\x1c\xf3\xd9\xf2\xbd\xe6+\x0e\x804r\x8d\xbbo\xe2\xe6\x00\x86oW\x83\xac)\x1fi\xadM\x03l3\x14\xaa\xe2`(6xq\x10\xa4\xf3\xce\xebo\xa9\xfc\xe8\xf5\xf9d\x04\xa0\xde\b\x02,<\vK\xf9\x8d\x83!\xa0~rn\b\x01\x85\x04̴gP\xfcS\x13\x0fO<R\xcbBU\x0e:nn.)B\x81\u007f\xdb\xf5\x054\xf6\xa6\xd8\xfc\xe2\x97#\u007fn\tk\xc6k\x80\x9d\xa9\xb6\x86\xc7Y\xbb\x8e\x91!5\x0e4u\r\x17E\xf1D\x11y\x11\x80\xbbby\xf5\xe5@|\xe7aK\x8c\xef\xeaMx\xb0\x1c\x19\xe8\xe4r\x11Y\x17X\xc7p\x19\x11\xf9Njn\xdd\xf8~\x11\xf9\x9f;\xdex\xf7\xb2\x1en\xb2gˎ\xbd\xcb\xf9^L\xb1\x17\xe6E\x96F\xe3\x02\x16n\xc6b\xc5b\xa7\xa22\x887\x97\xe9\xc4j\x94\xc5\v\x9a#\x88\xf8(\xee\xa3Q穐ϊ\xb3 6L\xbd\x1c\xbe*\x12\x13+?;\x02U\xaa\xec\x9ef732\x06Y\x96M5\x1a\x8d\u007f\t!|GD\x1e\xb3֎\x018\x19\xc0\x19\xd6\xdasD\xe4\x15\"r\xa6\xb5\x16\xed\xac\x05\xff\xef\x1e\x8ds\xd7 \x8c\x06XXH\bȋ.\x9e[\x98\xb2\xb8\x1f$`\xcd\tk\x11\xc4\x03\x0e\bi\x80\x18)k0\xae~f\x16\xf3\xc8c\xed\x17\xc2\xd2E\xa8\xdfW}M\xd3\x14y\x91\xc3\xf8\x85G\xccsp\x10\xb7a*/\x9c\xc9\xc5s\xc9\x0e:\x86\x13⌁\xe1\xb5\xc5\xc8\x1a[:d2\x021\x9c\xc6\x06&>\xf3\xacW\xa6\xa9\xb2X\r\x9a\x9c\x99@\xdah 錳\xd1hԜ\x85ޛ\xdb]{5\x1ep\xc0`m\xe7As\xcb \x03S\xc9O\x83\x00\x95E<\x8f\xcc\x17\xeb`\x1c\x80\xe9g\x81n\x9b\xbb-,\x1e\xbe\xedAdEV]\xdf{\xdf6\xc6|\x11\xc0N\x00\a\x8d1\x87\x92$9)\x84pf\b\xe1l\x00\xaf(\x8a\xe2i\xce9̷\x9b\xf8ܿ\xfd#6=\xb8\x11\xa7\xbd\xf2\x89\v\xe0]\xa58\x90\xe7\xc0\x92\x031\xb6]\xac'\x94\xad\xbe\x12\xcbu \xd6Z\u1cca\x989\xfe_\x15<\xc6\xfc\xf9}\x8e\xa6\x00\xa4!\x84\xf7Xk\xdfs\xe1'/\xf9\x9a\xf7\xfe\xd3\xd6گ9\xe7\xee\xbd\xe7\r_o\xf7\xc3\xdb\x00\xe9\xd3\xd6\xda{\x98?U\xe8 \xe1g\xc4ˉ\xdc\b\xa0\xe3S\xc5\xe0\x85ȑ\xa6N\x82\x8e_\x15>\xcb2\xc0\xfb\xbf\xd6ϳs\xe2\x8c\x00\x00\xff\xfe\xe1\xd1\x06\xd01\xd2\xd5\xf7\x19\ag\x83\xc7\v!\xc6K9\xc2c\xe7\xc3\xd7i\xff\xfb<;\xa4\u007f\f!\xfcY\x9a\xa6_\xdd\xfd\x81{\x17=\x0e\xfa\x05W_`\x8d1\x17\x89ț\x00\xfc?\x8dF\xc3\x16\xfb۰\xcfJaO\xab\x9f\xe4˼8㐷\xb2n\xf6\xd1,wl{u\xf4\xa9\x83Mlْ<\x92\" \xc0\xb8\xf2 K6\x84\xfd\x90\xb5\xf6\x01\x00\u007f\xcd\x1b\xba\xaa\xc0`\x14O\xb7־\x8c?ϲ\xe4\xec\xabs\xad\xea5\xdeD\xc9F\x10\x00|\xc3?\x92$ɿ\xb2\xc1\xe6\x00&\x0e\x04\xac\xb5GͶ\x83t\x1b/b\xf8By\x8e\xbb\xf2\xf8>\xcc?\x1bN\xad\x87\f\x9a\x8a\xa2\xa8\xae\xcd\x10\xb9\xb5\xb6z\xa2\xe4\xc8\xe8h\xcdA\xebZ\xd3q\xb1\\\x81\x0e\xe4f\x96\xef\xf0z\xed\xd6\x06\xba\xeb\x97\xd7:\xaf+\xbdw\xecp8\xb2\xd7\xf7\xee\xfb\xc4w\xd8h\xef\xb2־\xcf\x18\xf3\xcf{\xb7\xee\xecY\xac\x06\x80s\xafYg\x00\xac\x0f!\xfc*\x80_\xb7ֺo\xdc\xf7M<\xf3\xd6g\xe0\xa9?}6F\x935H\b~cb=T\xddR=Q(6\xee\x1a\xd3\xf1td\xf1\n\x00\xbf\x1f\xf3\xd4\xd7\xcaZwˆ\x87\x8c1OS\xc5\xe7\xc8\x15\xa8ciJ,HU~\x8e(8\xda\xe2\xcfu~\xda\xd6\xda\u007f7\xc6|\xcd\x18\xf3U\x00_\xb9\xf7g\xef\x9a\xec\x87\xd7\u0560u\xb7lx \x84pv\x8c\xbb\x02\va<v\x9cq\x96\xc2\x11\xb2s\x0e;\xdex\xf7@[[\xce\xff\xbb\x17~.I\x92W\xe9\xd1\x0f\xbcّ\xe1\x10\xee c#\xc2Q\x12\xc3j\xaa\\>x\x84\x9d\xb9\xbew/\x80\xff\xbew\xebί/\x95\xcfs\xafY\xf7\\\x00\u007f\xe2\xcbg\x80 \xbdh\xb4v?\xa0\xdejȼǭ\x86\xec\xccu\x9c\xea\xfc\x93F\x02\x97:\x04\x84\xfb\xefy\xdd\xd7\xcfY\x89l/\xb9c\U000eb735\x9f\x8b\x03(\xe65>(\x12Xx\xb2\x01\xe3\xe4\x9dk}\xfe\xae\xcdw\xbcj%\xbc1m\xbc}\xf3\x06\x81\xdc\xcd\x06N\xf9`\u074c3R^\x9f*\xdb\xc8\xe8}\xe5\xae\xcdw\xfc\xf8\xa0\xf8\xac\xf8\xbdc\xf3W\x00\\\x06ԍ\x1c\xd0-\xdesc\t\x004FF\xe0:\x0e\xc69Wk\xa0\xa8 \xa3G\xfd\x8b\xfe\xe9e\u007f\xff\xad\xa5\xf2\xf3\xda/\xbf\xf1\xe7\xfdi\xfe\xef\xe2\x93\"Ա\xc7u9\x8e\xfc9#\x8a3N\xed\xbeL\x9c\xc3\xc4\xdf\x1f\xc2\xd8\xcc8Dd\f\xc0[\x01\xfcݾ\xebw-\ts;\xef\xed\x17\xfeX\x9e\xe7۬\xb5?\x99\xa6)\xce>\xe7\xd9\xc0\xc62\x03]\x93\xaeAäH\x90\xe0\x84\x91\xb5H\x90T\x0fʊ\x91\r\xd5\xe7\xf8\xa8\x1d\xe6\xbd3n\x11\x91'\xdfx\xf6u\xb5\xa3\x10\xfa\xca@\x8a\xb1\xdc\xd9\xd4\xc1%\x16y\xc8J\x8c\xbaQ>\x0f\xc1\xa6\xbd\x1f\xb2\xa2\xc2\xe5\xf4\x8d\x17X\x1c\xa9s1\xdaZ;\"\"\x97\x02\xb8\x14\xc05!\x84p\xe1'/\xd9a\x8c\xb9\xc3{\xff\xc5$I\xbet\xcf\x1b\xbe\xbe:\xe7K\xf7 N\x9b\xd9K\xf3\u0600\x85\x9dB\x1c\xb9\xb3\xf1\xeb7\"^\n\xad\xbbeè\x88\\\xaeF*>\x17\x8ayV\xe5\xd1n!\x8e\xac8:\xd518\xe7 A\xe0\x1ep\b\xc8\x11B\xf8$\x80_ٻugs9\xbc\xeeݺ\xf3;/\xb8\xfa\x82W\xa5i\xfaޢ(ޙ~7Ex\x81,\x88\xee\x80z\x17\x89\xc2|\x9c\xc9q\xf4\x17\xc3O\b\x80o\x0f\xb6{\x88#\xe1\xcaQQw\x14\x1b^\x86\x14T\xce*\xd7x\x9c\x83\"\x1f|\x951pF̺Ɏ,\xc6\xdbـ\xf0I\x05\xab\xa1\xb3@\xbdê\x96A\x90#ֶw\x85\x94\xe6\xe7\xe6\x16ԕ\xd24\xad2\x16\xeb\xeaOv\\*\xc5ȉ\xbe\x06\xd4\v\xdc\xcaw\x1c\xbc\xf0\xbcs\x94o\x8cA\xb1\xc3\xe3\xf0\xf4\x18\x00\xec\xb7־zϖ\x1d˅\xee\xbf{\xee5\xeb^\x13Bx{\x9e\xe7\xef\xbf\xef{\xdf1\xcf|\xc6s`\x9ff1\x97\xcfa\x0e\x9d\xe0%+\xe7.\x81\xc3\xda\xc6Z\x18o\xb0&Y\x83\x86m 5ݓ/t\\\\\xf3b\x94ED\f\x80\x9f\x00\xf0\xb7\xccG\xbf\x10\xd6!)\u0099E\xd1I\xcdL\xf9\xa0%k-\xf2\xd0ٍ\xee,`\r`\x046\xb1𡀷\x82\xa4\x91 \x0f\x19\x8c\xb3p\x89[ p\x15:\xd7K\x00\xc4\x03\xb3!\x84\xf5\x00\xd6[k\xdf\xe6\xbd\xffᅟ\xbc䯭\xb5\x1f\xbb\xe7\r__\xd6\x04,\x858\xd2\xe4\xc8\x02X\xd8T\xa0)8G\xf1\xbd2\x96Uh\x8b\\o\x8cY\x13Ä\xcag|\u007f\x91\xf2ќ\xcaG\x1c\xdd\xc7\x06R \xc8'Z\x00\xf0Qc̛\xf7lٱ\xa2\xaaj'\xe2\xba\xf6\x05W_p\xb8՜\xbb192\x82\xe4G\xba\xcf@\xe9\x05\xbf\xb0AT\a\xc9\xd0\n;hu6\x83\xc2\xeeCV\xc0\x8d4\xca\xe7E\x90l\xd9@p+\xae\x8e\x01\xe8vlqƽZ5\x85\xc4&%\x84\x17e\xc1\fEi\xa1W\xf9֮<\x0e>x<1\xba0HR\a\x10\a\x93܂\xce2\x8b\x1d\x87\xfe_\x14\x05\x8c\xf7ȳ\xb2\xa6\xb0\xdc\xc3\x14My$Rm}\xb3c\xd3{ǻ\xccYה\xb7\x05\xad\xe5\x85\xe0?v~\x1b\"\xb2\xd7Z{ٞ-;\x96\xf4\xf0\xa6\x98\xf6n\xdd)\x00>\xf0\x82\xab/\xf8\x1e\x80\xff=\xfeՃ\xf6\xf47<\x05 \xa7\xaf\xf7\xce|\x8e\"\x9b\x81\xb5\x16\xd3\xd9L\x05\xf3\x8d&\xa3\xd5\xf1\xf8#R>sŠ\v\xbf1Ҕ\xa6\xe9\xcb\x109\x90\xfe\xb4x\x12?\x88\xa3\xe9\x18+\x97 \x80\x17\xa0\x00\xa4\x15`\xda\x06\xa6\t\x14\x939\xc2T\x00\xa6\x04\xd9X\x1b\x98\x11\x84\x19\x8f0\x17 ̀\xd0\x0e0\xa1|\x8e\x86FMq\xe4\x16\xb5\x94\xc1\x18\xf3\x14c̻B\b\xf7\xad\xbbeç.\xf8ċV\x04O\xf4C\x12M\nP\xaf\x19\x18czv`0\x14\xc3\xceg\xd0\xc7C8\xe7\x9e\x12;5vn\xba\x1b\xb9\xd7{\\h\xe3\b\x8aq\xdc\xfc\xde\x16B\b\xdf\a\xf0֕:\x8f\x88\xfeLDn\xcf\xefkU\x06A\x8d\x1a/\\\xfd\xcd\xf0'\xd0ť\xe3z\x1c\xd0=\x98\xb0\xdf\"\xfa\xd1(\x9f\xc81\xf7\xe8,\xdac-\xb4\xc6[\xc8&\xdb\xf0\xf3\x05B;\xa0\xc8\nXS\x1a\xe78\x92\x0eT\x8c5\xc6T\u007f\xc7m\xa2\x83\"\xc1\xc2V\xce8\xa2\xe4s\xe9⚘\xfe\xd6bv\xbcwe\xd0\xc4Y\x8e\xeb@R\xf1<\xf3\xf1\xf6\xbc\xc6\xf8D[\xd5\x1dθ\x96C*?\xa0\xde\xf0\xa2sƐ\xae\xbe\xa6\x9f\x05\xeag\xc1\xe9\x9a\x0f!\x00\"8\xf2\xa9\xc7\x00\xc0\x1bc~\xf9X\xfbޖB\xfb\xae\xdf\xf5\x0fƘ\xab\xa7\xe6\xa6`\x1eDup#CPlSU\xbey\x91c>\x9f\xc7T>\x8dC\xad\xc3x\xb8\xf9C\xfc`\xee\x01<8\u007f\x00\x0f\xcf\xfd\x10\x13\xf9$f\x8b9\x14R\x05kό\xef\xdd\xdf>\x90\xa9\xe2\x11s\xca\xc2\xed\xf11\xfe\\1\x16=\x13\xa2\x8a\x10\x8cAy6S\xe7\x99١\xfe\xb8Mk-2\xdb.+3\xa9@\f\x80\xce32|Qb\xdaA\xbaim'B\xfa)\x11\xf9\xc9\v?yɍƘ\xf7\xdd\xfb\xb3w-Z\x84Z\t1\xf6\xa9\v.\xce4\xd8q\xc4\x10\x10G\xa0*\xc7A\x92\xf7\xfe\f\x00\v\x8c\xbf\xb5\xb6z\"\x19g\x17\xfaY\x8e\xb08b\x06\xea\x05v\x00\xd2Q\xfc\xf9A\xf2\xbd\xef\xfa]\xe1\xdck\xd6\xfd\xaa\xf7~\x8f\x8cɉɓ\xbb'\x02\xf3x\xb8\x1dUy\x8d\xeb\x11\f\xdb\xe9\xe7uѯ\x94*l=\xa7\xfd9\x99Ԝ\x80\xb1\x06\x85\xcba\x9c\xed\xec\xd6O\x00\vؤ\xcb+w\x10\xc5m\u0383\xa0 \x01\x89I*}ձs{n\fm\xb1\xacX\xa6\xab\xa9\xaf\x15\xbf\xa1{\xaa\x03\xbf\xc6\x193;9~\x82';DδJ\x94dy\x8eyL\x0e!\x9dj\x00Ơ\x91\xa6\xd5q\xfa@y\x9e\x18?͑\x9f\x84\xb9\xe0\xfe\x84\xaeXk!90>;\x0ec\xcc\xfb\xf7]\xbf랕\xc8l\x11\xfa\x13\x00\x1bZ\xbbf\xdep\xc29\xa7\xd6\xd6y\f\t\x03X`\xbf\x19\xfa͊\x1c\x19r\xcc\xe6\xb35\b{č<#\xbei_R\x16\x91\x1d\f\x85(s\x8c\x8b.\xe8oG\xbdUT\xbf\xab\f\xf3\xf5\x18\x9f7b \x85 \xb4\x02\xb2\xe96\xfc\xacG6ц\x99\x05\xf2\xb1\f\xf9X\x86l<\x83\x99\x03\xc2l\x80\x9f\xf3\x90vhH.\xef\xf0Yq\xf7\xfa[7-\x18\xe4\xa0(v\x14,\a\x8ez\x18\x93W٬\xe6\x81t\x1d:\x8f\xe5˽\xf0\f\xa1\x00\xf5MQ\\\xd4U\x9e+c\xa9\x06\xfb?\x00k\xed\r\xfb\xaeߵ\xe4\x82y?\xb4w\xeb\xce\a\xd24}\x9b?\x90Ղ\tVr\x86\f\xe2n'\x86\x10\xb8%Zuu\x10p!/\xb0\xb8\x9e\xa1<\x06\x1f`\xbc\x81\xb4\x03\x8a\xd9\x02\xd9d\x1b\xed\xf1\x16\xe6\x0f\xce#\x1bk\xa3}\xa4\x05?\xeb\x11\xe6}\xe9|2\x8f\xd5(-\xb0a\xe0z\rg$\x8c \xf0\xff\x9cݱQ\\-\xfd\xe5H\x9e\xb3\xca8\x8b\xeb\xb5\xee\x16\x1b{\ba\xd9gw\x85PvH\x16y\x8e\x99\x99\x19LMN\xe2\xf0\xe1\xc3\x18\x1f\x1f\xc7\xf8\xd8\x18\xe6\xe6\xe6\xd0j6\xd1lv\xcb\u007f,K\xe6\xaf&\xd7\xdd\x01\"\xb2[D\u07bb,ƎA{\xb7\xee\x94$I\xde\xfe\xf0\xf8\xc3y\xe1\xbb\xcd3\x9c\xa1\x01X`\u007f\xe3̝\xeb\xbd\xfa\xfd\xf2\x0f\xa0\x1d\xdaO\x8a\xefۗ\x03\xb1\xd6\xde.\a< \xf5g0\xf0b\xe2\xe2\vG.\xcc\x04G\x90\xfa9\xceV\xd8\x003\xdeXSd\x97\xc0\x04 d\x01\xc8\x04a\xde\xc3\xcfx\xf8\xa9\x02\xf9\x91\xfc\x05\xf9X\xf6\x8d\xf3n^\xbf\xb1/\xa9\xf7I\x9cy\xc4P^\x1c\x05\xf7\x1a\xffb\x10р\xe9\x19\xfa\a+\t/<\x95\xbf\xf2\xa1P\x11;AV8k-\x8c\xb5ȧ[\xff!\"\xef\x1e4\xc3L\"\xf2\x17ƚ/\x15yQ\xd31\xe5\x83[ku\f\xbcHԩ\xe8g5p\x19T\xbd!\xdep\xa7FO#`\xe5\x83k/\xb5\xe0\"\x94\xf0n6\xdbF{\xba\x8d֑&\xb2#m\xcc<<\xb3bޘ\xac\xa9\xc3Q\xf1\xdabb\xf8\x8f\xa1b\xa0\xfe\x1c\x89A9\xe1\xc5HDj\xcf0\x01\xba\x8e\x9a\xe5Νm\xca\u007f\xac\xe7U\xa6\xbf\x82\xb3\xbb\x18\xf6\x8c\xed[\xbb\xd5\xc2\xcc\xcc\f\xa6\xa7\xa60v\xf80\x0e\x1f:\x84Ç\x0eaff\x06s\xb3\xb3h6\x9b\xb5S\x85\x95\xc7\xe9\xfbǂ\xb5\xf6\x97\xf7]\xbf\xeb\xe8\x0f\xb5_\x01\xed\xfe\xc0\xbd\x0fXk\xff\x12\xd3u\xa8\x8f\xb3<vv\v\x82w\xaa\xe7(\f\xc6\tC\ba\xf45\xfb~\xb6\x16I\xf4\xb5\xb2\xf6l\xd9\xf1\x80\xf7\xfe\a\xd6՟2\xc77gC\xcf\xcf\x1b\xe0\xcd=q\xd4\xc6\v\x9f\xa3^N\v\xe3HD'G\x95\x9a\xa3\xa6\x8e\x91y\x92\xb3\xee\x8b/\xf8\xe0\x85\xe7\xadxF:\xc4\x06\x8b\xa3\xba8\xbd\xd7I\xe1\xa8T?\xc7-\x81\x8c\x93\x0f\x8a\x9csOb\b'^\x8cJ\x9c-i\xd7E\fc\xf1u\xc4\a\x00\xf8\x9b\xbd[w.\xediVK\xa4=[v\x88\x88\xfc\x99\xae{\x9d\xe7xw2\x1bB\xd6\x1d\x8e\xfa\xe2\x831\aᬵ\xbe\xc1\x05\\uP|\xfc\x06w\x1a\x1e\xad\xf6\xb2\x12\x9c\xfeh\x14\xa4\x1e\xa4pA\x9c\x8d\x1a\xcb$\xfe\f\x1b\x9a\x18z]-\x8aa\x14\x95/\xef\xa7\xe2\xcf2|\xa5\xc6n\xb1\xa3\xe9\x97B\xbc\xce9\xd3U^bǢ\xeb\xa9\xd5l\xa2\xd5jazj\n3\xd3\xd3\x18\x1f\x1b\xc3\xf8\xd8\x18&&&0=9\x89\xb1\xe9\xf1;\xf7nݹcٌ\xf5O\u007fe\xa6\xeb\x1b\x90\xd9\t2\xc5vM\xf5%\xce\x00Y\xdeI\x92\x9c\xce\xd7\xe8;43\xc6|\xa8\xb8?\xab\x8cQ\x9c\xfa\xb0\xb7cLP'\x97\x9d\x8d*\x83~\x86\x8bR\xfa\xf9^8=_7\xc6\x1c\xf5\xef\xceg\xd7:\xe7\xfe\xe1\x82\x0f\xbd\xf0\xd4~\xc7w4\xb2-\x03?\xe7\x91\xcff\bYyX]\x91\x17\v\xd2Aδؠ\xf1{j\x84\x06\r\t\x14E\xf1\x84\xb8\xfe\xa1\xb2\xeb\xb5 \xac-kU\xb1\x93\xe3h?\x84\xa0\xe7T\xf5\xf5|䕒\xf7\xfe߬\xb5m\x8e\xf4\x81nG\x16\xcb4\x1e\x9f\x1a>\x86B\xf4\xbb\x830\xd4q\xa1\x9eOXЧ\x15\xc6\xf5%\xe6C\x1d\n\aO\xacσ\xa2\x90\a\xa4IZ\xddC\xf9T\xec\x9e\xefY\xabM\x12\xcfi\x9a\xd6\x0e\xdeT\xfeW\x8btnYoUޱ\xbc8\b\xe3L\x8b\x83Օ\x12g\xb9\x1c\xa4h\x91\x9f\rl\x9c\xfd\xa8\x1e\xaaSγ\f\xadv\x06\x18|j \xcc\x1d\x83B\b;e^\xa6\x95\x1f\x1dG\x96e\v\x9a'8\xd0P[\xa0\xfa\xa2\xef\xe9\x0fP\x95/\x9e\xcc\xf7\xeb[{E\xe4#Ƙ19\xd0\xed\x94\xe1ݠq\x14\xa8\x91\x99zm\x15|\x1c\xa5qT\x17G\x9a\xeaH\u0603\xb21`\xef\xcaE\xb5\xce{\xcf\x16\x91\xbf\\\xe1|\x00\x00|\xb3ĭM\xcb\xc0O\x15\xc0\xb4@&C\xf93\x15\x80YA1S\x00\xad\xb2vc\x83Eb\x1c ]G\xa7\xe3\xd21\f\xa23\x88ID\x8c\x1a\xfe\x1a\x04e\xba\xbb\xea\xb9\xd8\xc8\xd9\x12C\x861\x94\xd0n\xb73\xe7ܷ\a\xca\xec\"\xb4\u007f\xdb\ue588|\x9f\xf1Z\x86\xaa\xd8h\xb0\\Yg\x18\xe7\x1f\xa4\xd1\xe3H\x98\xaf\x9b\xd0Ù\x94\x1f\x0e*\x94\x18\x06Y\xcdh\xbe\x98,\xbbŚ\x8f5\xd1\x1eo!\x9f\xca\xe0\xe7=laP\xb4\n\x04\xbf\xf0\xb1\x04,;\r,\xd4\xe8\xb0a_\rR\x03\xad|(\xf1\xfc\xb11\x03\xea\xba\v\xd4\xed@\xf5\xfde\xb6\xf1\x02X\x800\xa8|\x18\xfd\xe0\f\x8f\x11\x18\x866\xf5Z\x1dy\u007f~\xd9\f-\x81\xf6o\xdb\x1d\xcc\tf\x1f\a\x8b1BĶH\x03\x05\xde\x00\x19B\xa8u02|\x1f|\x18\xe1\xfb\xf5\xad\x15\xfb\xb7\xed\x9e\xf3\u07bf[D`;\xe7\x81\xfa\xa2\xfbHI.\xbepԧ\x93\xcd)?\x1b\xaa\xb8w\x9f\a\xc8\xe93/\xdc8\xa3\xd1\xfb\xb31\xec|\xfe\xbf\x9ew\xd3\xfa\xf5+\x98\x8fj\x02\x98*/\xee\xcb\x16Nm]\xf6s\x1e\xc5t\x8e0\xed\x91\x1f\xc9!\x93\x01\xf9x\x06?Y\xc0\xcc\x03\xf9t^\x15P1xHY4\x82\x88\x17<G\xa3\xbd\xa2;}\x8de\xa8\x9fO\xd3\xd4\x0f\xb8m\xf7X\x94\xa9^0\xfe\r\xa0\xb689(\xe1\xac+\xa68\xf3Z.\xe9\xde\x04\x8er\x19J\xe5̈\r\f\a6\xac\xb3|V\xd6j\x90\x01ʎǖ\x87\x9f+Кh\xc1O\x17\xc8\xc6ژ{t\x16\xf3\x87\xe6\x90M\xb6\x91Mg(\xe6s\xa0@\x95U\xc7-\xaa\xc0``\xc0^\xa4\xf3\xa8\x01\x0eg\x1al\xc0\x95\a\x8e\xf2\xf9\xb5\x98G=\xbdx\xa9\xc4\x198\xb7\xde3\xec\xdb\v9\x01\xba\x8e\x8eaz\x00\x10\t8\xe1\xccS\x8ez\x8a\xf2 \xc9>\xc9e:\x8f̧R\xdc\xfd\x17\u05ee\xf5\xc8&\xbd\x06g3\xa6ejP\xf6\x92\xc2\nk\xedG\x01\xfc\x8d\xf7\x1e\xe1\xc1\x02v\xde\xd6\x1e\x14\xd5\v/唔\x9d\x04\x17lb\xbc\x98qX\x00\v\xf0<\xfd>;\x95\x91\x91\x91jSY\x04\xe5\xbcg)c\xecE\x1cU\xc6\xc7N+\xef\x1c!)OޗO\xfd\x93B`\n\x03\x9b\x1bH\xb3\xdc\a\xe3'\a\xbe\x91\xder\x1aώ\x9c\r+\x1b66^\xbc yA\x14E\x91\\\xf0\x89\x17\xad.\x00N\x14Bpl\x84\x95T\x8fT\xb1\x95\xd4\xe1i\xc0\xa1\xdfc\x18n\x10\xd9\x1eװ\x80\xfa\xa6\xb2^p\xaeʘ\xb3k\x0e\x98FFFV\xa7\x06BN\x8d\xa3e}OD\xf7l\x01\xf9|\x0e?_:\x97\xf6\x91\x16\xb2\xb16\xe6\x0f\xcea\xee\xe0,\x9a\xe3\xf3Ȧ3\x84V@\xd1ʑ\xb5V\xa7\xf6ˁ\v\xb7\xbb\xc7\xd8<\xc3k\x8bes\x9cY\xad\x948\vџF\xa3\x01\xa0\xbbF\x94\x17\xb6\x0fq\xf1Z\xf5#\xb9(9e\xc5L\xf5I-i&|\xfeZ܍ș\x1b7\xac\xf4\x1a{\x8c\na{V\x8bƖ\xe4@\xf6n\xdd)!\x847\x1bc\xbed\x8c\x81\x1f\xcf!\a<\xd0\xee\b\xd5\xd8\x05\x9eM'Y\x8d;GȜA\xe8\x80┹\xc6<\xba0\x86N\f\xb7m6\x1a\x8dZ\xe4\xd4\x11«Ͽ\xf9\xe2g-e\x9c1\xc50P\x1c\xf5\xaaB\xeb\xc40\xd4ƛ!5r\x8e\x9d\xec \xc8\x18\x93\xc7i>+\fgi\f\x11q\x8d$\x8e\xfc:\xe3J\x93$Y7Pf\x17\xa1\v?y\x893Ɯ\x13+/G\xa2\xaa?l@\x18\xd3\xe7\xc5\xcb\x11\xffJ\x89\xe1G\xa0\xbe\xb91\x8e\x96\xd9q\xf7ʮ\x192\\\rh\x88\xa1I\xbe\x17\xbf\xcf|\xb1\x11t\xd6\xc1\x19\x87\xd0\x0e\xf0\xf3\x05\xf2\xe9\f\xc5T\x81bbu\x0eS\xe4\x00G#\xfe؆\xe8\xda\xc9\xf3\xbcּ\xc3uV\xb6\x13ι\xe5\xefD\xefȂO\xa7V\x87\xa4\xc1\xae\xae-.8+\xcf|\xd8j\xa4+/Y\x16CK\xa4K\xb7_a\xa6&'\x9f391\x81Ç\x0ea~n\x0e333(\xf2\xbc\x82&\xd9I\xc7\xd9y\f\xc7q\xc0\x04\x00\xdf\xfb\xe1\xf7\x1b\xfc\xf9%k\xef\xfem\xbb[\x00^!\"ۀN\xbb\xdfc\x1e\xc5\xfd\x19̡:$\xa2\x91\xa02\x16\v\x9b\x17\x1f+<\xb0\xf0H\xee\x1a\xd3\x14e\xe8\xc3{\x18\xfbgat\xee\xf1\U000a5393\x89\xa3ZΜbG\xc7\xe3e\xc3\xc5ІFY\x83&\x99\f\xe3f\x16\xd5.\u007f\x97\xdb\xf2q\x9b\x85@\xbcTY\x92\xf2˵\xa3^\x06N\xc7\xd0\xf9\xfck\x06\xcepo\xba4I\x92\x93t\xd7<\a\x14ʏ\x12g\x1b,\xe7\xd8\xc8\xc7E\xf5\xe5\x92\xde'\x9e_\xbe_\xbc!.\x867\x80\x85'\x1e\x0f\x02^\x8bI\xf5\x8d\x8356|\xbc\x0e\xd9\xd9\xc500끈\x9c0pFK:\x91\xa3\xe08\xa3\u0ff9\xc1&v:\xfa7\xb0\xb2\xa3\xe7u\xec|\x12\x82\x06~1z\x12C\xf6q\xd6\x11\xc9\xfeu\xcbfj\tT\x14Ņ\"\xf2Dͼ\xb3,Cs~\x1eSSS\x98\x9d\x99\xc1\xd8\xe1\xc382>\x8eɉ\t\xcc\xce\xceb~n\x0eEQ\xa0\xd9lւ\xae<\xcfk\xe7\xcei\x82\x90\xa6i\xed\x99D˒\xf4ޭ;\x8b\xfd\xdbv_-\"\xaf\xb7\xd6\xfe\x87\n\xabhf0\x0f\v\xfc\x039\xfc\xfd9l\xa8\xd71X\x91ِr\xa6\x12\x17Ҹ\x10\ft#A5 \xaa@\x1cUq\x1a\xdfQ\xc8\x159\x10\x8e\xe8\xe2\xe3\xeacL\xbc\x97\x12\xf5ʞ\x06\x8d}\x87\x10\x1e\xf3\x99\x87\xf5\x16\xd2\n%\xb6=\x9d\x97G\xc7Lz\x98)\x00\xd3\x02?Y@fˍn&\x03\xac\xb7pp@\xe8>|\x86\x9dKG\xa1~\xfe\x82O\xbch\xd5wB\x02xS\x9c]\x02\xa8a\xe3:\aZ\xf8댽\xf6Y\x9d\xafA9\x0f\xa0\v\xa1\xf1^\t\x86\xc7\xd4\xe8p֣|\xa9\xae0$º\xbbZ\x14;X\xa0kp9\xabg'\xc2\xfcFY\xcb\x13V\x87G9Me\xd2\v6\xd2\xd7t.\xb9\xbdW\x03\x06v\xd2+m;f;\xc4\xf8\u007f\x92$\xb5\xfa\a\a\x85@7X\xe1Ca9\x90\t!\xbc\xf6\xd2\xedW\f\xa4+\xf4h\x94\xa6\xe9\x9bX\xdf8 g4$\xcb2\xb4\x9aM\xcc\xcc\xcc\xe0\xc8\xf8x\xb9a\xf2\xd0!\x1c\x19\x1f\xc7\xf4\xf44\xb2v\x1b\xadV\xab\xaa\xfb\x85Pn\xce,\x8a\xe21\xbeߊ\xf2\xe7\xfd\xdbv\u007fZD\x9e/\"\xbf\x0e\xe0!\x11\xe9n\xf5\xb7\x06\xf9\x816\xe4@';9\u0099Fɐb\x8al08\x8ac\\;\x8e8\xb83\x80\x8d\vGv\x84\x83\xbfx%㌍\x13\xc3Sl\xac\xf4\xe9i\x1c\xbd1>\x0ft1\xdfA\xb7\xf1J\x90\x878\xb5\x8fa \xef=\x10\x00x\xa0h\x16\xb0\x99A{\xb2\x8d0㑍\xb7\xe1'\n`J\x90\x1fɑOd\xc8&ې\xa6@Z\x01E\xabx\x0e\x02~q\xa0\fGtѭ\x1b_\v\xe0\xe7\xf4\u007f]\xc0\xfa\xc3\x0e\x97\xc7\xd5k\x1f\x8b\xca;\xcejWB1$\xc8-\x9d@\xf78l\x8d\x94\xf9\xf3l\xa8\xd9a\xacF\xf6\xc1\x0e\x8a\xd7\x15\x1bE\x86z\xb8\xce\xc0\xfcr\xf6\xd7\xe1\u007fU\x1cH>\xd6~\xc2\xfccs\xc8&\xda\bs\x1e\xf9\\\x0e\xdf.\x1fs\xcb<\xb2\x1d\x88\xf7{0\x14\xee\x9cC\xbb\xdd^v}\x89\xf7\xf4\xe8\xf8\xf9^|\xbfx\x1dǎCe\xd7y\xb4\xc2I\x00\u07b9L1\xf5E\x9b\xee\xbc\xfce\"\xf2\xeb\x9a1)1$\xad\xfcs\xf6ę\xaa\xf7\xber,\xd3SS\x98\x9c\x98\xc0\xf8\xd8\x18\xa6&'199\xe9\xf7o\xdb];*j\xc5\x00\xec\xbe\xebw\xe5{\xb7\xee\xfc\u007f\x01<\xcb9\xb7\xd9Z\xbbMD\xbeÆ\f\x00d\xae,\xbc\xe3\xa1\x009\x10\x80\xc3u\x83,\"\x95\x01fH\x8a\a\x1eGM\xecT8\xad\x04\x16\x1c\x1ex\xfa\xf97_\xbc\xa2\xb1*.ʩ\xa9*v\xdc\x19\xa2\xbcr\xe6\x15GÃ\xce@\xec\xa3v\x0f\xf3Î\x8e\x9d\x18/6}\xaf2\xc2>@\x8a\xb2\r\xd9\xe4\x06\xa6\r\x143\x05\xcc\x1cP\x1c\xc9\xff༛֯\n\x8cqѭ\x1bO\x17\x91\xbf`H'\x863c\xfe9{U\xa3\xa2\xef\U00061703\x82\x89bh\x853\x0f\xe5M\x0f \x04\xba\xf5\x9a\xb8~\xc7\x1d0\xb1a\x1a\x041\xb6\xad2T\x1eb9*O\xfa\xbd\xb8) 2,'\xaf\xbbe\xc3\xe8 y]wˆ5EQ\x9cd\xa4l1\xcef3dSm\xe4\x93\x19\x9a\x87\xe7\xd1<8\x8f\xd9Gg\x90O\xe5\xf0\xb3\x05\x8a\xb9\x02y3G\xc8}\xf9\xe4@\x82`\x81\xfa\xeeug\x977\xe7\\'d\x1d\xe2yd\x1d\xe4c\xf39+\xe6\fXO@\xf6\xde\xffΦ;/_Q=v1\xdax\xc7\xe6SP>\xe6{Q\xbb\x19\xa3;<\x8e8[6\xc6T\xa7\t\x03\xe5>\xa2|<[\xf0L\xa6\x81U\xf0\xf6]\xbf+߳eǝ\xfb\xae\xdfu\xf5ޭ;\x9f\x17Bx\xb6\x88\xfcN\x9e\xe7\xff*\"\x99\x1a6\xdd9\xea\xe7r\xd8G\x80\xe2\xfe\fr\xa8\x9c\xa4\"\xefzM>Q\x92'\x903\x8f\xb8_;\xfe\xad\x023\xe5\vˎ\xa0xQ\xa9B1/\x1a\x850N\x1a\x17\xd6t\xb2\xe2\xe7t\f\x8cB8\xc8\xd1e\\\xbc\x8fSj5\xac\fǰ\xb1\x89\x15\xceZ{\x16\x80\x8f\x9dw\xd3\xfa\x81wd\x85\x10n\xf6\xde?\x89!\"\x96\x8f\xf2\xc1\x9b\xf9hn\xab\xcf\xc6N\xb3W\xedd\x05<ֺYX\xb6\x8a\x97+\xef\n\xb9\xe9\xc2d8\x86\xb1u\xe5\u007f\x90$\"\xf3@\xf7\xd9;\xfa\xb7\xdeKaJ\xbd\xaf\x8eI\x1d\f\xff\xa8\xdeҹb?:`^\x9f\xc3\xd92Н\xebJ\xf7\x02\x10\xdaefR\xcc\xe6(\xa6r\xcc\x1f\x9a\xc7\xcc#\xd3\xf0\x93\x05\xf2\xc9\x1c\xf9t\x86|6C\xdȇ5\xdb00(\x1e+\xe6\x96\xcb\x17;ZF9:<\xd7`ʸv\xc4-\xb3\xec\x9c;\xaf\x8f\x00\xf8\xf4\xc6;6\x9f\xbc\\ގB7\x02x:;\x00\xa5^\x0e\x90\xd7P\x1c\x98+qW\xab\x88\xc0~\xcf>\x14\xdftuv\a\x01\xd8w\xfd\xae\xfb\xf6]\xbf\xeb\x83\u07fea\xcfO\x88ȏ$I\xf2\xfa\x10\xc2G\x00Ԟa\x1eB\x00Z\x01\xe6a\x81\xb1\xf5\xa3M8\xf5\xe6\xc9\xe0\xbf\xd5\x10\xc6\x1d-<ᝅSۂ\xbf\x14\xe2\b\x8e\r\x03\xdfG?\x17\x17\xcf\xd8\x11\xea\xff\xaa\x98\x83\xa4\x10\xc2A\x9dh\xde%\xcdNE\u007f\xf3\x93\xe6:\xdf]\xb0\xf9\x89#)2\xd0oH\x92d\xa0i\xf8\xb9\x1f\xbd\xe8\x17\xd0\xc2\x1bLV\x9enkBy\x8e\x91f{@]ᕗ\xaa\xeeF\xc5\xf6xN8KY)\xa9>\xaa\xf1e\xdeb#\xc3\xd90\xe3\xf9\fu\xf2\x02\x1e$\xb9\xfdv\xca\xd9:\xec\xc7NB\x1d\x02\xaf#\xae)r\r\x80\u007f:\xe3\xbbz\x90\xbc&Ir5\xf3\xc5N66̱\x93K\xd3\x14Y+\x83\xf1@{\xa6\x8d0\x1f\x90M\xb4\x91\x1d\xc90\u007fp\x0e\xd9\xeeֲ\x0e\x19c\x98/\x0e\xf8b\x84A\xa9W\r6\xde\xd3Bk\xf0\xdc$In\xbb\xe4\xf6\x97\x0e,\x9b\xbf\xe4\xf6\x97\xbe\x0e\xc0\xafp\x90˙n\x9c\xf1\xc6g\xc5ŁV\\;3\xc6\xc0:\x87\xc9\xc7\xc6\x0e\xc4\xf7^2\x10\u007f\xee\x9f_\xf4\xca$I\xee\xd8\xf9\xe6o\xf6}6R\a7\xfbt\xe7\a\xe7^\xb3\xee\tƘ\x8d\xde\xfb˒$y\x9d\xf7\xfe\xb9\"\x02\x1c\xf0\bg\x99\xea$M\xc6\x1fc\\6\xa6\xf8\x8c\x1a\x9e\xf0\x8e\x82.\xfb\xd4:\x9d\x10\x8e<c\x85\x89a\x02\xfd[kB:\x1e5փ&k\xed\x0e3e2\x9c\x8a\x86\xf2\xcc\x066\xe6\x81\xf1\xf18\xab\x02\xba\x11,+Qg\x1e\xdew\xdeM\xebO\xb7\xd6^\xbd뷾\xb5\xec\n\xf0\xf97_lD䷑\xe3O\xf3vV\x19\x8c`|Ն\xe9\xd2\x04A|\xf9\xa02+\b\xae<\xe2\xdf\xd8r\xd3[\x92&\xb5c\xca5\x98Ь`A4\xbb\x02\xe2\xb9V\x83\x1b\xb7\x12\xc75<\xa0\xbe\x18U/\x18b\x1b\xb4\x13i\xb7\x9b\xe2B\xa3\x06\x9fr\xe3\x86\x1aH\x005\xe3\x1cgѽ\xeatƘ_\\wˆ\x8f\xec\xfc\xb9o\xac\xf8T\xe6\xf5\xb7m\xba\xb4(\x8a_\xe0\x00\x85\r\x1d\x1f\xb1\xa2\xf0\xa0Ω\xca\xdd\xda\xee\x93\x17\xeb\x8c\x02\xed\xac\xb9\xac\xb4\x93\x83*\xad\x0fp \xabA\x00g\xbd\xca3\x9f\x04\xc1z\xa9\xef\xbb\xce\x06\xea$I~\xc2\x18\xb3{ӝ\x97\xff\xca\xd7_z\xfb\xf6\xe5\xf0\xa9\xb4\xe9\xce\xcb\u007f\xc5\x18\xf3\x11`\xe1\x9e\x0f\x9d\xdf4M\xab\xccW\xf7\xa9\xf0V\a\x0ef\xd8~\xb1\xfd5\xe5{ߌ\xef\xbf$\xed=\xef\xa6\xf5\xe7\xa4i\xfa\x99\x10\xc2\xde\xf3o\xbe\xf8\x95\xcb\x1d\xf4ޭ;\x8f\xecٲ\xe3\x9f\xf6]\xbf\xeb\x9dY\x96=\xdfZ\xfb\xf2\x10\xc2g\xe34\x91\r\\\xdc\xeb\xcd\x11T\xac\x80\x1a\x01\x00\xd4\x1a\xd8²\x1e\xbf\n\xd4\x1fU\xa9\xff\xf7\xe2A'\x86\x95\x8b\x1f\x13\x19\xa7\x95\x83\xa4=[v\xcc˴\xbfS(\xfa\xe1HJ\xf9稜\v\xfe\xb1\xbc\x19\xde\xe2h\xbbCo\x01\xf0\xf9\xf3nZ\xbf,H㼛\xd6?\x19\xc0nj1\x1f\x14\x11\xdb\x03r\x04\x04(\xda\xe5\x0ei\xdf,\xca\r\x98\xb3\x012\x13\xaa\a\x94\xf9#\x05\u0094\x87\xcc\x06\x98\x96\x81\xcbm\xb9\xf1\xad]\x94{\x19\xc2\xc2ξ\xe5\x12w\x01\xa9|\xe2\x8e:ΞU\xa6q\xb1\x9d\x17n\fg\r\x88\xda\xd6\xd4\v\xbfj\xd8b؏\x1b;\x94\xef\xf8aDq4j\xad\xfd\xe0\xba[6\xacH\xa0\xebo\xdb\xe4\xbc\xf7\x1fdhX\xafϧ\x0f\xb0\xc1\xe6\xec(曑\bc\f$\b\xac\xb5\xed\xe5\xf0\xd6>\xdcB6\xd1.\x1bL\x9a\x1e\xed\xd96\xa4\x10xr\xac\x1c\x10\xc4p\xa5ʕ\x03Eu.z\xf2xǎ\x9d#\"w^\xba\xfd\x8a\x9b.\xb9\xfd\xa5'.\x95\xcf\x17\u007f\xe5\xe5\xa7m\xbcc\xf3M\"\xf2W\"\x92r&\xc7땳O\x00U݆\xb3<\x955\xeb)C\xde\xd6Z\xe0\xbb\x00\x80\x05DZ,I\x11\x8c1\xef\xf1\xde'\x00\x9e\x15B\xf8\xfc\xf97_\xfc\x0f\x17|\xe8\x85g-u\xf0L\u07fea\x8f\xf0y>8\x00\x00 \x00IDAT\xec\xfe\xc0\xbd_ܿm\xf7kD䆀n\xeb.G\xcf\xdaN\x16\xc3\x031\xb6\xa7\x93\xcb\xfbO$\bp8,\xbb\x06»\x9f\xe3\xc9\x00\xba\x8a\x1c\xe3\xf7<\x19\xec\x84xq\x0f\x98\xbe\xe0h\x87|,/Κ\xd8\xd11\xf4\xa6N/\xc6o\xe3\xb1x\xef\xff\x8b\xb5v\xff\xf97_\xfc\xe1\xf3o\xbe\xf8\xc7\xfaa\uef1b\xd6?\xed\xbc\x9b\xd6\xff\x91\x88\xdc\a\xe0\x97\xf5Z5\xc7AĐ\x1bGDJ\xbe\xf0\x80/\xa1/=JF\xe6\x02d:\xa08\x92#\x1c\xf1\xf0\x13\x83\xdd\x04\xb7\b,Q\x19>\x9e{\x9dg\xde\\\xa6\xf5\x04.\xbe\x0e\x98\xc6A\xebC\r/w3q\x96\xa1\xbc\xc6{)\x9cs\v\xb2\xd7\xcew\xd6[k?\xba\xee\x96\r\xcb\xdaY}ѭ\x1bO\x11\x91\x8f\x00\xb8\x88\xf51Θk\xf0I\x04\xc1\xea\xfbj\x90\x81n\xc6\xd0\xf9\x91\x10\xc2\xf8\xb2\xa4'\x82\xa2U\xc0\x16\x06\xed\xa96¬G>\x91\xa1u\xa8\x85֡&\xf2\x89\f\xc5L\x81|&+\xbb\x19ea\x81Z[~9\x88c\x98\x98m\x81\x88\\i\xadݽ\xe1K/\xf9\xa9\x8dwl>f\x93¦;/?}×^\xf2\xb6,\xcb\xee3\xc6\\\xc9\xeb\x9231Θt\r\xe9\xfdU\xee\xf1A\x9a1\x9c\xa8r\xf5!\xa0\xf5\xe0\xecA\xe7\xdcΘ\x9f\xbe!\xac\r[.{^6\x99\xfd78\x03\x9bZ\x04\x13 V^/V^\xb1\xee\xe6\x17\xfe\xa5\x97\xf0\xc1=\xbf}\xcf}\xfd^\xaf\x17\xc9\xd3̻\x9c\xb1o\x01`5\x85\xe6\xc8C\x15]\x1d\x8a\x0eP\x85\xa4\n\xc6\x13\x1aBy\xa2l\x1e\x96\u007f\x9e\x05\x9f!\x15G\x9fqD\x14\xd7g\x80z-\x821\xcaA\x93\x88|\xc1\x1f\xf17ʉ\x82$Mj\xb2`c\xa0<\xc70\fw\x9d(1\xfe\xcc\n\xd9\x19c\x12Bx\x931\xe6M\xe7\xdf|\xf1\xf7E\xe4\x9fD\xe4\xbbƘ\x83\x00\x0e;\xe7N\xf1ޟ\x19Bx\xa6\xb5\xf6\x95\xd6ڋ\xd8\x11\xc7Ƙ\xc6Q\x8b~\xd9Ȱ\xd3\xebe\xf8\xf8=\x00\xd5\xe1\x81\x03\x90mŧ:g\x95\xabs\xae:\x91\x17@\r\xcaP~\xf4\xb7f\x1d\f\x83\r\x92\xf6n\xdd\xe9/\xbauc\xab(\x8aQ2\xa8\v!\tc*X\x88uV?\xcb\x01\b\xd0}(Z\xe7\xb5_3\xc6\xfc\xe4\xba[6\xfc.\x80\xdbv\xfe\xdc7\x8e)\xe0\xf5\xb7m2y\x9e\xbf\x01\xc0\x9f\x8a\xc8\x19q@\x15C\xaa\xbc\x9680\xe3\xd6y\xbe\x06\xd7q\xac\xb5\xad\xfd\xdbv\xaf\xc83svY\x9b\xf7̗\x19\xaes\b!\xef\"\x0f\x89\x83K\x1d<\x02\\b\x01\a\xa4#\r\x04t\x1fn\x15?\x93\x03\xa8 \xb3g&I\xf2)c\xcc̥ۯ\xf8'\x11\xf9\xa6\xb5\xf6\x87\x00\x1e\x15\x91Qc̙\"rV\x9e\xe7\xff\xc5{\xbf\xc9Z[\xcb\xda㵩:\xc9\xe3`}\xe4\xda\x12ˎ?˿C\x1e\x90\xfb\xfc\xf3\xbd\xce\xc4\xebۊ\x85\xd9\xf0\x87\xa3ɨ\x95\\ MA\x92\x8ch\x14\xb5\xc6Z\xfb?\xf2\"\xff\uf5fc\xf7ş\x0e\b\u007f\x12L\xf8꿿\xeb\xae%\xad\xda\v>\xf4B\a\xe0oB\b\x95%\x89\xa3$\x8e\x8cc%\x8b#\xa68\xc5\xecLȲ(Ɛ\xb9\b\x1ec\x9e<I\xfaY\xfd_\r^\xdc\xd2;(\n!|\xc7N\xe1@rZz\x96\x1a)6v1\x14\xa5\x0eC\xa3%퐋\vk\x9c\xad\xa8\xe2qM\xa83O?j\x8c\xf9]\xe5\x85\xe1\x1e\x8ezx1\xaa\\\xa2豒\x9d\xfe\xcf|\xebw\xf9\xd4`\x86\x87b\x87\xc3\xe3]\x91l'=lj\x01ga\xad\x81\x97\x00$\x80\xebQ@g\xf91O\xbc\xd0٨\x0f\x9a\xbc\xf7\xe3\xd6ڧ\xea\xb5;\xb8{\xed\x9e\xdcz\xca\xd1'g\xff\\\xecg\xbe;\x06\xfd\fc\xcc'\xbd\xf7\xbf\xb9\xee\x96\r\xb7\x1bc\xbe/\"\xdf3\xc6|\u007f\xc7\x1b\uf7bd\xe8֍'\x1ac~\xd4{\xff\x1cc̏\x86\x10.7\xc6l\xd6{\xc55D6|\xaa\x13*O\xe6K\r\x9d\xea\x8566Ԑ\x81\xe0\xc7\x16\x15N\x1f\xc4\xfc\x01u8\x87y\xe2\x9aW\xf0\x01\xbe(\xd7v\xde*3^o;\xeb\x03\x021\x82\x90\x06xx\xa4\x8d\x04&\xb10\xce H\xad\xf3\xf1\xa4\x10\xc2\x1b\x9dso\xe4\xf1\xa8\x81\xd7\xe3U\"\xe7S\xf1\xa4Y-;\x8cx-\xc75$F\x18b\xe82I\x12\x04\x11د\x06\x84\x10z\x9e&ܗ\x03y\xd1\xef_\xba\x0e\xc0\xcf\xf0\xc2\xd4\x01U-\x820Ʒ\xfd\xeb\x9ds\xaf\x17/\xdf\xd9\xf0\x9e˾`\x8c\xf9W\x00_\xbe\xfb\x0f\xberԖ\xba\xf5\xd7m\\\x1f\xa6\xc3\x1f\xc2\xe1U\xd6Y\x04xX:\xb4\x90暑S\x0f\xcb\x18\x1f\x1b\xbfH\x01g\xf7nٱ\xec\xd3\xe0\xb8\xe0\xc9J\xc5Q3\xa7\xde1\xa6ˑ\x96v\xf1h\x8b\xdc i\xff\xb6\xddr\xfe;.\xfaB1V\xfc\x06N\xc1\x02#\xb5\x18\\\xc2P\x92.\xde\xd8бC\xd2\xd7c|\x15\xa8\x9f\x14\xa0\xbf\x81n\x16\xc6\xf5\x19\xfd\xbbW\xe19\xae\xcb\xc4Q;\x1f)\xc2s\x12;\xf7AE\xf8\x12\x04\xbe\xe5\x01x\x92Uw_\x8a\x982\n\r\xf00\xceBl\x80q\x16\x05\n\xb8\xc4\xc1&ݬ\x993\xd0Հ2\xed\x03\xf6\xfe\xf0\x8c\xf0Tv\x16j\xa0\x15n〆\xe7^\x83.5\xcaqWd\x1cH\x18c6\x03\xd8̺v\xe1'/\x99,\x8a\xe2\xd4\x1eEx\x00\xa89-\x86V\xf5>\xfa;F\x12\x80\xfazb{\xc0\x81\x83\xfd\x81\xbd\u007f\xb9\xb2\xd35\nt7\x06\xc6\x067v\x82\xfa:\x9f`\xab:\\\xe9m\xee\x11\xf2N'\xd9|\xf7Ad!\x04\xa4\xa3)\x8c3\xf0\bH\x1b\t\nS \x19IJ\xc7#\v\xeb\x1a,k\x9e\x0f\xcd(\xf9s\x1c\xe8q\xf0˶\x8b\x03:ՉF\xa3Q\xca7782s\xa40\xc6|\xb1\x97\xbc\xfa\xcd@\xfe\x98a\x1bU\xb28:UeK\x92\xe4\xb9!\x84\xe7\x86\x10~\xd79\x97\xbd\xf0ݛ\xbei\xad= \"\a\x9ds\a\x8b\xa2\x18\xb3֞\x0e\xe0lk텡\x156\x89ԟ5\x1dB@\x82Nˣ\t\x80\x03<<\xc4\x02p\x80\x98\x001\x028 \b\xe0\x8d\x87I\xba\xe7T\xd5`\x83CŲ\x15\n\xa8\x1f[\x10C=\xb1b1\xf6\xcc\x11@<\xe9\xab\x11yvx\xfdK\xcc\xc8o$\xa7\xa7\x00\xea'$\xc7\xf7d\xe3\xcb\xddX\xbd\"\xf9\xaa@)\xd2SƬ\xc8\xfa\x1a\x8f\x9d\xef\xc1\x0e\x9e\x15We\xc9\vV\xdfk4\x1a\xb5\xd7\xf4\xbb1\xec\x16\xd7vbG\xbf\\\x12\x91jsZ\b\xa12\xb2\xd5\\\a\x81\x0f\x9dlS4\x98\xe8\xe8\x88\x05\x8a\x90\x03\xd6\xc0\xa5\x160@&\x19\x92\xd4\xc1%\x83\xef\xc8\xcb'[\x0f\xa5f\x14b\xba\x19\x9bs\xf5\x93\x12\xd8\xf8\xc6\x01\x03\xeb/\xeb\fG\xa9\xac+*\x1f\x95\xb7\xf7\xfeT\xb5\x17\xfcY\xce\xd2hs]-\x18`}Pb\xa8P\x1d\xa1\xf2\xa2\x81\b\x8f\xb351\xb7`\xbfB\xbfTf\xe1\xe9\xa2\xf5L\xe5C\x8dql\x17\xf5\xffxm\xa91\xef\xf5DâݭIy[\x8e\xad--\xc0\x94\xfaR8\x03\xe3,\x8c\x03\x92F\nq\x02\xeb\xba\xe8\x86\xeawܖ\xab\xb2$\x94\xa0\x1a'\xdb/M\x048\xd8j\xb7\xdbp.\x81\xdfބs\xee\x13{\xb7\xee\x9c\xea%\xafc:\x90\x17\xbe{\xd3%I\x92\xfc$\xf7C\xb32pڤ\xccs\vh\b\xa1a\xad\xbd\x8c\xa3\xdbZ\x8aDƙ=\xbbR\x15\x15\xb5\nXðQ\xb7\x1d1\xa5\xc92\x89\xe9\xd4g\x00\xe3\f\x8c\x13\xe4\xb3\xed\a\x8f5Σ\x91\x1a4\xe5\x97\xc7\xc7FT\v\x94\xaa(\x1a]\xe9\x18X\xa1V#\xf2\x04\x80\xbd[w\xfe\xfb\v\xae\xbe\u0cd80\xafƩ\xa8);\x13\x1b\x006\xe8\xfa\x9eF!\xec\x04b\x8c\x14\xa8\xb7\xfd\xc5i1Gg\xfcY\xbd\aG>\xfa\x9a*t-\xa2\xb4\xdd\xe38\x18\xdb\xe5\x8cHy\xe3\xac(vV+!\xe7\x1c\x82\xafg\x96:&\xa0[?\xd0q\x14E\x81\xd1\xd1\xd1\xea\xa1L\xd6Z\x84\xc2\xc3\x19[^\a\x80o{\x142\xf0c\xfd!\"\xf7\xc0\xe0\xe7 \v\x8d\xb2\xca_\x8d1G\xdbl09{\x8c\xb3X\x86T؈Ŷ!\x0e,8\xf3\xe8\x95\xe1\xe8w\x98?\xbe'G㬓Zs\xa2\xcc\xea\x9e\xe5ʎ\xb3&\xbe&ý\xac뜙s\r\x873:\xfd;F)z9a\x9e\xa3\x10\x02B\x1e`\n\x83\xf2\x1c\" \vYy?\t\xb0\xce\xc25\x1cr\b\\\xc3A \xb0I\t\x99\xc5\xed\xed\xb5\x9a\x06͡f\x1al\xc3+\x9b\x96\x19L\xb5f\xbd\xb5\xf6\x8f\x17\x93\xd71C3k\xed{Y`ʈ\x0eT\x15\x81\xa3s\xa0\xbe\xa0x\xa1\xeb{l\x14T\x88q\x9a\xa6\x8a\xcfu\x04\xeed`R\x0fo\xc5\xc2y\a\xd3\x02\\\xcb\xc2\xcd'p\xce-\xe8_^\n)\x9f\\\x00\xd5\xf1\xb0\x11V>\xf8)^|\xc0\x1eCm\x83.\x9e2\x89\xc8\x1f\xfa\xa9\x1c\x82n1\x94\x17\xa3\xf2\x1dgNʿ\xf2\xcb;Qkx/A\b\xb1a\xe7\xe7\xc3p\xe6\xd5\xeb\x18{\xce0\x18Έ\x17\x1a\a\x1d:\x0e&\xd6\v\xe5E\xf9\x89\x1f\x02\xb5RR\xdd\xe5\b36~*\a\xe5[\xff\xe6vZ\x1d\xdf \xb2\xa3\x1e<~\xc6>\xb2\xf0\xa1kʫ\xea\x04P?[Nǧs\b,\xec:dX&\x86\x1d\xd9x2)\x0f\xfc\\y^\xd3\xfa]\xcepb{\xc1\xf2U\bS\xef\xc5|\xd9G,\xac\xb5\x9fY\xae\xecbx*ַx=\xb3\xdc\xf85\xb5\x15\xea8؉\xc7NV\xdf\xe7 \x9b3\xc3\xf8yC\xde{\x14y\x81P\x04\x14\xcd\x02\xf9lypj6\xd1F{\xac\x85\xe2H\x8e\xb9\x83\xb3\b\xb3\x1e\xed\xa96\x8a\xf9\x02E+G\x91uO\xcaУ\x9e\x18\x1eֵ\xa3\xf7mm\x9f\x05\x80\x8f\xefݺ\xf3?\x16\x93\xd7Q\xb5w\xc3{.\xdbl\xad\xbd\"\xae\xe4\xebb\xe5\xcd):\xe9\xbc\x03S\x05\xd6kW&O\x18OL/\x03\xc3)\xb8\x92\x1a\x9a\x18\x02\xd1\xebi\xed$\xcf2\x88\xc8'\x8e6\xcec\xd1\xda\xc3k\xb0fl\x14k'\xd7btr\x04\x8d\xa9\x14#s\r\xb8Y\v;o\x81& m\x81\r\xb6l\x19F]QbH\x85\x17\xf0j\xd0\xfem\xbb\xef\x11\x91\xcf\xc8\x01\x0f\xdb1\xa6|\x14=\x1b|v,\x8bAVq\xe0\xc0?\xfa:?\xc0\x86\r\x81ރ#1\xde)\xcfN\x82#L\xe5\x89\x1d\xad~_\x8d\x9e\xf2\xc9\xc1\x87\xf2\x91e\x19\x8c\xe9>\xdf{\xa5\xc4\xfc\xc5\xc1T\x8c\xe3\xc7\xd9\x19gFld{\x19\xa8A\xd0ޭ;\xbf\xdf:8\xf7\x1d\xdb4\b\xf3\x01h\v\x8af\x01\x13\fB\x11*\xb9\xf0\xbdu\\\x9ca\xc7\x19%\xaf\xdb8#\x89\xb3\t\xd6\x1d\xdd[\xa2k6~\xa6\x0e\x80Zdφ\x92\xaf\xc5k\x9d;\xd88\vn?6\xbf\u007fϖ\x1d\xcb\xee\x06\x8d\xb3ט\xf4\xbc3\x9dw5\xc0l\x88\xd9^\xc5\xebF\xaf\xcd\u05cf\x83\xed\xd8)q0\xa2\xefŏ\x15\xa8ɦ\xf0Hl\x82|>/\xe7~&G6\x91\xa1\x98\xc8\xd1|l\x1eّ\f\xf9dV=\x82[\U00080b15Uk'I\x13\xf8oz4\xb3f\x91\xa6\xe9{\x8f&\xafEW\xd6ſ\xb7\xd1\x00xo\x8c\x8d\xa9\x90\x19\xef\xe3\xc8O\a\u008b\x84\x8d(/\x1a62z\x0f6\xb2qt\x1cu\xfd,\nϨ C\b\xc8|v\xf7ޭ;W\xd6^,R\xf6{\xe7\x02\xdb\xf1\xb9\x0e\xf5{\xabC\xb5֖\xbb\xa5\x1d V \xb6\xacӔ\u007f\x97\xc5X8,\xfb\xb0\xb7~\xc9\x18\xf3\x87\xde\xfb\xd74\xc6S\x14\xa7\x140\xb6\x1b\t\xf3B\x15\x91\x1aT\x15\xa7\xbb\xea\x1cTa\xe3\xc2y/(\x82\xb3KU\xfa\xf8H\xf6\xd8\b\xa8\xc3b}\xe2h\x94\x17\x95\xde\x17\xa8;\xa1ب\xf3\xfb+%k\xcb\x13\xa6\xd9Xq6\xa1{\x12\xe2\x05\xcf\x1d|\x1c\xf4\xb0\x0e\xaf\x06\x89\xc8g\xc2\xc1\xf0\\\u007fb\xb9c_B@&\xe5\xde:\xb1\x01\xdey$\xa9C\x11|\x19F\x1a\x81I,\\ja\x12\x8b\xbc\xc8k\x86\x89\xd7g\x9c9j\x10ɭ\xbe\xfa\x1d\xce>93\xe4,\x833\vޥ\xaf\xf2\x03\xea\x8faedB\xed\x10\x04p?p\xc8E\x96\x9d}(_\"\v\x9f\x8b\xae\xf3\x1d\xd7\x1d\xb8S\x8du[\xe5\xc2h\x03g6\xfay\xbdO\x04\xfb\xf3<\xd6\xe4ş\x89\xed/;\"\x86\xafj\xd7\x12 \xe4\xe5{y\xb3+k\xef=\xd2F\x8afh\xc2\x16\x06~<\x03\x80\x8f\xed\xba\ue7a3֏\x8f\x96\x81\xbc\xd2\x18\xb3\x89;_8\"P\xe2t7.ز\xa7\x8d#rV.V\x16\x8e\xd2\xf8\xbbl\xf0t\x02y\xe1\xc6F+\x04\x8f\xb9\xe6,D\xe4\xef\x8e&\x80~\x88\v\x82\xba\x10tҙ\x17] \x89up\xe2\xe0\n\x87$K`\xe7,\x92\xd9\x04\x8d\x99\x14kfG\xb1vz\rF\xc7G\x8eqו\xd1ޭ;\xef\xb5\xd6\xdeZ\xccd\xa5\x1c\xb1\xf0AA\xaa\xdc:\x0f\xbc\x10\xe2LP\xffgE\xe7\xefi\xe4\xda+\xe5g\x88\x01\xa8w\xb7pF\x1b;\r\xa0\xbb\xe8X\x87\xf4\xfb\x9c\xda3\xbeΙ\n/ƕ\x90\x8e\x93\xe5\u008b\x95\x9f\x15\xa1\xc4\xce#v\x8e\xfa\xb3Z\x99\xa81\xe632\xe3al\x8f\x83)\x05\x80\x17\x84,\xc0w\x8e\xf67-\x03\x99\t(&\n\xb4\x0f\xb5`g\f\xfcDQ>~y֗\x9dC\xad\x00\xe3\r\x10\xeagR\xf5\n\x06t.\x18B\xe4\x82y\x8d\x1ft\xb3\n>\x01X\xa3xv:\xb1a\xac\x82S\x03\xb4&琦\xe9\x8a\x1d\b\a\xc3qv\x1c\a\xb7\xdayů\xb1\xe3`\x9b\xc5Y\x1b\xc3\xe1\xf1\x1a\xe0u\x1a\xa3\x00,O\xd6{\xfd\x9f\x1d\\\xec\xfct\x0ez\xa1#Ɣ\xa7?8Xd;\x9b\xc8\xf3|\xca9w\xd4\xec\x03Xālx\xcfe\xd69\xf7^\x8e\xb2\x18\xd7慢=汧TA\xe9\xc0YQ\xd8\xd8s\xe4\xcaB\xd3\xcf\xf2k\x9c\xb61|\xa5\xc2\xd0G\xda\x1a\x18\x00\x06\"\xd2\xf2\xde\xdfv,!\x1c\x8bb\a\xa8cc\x05a\xe8\x85'\x87\x17/+\xc4 \xa2\xe2>\xe8M\x00\xee3\x8f\b\x82\x84\x1a\x8f\xf1\xc2\xe8U\x83\xe2\x80!\xee,Q\x99\xb0A\xe0E\xa7\xca\x1cC;\xec\f\x94\x18>a\x05\x8f\xe1\x04\xfd\x9b\x9f\x8b\xcdp\x98\xf2\xc0\x86Hy])1\xa4\xa7c\x89q\xedŢT\xfd\f\x1b\x89X\xe6\x83&\x11\xb9\xab(\x8a\xbb\xcd#\xdd\xe7\xef0\x84\xa4\xb2ֵȎYa\x10\v\v\xe4\x00\xda\xe5\xde/\xd3\x04\x8a\xc9\x1c\xed\xc3md\x87\xcag\xc8\xc8t@\x98\xf1@\x13\xf0\xf3\x05\xb2\xb9\xaclW\xf5\xd2s\xed\xab\x1daH\x93\xe7_\xd76Эϰ!Wb\xc8RB@~O\vƘ\xbb\x8a\xa2\xf8\xc6\n\xe5\x06`\xe1S\x1dy\x1ds\x16\xce\x01W\xaf`'\xaeip\x80ú\xa2\xf7\xe6\xac6\xb6\xab\xfa\x9b\x9dv\xbc>\xe3qp\x10\xae\xdfg\xfb\xac\xb2\xacjI;+\xc7\xf6\u007f\xefٲ\xe3\x98\xddl=\xb5\xd7\x18\xf3zc̅\xec0b\xe7\xc10\x16\x0f<N\xe7\xbc\xf7U\xf1\x8c\x17Oŀ\xedv/\xe9\xf5\x19\x06\xd0ϰAQ\xc18\xe7*\xa7\xa1<\x15E\x01\x81`\xbe5\a\x11y\xf7\xfem\xbb\x0f\x1dK\b\xc7\"n\xd3S\xa5V\x1e\u0600\xb2C\xe3蘣\x1a\x9d\xc8\xd5,\xa2+\xedݺs\x12\xc0O\x89H\xd3>\x02\xd8i\v7_fE\xa9O`r\x03+\v\xa3u\xee\xd0\xd1q\xeb\xbc)\xdc\xc5\v\x9f\x8d\xa0\xfe͆\x83\xbf\xaf\xf2P#Q\x93[\x90\xdaao\x1c\xa93n\xae\xfa\xa2\xf3͎\x8c\x17\xafF\xafqV\xb4\x12\xe2l\x82\xb3c\xd6M\x8e\xfc\xe2\xccK\xe5\xc1\x19\xfdj\xd0\xfem\xbb\x83s\xeeJH\bI֍\xe2\xf9\x98\r\xceF\x81z\xb3K\x9c\x1d\xb1a\xaft\xb7\xf3\x802\xc9\x04\xa1Y>J\xd96M\xf9\xd4˩\x80\xecP\x1b2%\xe5\xf3d\xa6s\xf89\x0f\x9b\x1b\x14\xcd\x02EVvU\xf6\x82\xb1yM\xb1\x8c\xd9\t\xb3\xa15\x8fX\b$\x88ȕ\xfb\xaeߵ┓\x03<\x86\xdf\xd8>)o\xbc\xe6\x95\x18\xb2U'\xc4\x01\b\a\xd6<nv(,\u007f\x0e̸\x01\x81O<\xe8\x95ų3\xd4\xf1\xf0Q\xfez\xffʞ}[\xe0C\x81$I\xb6\xecݺ\xf3\x1f\xfb\x91\xd5\x02\a\xb2\xf1\x0f\u007f\xdc\x19c\xfe\x98\x9d\x05G\xdd\xecEY\x01\xe3hC\aޫ=LI#\x12\x1e\xb8\xb5\xb6\xc2SY(q\x14\xc9\xc6<6\xea\x1d\xe7\xf1-\xe7ܟ\xf6#\x84c\x11\xc35\xbd\x1c \u007f\x8e\xfff\xde\xe3\boP\xd0ʱh\xef֝\xbb\xad\xb5\xbf\x99\xe79\xf2#m\xa43\t\xd2\xc9\x04\xa3S\xa3X;\xb5\x06k\xc6G\xb1\xf6\xf0\x1a\x9c0\xb1\x16k&G\x91N$h\xcc4\x90Υ%\xf4\xd6.;ڐ\x01V\xba2瀁#1\x00Uj\xcfN#>\xd6^\x17T\xa5܂\xaaư\xd8&K^\xc4@W\xe78\xdb\xe1\x05\xad:7\b\x98\x88\xa1\x848\xaac\x87\x17\xebx\x9cy\x03\xa8\x05L\xab\xa9\a{\xb6\xec\xb8\x17\xc0\x87\xfd\xa1\x1c2\xb30S\x8e\xf9S^bx\x85e\xa0\xf2䢷\xfep`Pe<Y\x0e\xc9\x05\xc8\x00i\x06ȼ\x94\x8fT>\x92\xa3}\xa8\x85|,\x83\x9f\xf4\xf0S\x05\x8a\xe9\x02aޣ\x98/\xbfc\x02`P\x87\xbc9\x90\fA`\x1e,\xf1z\x11\xf9\xd0\xfem\xbbw\xacTfq\xa0Ǚ\xa5\x8eKm\x94~\x9e\r2G\xf7\x9c\x91\xfa\x1ev\x92\xbf\xcb\xf0f/g\xa12\xd0\xcf\xeak\x1a\x8c\xf4\xea\xe4R=\xe5\xf5\xa2\x14\xa3\x11~G\x01\xdf\xca\x00\xe0Nc\xcc\xef\xf5+\xaf\x05\x0e\xa4(\x8a\xcbB\b\xcfc8\x81;\fb\x0f\xa9\x03fe\x8a!(`aڧ\x82\x88\x8fXP\x03\x15\x17\xd2\xf8:<\tU\x81\xaa\x03Ѵ\xf3\x16\xbc\xf79\x80_ٳe\xc7\xc0\x9a\xecc\x88\x8a\x1d#Gg:\xee8\x82\x03\xea\x13\xf8\x9f\xe5@\x00`ϖ\x1d\xff\xcb9\xf7\xe1\x10\x02ZY\xb34\xe6\xa6\xde\x05\xe4\xe0`\v\v\x979$-\a;c\x90\xce$p\x13\x0e\xa3ӥ\xb3\x19\x1d\x1b\xc1\xda\xc3kp\xf2\xf4I\x18\x9d\x18Ac\xb2\xf1\xff\xb5w\xae!v]\xd7\x1d\xff\xaf\xbdϽ3#K_T\x88mZ\\ZB\xa0z\x9b@\xdcGH!\x1fR\xbbNH(\t8\xae)\r\xa5\r-qh\xa8\xa4\x12ZSH\xa1hf\x14h\x1e\x1f\xf2h\xa1\xfd`5\xa4\x8e\x9b>▒\x96\xbaP\x97\xd8ռG\xc6\r8vd[\xb6\xf5\x98ǝ\xfb<g\xaf\xd5\x0f\xf7\xac{\xd7\xd93\xaa\xa4yH\xc9e\xffĠ\x99\xb93w\xce\xdeg\x9f\xbd\x9e{-\x8c7\xc71\xd6\x1a\x83\xdfp\xc8:\x1e\xbe\xe71\xeeƑQU;\xb2\x9a\xb8\x9d\x87Z\xad\x06\x0e\ft\x01Z\x1d\xf6ˈ\x95\x17\xe7\x1c:\x9dNE\xe8Xal\x85\x95}\xc0\xb6\xf2\xbbo\a\xebZ\xd3\xf7\xb6\n\x94}\xddj\xb0VX\xeax\xecƱז\xa8\x88<\xc1̗\x8b\xcb=`\x1d T[\x1fX\x8d>\xb6\xe4\xacU\x15[\n6U\xddλZ\x90\xd6M\xa7s\xa0\xf3\xa6\xf7V\xd7!\xe7\x01\x14\b\x94\x03\xdcb\xb8\x8eC\xb1\x9a\xa3X)\xfa\x15\x97W\x03\xd0\x10\x84\xf5\x02h\xf7\xcf'P\xe1\xc0/\a\xe4\xd7:\x10\x91\xcb\x00\x9e؍\xf9\xb2q\x86XqV\xb6r\xa9\xd9{\x1f\xbbj\x89\b\xa2J7\x0f-\xf0\xd8Ka\xf7N}Om\xfbm\x95#\xbb\x0f\xe9\xde\x13[F\xb1{P\xef\x8f~n\xc3\x01X\b\x10\x04\x10\xd1%\"zd\xe1\xcc\xccM\uf6db\x04\xc8\v\u007f\xfaܳD\xf4\x18\xf3\xf0샕\x8cV\xa3\xd6Iҋ\xb1\x12X\xbf\xb6\x83\x8d5p\xfb0Z)i\x17\xa4\x95\xa2\xaa\xb9\xe9\xffz3\xb3̃@\xd8h5\xf4\xc6\xff\xf1\xd2\xd4\\\xa5q\xd5N\xb1\xfev\x00\x95<\xf9ؕa\xad\xa9\xd8J\xd3\xf1\xdc\x0e\x17\x96\xc59\xf7\x99,\xcb\xfe\xa1(\n\xac5V\x118@\xb8\x1a_\x88ﭵ2\x14\xe6\xfe\xe1\xa6:\xea\xf0=\x87z\xaf\x86\xac\xe51ѝ\xc0Dk\x02\x13\x8dq\xf8\xb7\x1d\xc6.\xd71\xf1\xf68&\xae\x8e\xa3v%\xc3\xd8\xea\x18\xc6\x1bc}\v\xa8\x95!\xebxP\x87\xe0\n\x87Z\xa8\x81ߪ\xfa\xe5\xadŪף\xe6w\xfca7B;\xff\xfa\xbb\xbb\xe1&\x8aݳ:\x17\xfa\x9an\xaa\x8a\r*\x0f\xe6\xcdXW\xb1\xb5\xbeW,Mͭx\xef?\xe1\xbd\xcfõ\x1c\xc5Հ\xcc\x0f\x0f\xf0Z\x85к\n\xb7rO\xc6J\x8f>õZm\xcb\x03\x89[=\xe3\xf1\xbd\xb0_[m\xbf\xf2\xf3\x8c\xfei\xed\xd2U\xd6Y\xed\x80\u007fX@\xd6\v\x88HOD~syz~S\xbb\xd5\xed`k\xac\x01\xc3\xe3\x00VyP%7v\x01\xd99\xb4\xe3\xd1\xf7i?\xbf\x014\xcb^6\xd1Y0+\xac\xec~\xab\aQ\xb7J,\xb2\x9f\xeb\xb5\xe4y\xbee\xb2S\x1cs\xe1P\xc6\x1c\xe7z\b\x1cP\x14ś\"\xf2\xf0\u0099\x99\xb7ne\xbe\xb6\\\xc1\x8d\xe6\xfao\xb4:\xad\x8aD\xb4\x99\x10\x006\xf9\xa4\xad\x1bJ\x1fx\x95\xb2:\x99\xfa\x1e\xb6\f\xb3]`ֽa\xad\x10\xf5u덈\xfd\xf2!\x0fhu\x9az}\u007f\xb4457u+\x93p\xb3\xd8ִv\xa3\xb5\xae:}(c\xf3юu/}\xdf\xd7c\xe1\xccL\xb7(\x8a_\xf3\xde\u007f\x01\x00\x1a\xcdu\xa8\x92\x00\xd3\xc0\xcb\xde/{\x9dv<ֺR\xad\xc6f`\xa9\x89\xef\xbd\x1f\x1c\xect=B\xd6\xcb\xe0[\x1e\xbe\xe1Qo\xd41\xbe6\x86\xfa\xd5\x1a\x8a7{\x10\x910\x11Ɵ\x98X\x99\xc0\xc4\xda8\xc6\xd6\xebp\xab\x04Z\a\xc6\xf21p\x93\x81\x1e\xc0=\x1eTص\x0fT\xaf\xd7\x1b\x9c\xfe\xd7q\xc4\x1b\xfeN\xd9\xca]\x19k~V\xf3\xb4\xe5^\x94\xadb\x86{\xcd\u0099\x99\xef\x10ч\x9ds]Y\x0f\xa0פ\xe2\x82\xd1\x18\xa5\xddt\xe2Mӎ\x85\x99+\xf1\xa5\xd8\xfa\x06\xaaq\x84\x8a\xb6\x8b\xeb\x9f\xef\xb1V\x9d\xdd\xfc\xac\x05\xc7\xcc\xc8.9\xf4\xaeu\x00\xa0\xeb\xbd\xff\xf0\xf2\xf4\xfc\x96\x85\xfe\xb6C\xac\xdcY\x97T\xec~\xb2V\x9b\xbd\x97\xb1UW\n\x80\x9c\x88\xd0{\xa9\r\xf7\xa6\x83\xa0z\xf6*V:cE.^\xc3\xfa\xb3:W\xfa\xbfƸ\xecu\xe8\xfbW\xbc&\xaf\v\xf2\x99\x8eދ\x17\xbd\xf7?\xbf45w\xcb.\xc0M\x02\xe4\xf0\xa9\xe3\xef\x05\xf0\x01\x11\xc1F\xab\x81v\xb7UY$v#\xb1\x03\xd5&%ַ\x1dkYvAY\r\xcd.L5!m9\v}\xd8\xf45\xe7\xfa7 \x84~\xaan\xb3\xdb\xd4k\xfb\xcc\xd2\xd4ܟ\xdd\xea$\xdcp\x92\x9c\xab,,+L\xad;B\xc7`\xb3$\xf4\xf7m*\xf0nnj\xb7\u008b\x9f_\f\x8b\x93\xb3\xbfOD\x9f&\"n\xf7\xdah\xb67\x00T\x9b\x0f\xe9x\xd4|\xbe\x9e\xb6\x1ck\xfb\xd6\n\x03\xaagB\xecB֏n\xaf\x83f{\x03!\x84\xe0\xbd\u007f\xc4\xc1}\x87\n \xb4\x02|ףޭc\xa2;\xd1O\u007fn\x8ccbu\x1cw\xad\xeeþ+\x13ؿ\xb2\x1f\x13\xd7\xc61\xb6RGm5\xc3]\xdd}\xa8\xb52P\x93\xfa\xbf+u8v\xc8|V\xb9?\xdb%\xd6\xfe\xec\x1c\xc4\xcd\xcet\xbc[\xf5\b\xb1\xbf\xa7J\xd8\xed`qr\xf6\x9f\x01|\x90\x88\xdaE(\x10^ɑ\xbfַ\x86\xec\xb3\x06TcMz\xdfl\xc0V\x85\xa3\xf5\x1c\xd8ZU\xf6^o%$u\xcc\xd6\xdaT\xb7\xca\xf5<\x11!\x04\xe0-\x00\x17Y\x15\xd063?\xbcpf\xe6_vs\x9e\xc2J?\xabLZ\x02i3\xb8\xc3p\xec\xe00TJT\xc8\xc5^\x04k9X\xa1Z\xce\xe33\xde\xfbsD\x84\xe2\xed.\xa4\xac6_\xaf\xd5+?k\x05\x16PMW\xb6Ϧ\xfe\x8e\xf5~螣\x16\x8b^\xc7P\xe0\x01\xae\xe5\x10\xe6z\xc8\xdf\xea\xe8\xef\xfeG\bᗖ\xa6\xe6\xb6U\xeeiӮ\xe0\x9c{^D~\xd79\xf7\xba>\xfc\x1b\xadF\xb9є\xfeO\x93\xb1\x13\xe7\x1dǧLcS/\x8e\x83\xc4~;]\xa0q\n\xe8p1\xf67\xe1v\xbbi\xad\x8e\x00\xe0w.\x9c]ؕ\xa0y\x8cՎ\xac\xfbM7\xcb8\xa5\xd8j\x16vA\xe8F\xb3W\xb9\xff7\xcb\xd2\xd4ܗ\x00|\x84\x99[DT\xb9\xbf\xceh\xef\xf6\x01\xd7\xfba\xcfpX\x8b\xc4\xdeO[\xf2\xc4\xc6'\xfa\x9f\xf7\u007f\xae\xd1\\G\xaf聈\x82s\xee㋓\xb3OY!\x16k\x81\xb1\x9fXB\xff\xc1\x96\x8e\xa0^\xd4A\x1b\x84z\xab\x8e\x89V\xdfz\xa9]\xcd0qm\x1c\x13\x97DZ\xff\xda\xce\xdbO\xdb\xcdAǢ\xd7i-S\x00\x83\x18\xce\xf5,Q\xbb\xd6o\x87\x1bKY\x9c\x9c\xfd\xaes\xee!\"\xea\xbb{z\f~\xb5@X/3ʀ\x8a\x10\x04\x86\x15\"t-ر\xeb|\xd8Tj\xbb\xfe\xb7JÍ\xc7k\xf7\a\xbd\xb7\x83\x98\x99*\\-\a\\dP>\x98\xaf\x15\xef\xfd\x83\xcb\xd3\xf3\xff\xb6\xeb\x93\xc4\x02\xe9\t\xa8\a\xa0\x03\xa0%(Vs\xe4Ws`U k\f^\v\xa0\x16P4\np; t\xfa=B\xc0\xd5d\v\xa0\xe2\xa2\xcb\x01<&\"\u007f\xe2\x9cC\xaf\xdbF\xef|\x1b\xf2\x92\f\xaaW(Vp\xeb\u05fa'Z\x8f\x90\x9dkUZ\xad\x12\xa0\xffk܋\xe7z\xc8\xff\xb7c\xef\xc79f~pyz~e\xbbӵi\xf5.N\xce\xf6.\x9c]\xf8\x8a\x88\xbcSD\x1e'\xa2K:!\xadN\x13\x1b\xad\x06Z\xed\x8d\xe1\x03N\xd5\x1ce\x9b\xae\x16\xbb\xb4l)\x12\xab\xf1l\xe5\x1f\xb5\x82ƹ\xe1f\xd5\xe9u\xb0\xbe\xb1\x860p\xbf\xe0\xbf\x00ܿ45\xf7\xf5\xedN\u008d\x10\x91Wl`V\xb5\x0f벱c\x8a\xcd\xf7\xad\x02\xadY\x96\xddQ)\xb2<=\xff\x8f\xde\xfb\xf7\x10\xd1w\xf5\xc1n4ױ\xde\\\xaf$0\xe8\xbds\xce\r*\xa8ƽ@\x80\xeaحeBD\xfd\"\x98\xe5\xbd\xdch\xad\xa3\xddm\xe9\x02n3\xf3\xa3KSs\u007f\v\x00Y\x96m\xe8߱\nD\xfc0\xa9Eg\xad\xdc؟l\xdd E^\xbc\xb2\xd3\xf9\xf2M\u007f\xcdu\x1c\xa8G\xa0\x02\xf0\xe47\xa5\xa7[\v:\x16\x9e\xd6\xe26k\x00EQ\xbc\xbc\xd3k\xbb\x15\x96\xa6\xe6\x9e%\xa2w\x85\x10\xbeFD⽇_#\xe0\"C.2P\xaeJ\xad\x94`㛱\xa2d\xad\x11\xbbVb\xc5B_\x13\x91A\xe3\xadX\xc9\x1c\xccKyHQ\x82 \xbcZ\x00\x17\x19\xe1\xca\xc0\xc5&y\x9e\u007f\xd5{\xff\xae\x8533\xff\xb9\x17\xf3c\xaf\xd5*.\x833\x19\xdcO8A\xde?\xf7\xc2M\x86l0\xc2j\x81\xe2Z\x8e\xe2J\x0e^c\xf0z@\xb1\x9e\xf7\x85PW\x10:\x8c\xc5\xc9YY\x9e\x9e\xff\x1c3\u007f\xdc9\xd7\x15\x11\xb4V\x1b\x90\xc5\x02\xf2\x03\xdd\xfb6\x1f\xc0\xd4\xfd\xc6*\xa4\xfa\\\xd8\xfd\xc5>\x0f,\xfd\xc3ò\"\xc8g\xbb\xc0b@\x11\x06\xc9\x13\x97\x9cs\x9fȲ\xec\xb1\vg\x17\xb6\xd5\xfaW\xb9nz\xca\xf2\xf4|\a\xc0\x97\x0f\x9f:\xfe\x97ιO2\xf3gE\xe4\x1dz\xd3\xd77\xfa\xd5}\xbd\xf7\x98\x18\xdb7,U,\x02\x8a\x82K\xf6a\xaa\xd5j\x83ÇV\x13\xb7f\xaes\x04熾\xbf\x8dV\xa3\xb2Y\x97Z\xcf\xd5\x10\xc2i\xe7\xdc_-N\xce\xee\xa9#\xb9\xd9\xdex\x03@E\xb3\x8eMt\xbb\x91\x84N5;-\xeeD&\"\xe8\xe6\x9d;k\x86\x00X\x9c\x9c]>r\xfa\xc4\a\x88\xe8\xa1\x10\xc24\x80C\xde{=\xc1\x0f\xf4\x80\xfd\xfb\x0e\x94Z\xa4\xc0{B\x91\x17\x83\x12\xe4\xd65e\u074c\"2H\xcb\r!\xa0Wt+\xf1\x94\xd2\xdd\xf1\x8cs\xeeS\vgf\x06\xa5\x12\x1a\xcd\xf5\xa6nHV\x11\xb1Y?\xfa\x1e\xba![aa\xb54\x15\x1e\xe5k\xaf\xeft\xae\xf8Z\xb1j\x95\x9a\xc09 \x82\x80jY\x16\xf1\x00\x02#\x80\xe1\x88\xc0(\x06cf\xe3\xea#\"\x14\x12\xe0\x89\xb6]z|\xbb,\x9c\x99\xb9\f\xe0\x93\x87N\x1e\xfb\x1a\x80/\x89\xc8/\x00\xa5r\xf4j\u007f?q\xe4@?偬\xfc\xbeT\x9b\xa6\xc5~ykeYKB\u05c8Zj\xf5z\xbd\xd2\x1b\x9c\x8c\xbb\v\x05\x80\xd7\x18\x05\x0fS\xf8\xf5~z\xef\x9f\x13\x91\xc7_\xfc\xfc\xe2\xcc^\u038d\xae7ݏ\xac[ֺ\xd4\xf4\xfa\xec\xf8\x15-\x15\x92e\x19Bs\xe8\xfaW\x16'g\xbfq\xe8\xe4\xb1e\xe7\xdc\x14\x11=(\"\xe0\xb5\x1c\xc5\xf9\xfe\xdf\x1c;\xb8\x0fr_\xbf}\x00K\x80s\xc3\xf5o\x15\xb7\x81\xd2B\x0e!\f\xebp\xf1\x9b\x8c\xe2\xf5n%\xe6T\n\x9b\x0e3O\x13\xd1\xd4\xe2\xe4\xec\xc6n\xcc\xd7\r\xf3\x1b\x97\xa7\xe7\xdb\x00\xfe\xfc\xf0\xa9\xe3_!\xa2_%\xa2\xc7D\xe4a\xe7\\\x1d@\xa9U6*\x1b\xaaw\x1e\xb5\xac^y\xe0\xbd\xf7 \xe7\xd0\xeb\xe5pnh\xeao\xca`\xe8\xe5hv;\x95߳\xc1$\"z+˲\xbf\x16\x91\xe9\xe5\xe9\xf9\x1du\x1e\xbbY\xac/_\xaf\x15\x18\x96\xb2\xb7\x9bWlBZW\x85\x8d\xe7\xdci7\x96\xb245'\x00\x9e9|\xea\xf8\xbf:\xe7~\v\xc0\xe7\x98\xf9\x1dz/U\x988\xe7\xc0ݲ\x05\xa6\xf3\xb8k\xdf\xfe\x8ae\xa0\x14E\x8e^\xd1۴\xc9\x18\x8d\xf3\r\xef\xfd\xa7E\xe4\xe9\x8533\x15\xdb=\xb6@\xab\xae\xaf\xeaIZk\xc2[\v\x00\xc0\xc0Z\xb2>㝢\u007fǺd\xf4z\xac\xe6\xad\u007f\xdf\n<+\xe0b\x8bĎ\xf9vs\xe1\xec\xc2\xf9ç\x8e\xbf\x97\x88\x1e\x11\x91\xdf\x06\xf0\xcbDD\x03w\xf4\xc5|\xa0\x00\t3\xd8\t0N\xc8\xee\xae6\xf3\xb2q\x0e\x0eܯ\x05'\xd5\xcdغ@\x9ds\x90\xcb\x02j\t\x8a\xa2[YG:\xcfjq\x88ȳι\xaf\x8b\xc8\xdf\\8\xbb\xb0\xe7\x93\x15\xefY\x9a\x95e\x9fW{$\xc1\xde\u007f+,u\x9d\xd8{\x1e\xcd\xfd\"\x80\x87\x8e\x9c>\xf1~\x11\x99\n!\xbc[_k_\xd9@\xb6\x9a\xa1@ѷ\xfa\xb3\x1a\xb2\xfdu\xc8]\x02\xdc\x05`\x1f -AX\v\xa0\rB\xde\xee\xf4לȦ}\x13\x18\xec_犢\xf8\xec\xf2\xf4\xfc\x0fws\xben:A\xbe\xb4H\x9e\x06\xf0\xf4\x91\xd3'\x0e\x02\xf8(\x80_\x17\x91\xf7\xe9\x84\xeaD\xf5\xf2\x1e\xf2\"\xaf<\xf8q\xf6\x89\x1d\x1c\xb0Y\x9b\xd5`t\xa9\x81p\b\xe1\x99\x10\xc2_\xd4j\xb5g\x16'gw\xbf\x9d\xdf\xff\x03\x11\xfd\x0f\x80\t\x00\x9b\x04\x81}H\xac[%\x96\xfev\xac%\xbb\xdf\bb\a,O\xcf\x17\x00\xbez\xe4\xf4\x89s\x00>\x04\xe0#\"\xf2\x90\x88\xec\x8f\xcd\xfa,˰\xd6X\xad<\x1c:\xfe\xd8\xefo\xfc\xb7\x8b\xcc\xfcM\xe7\xdc\x17\x97\xa7\xe7\u05f7\xba\x06\"\xea0\xf3\xb7\x01T,\xd48\xbef\xad\x13+\x90\xad\xb6h\xcb}3\xf3\xb6\xfbC(\"\xb2Q\x14ŷc_\xb4]\x0f\"R\xb1\x9e\x00T\xae\xc5Z\xa5\x806/ʾ\xbf\xd3k\xdb\t\xe5\xc9\xeds\x00\xce\x1d:y\xec'E\xe4c\xcc\xfc\b\x80\a\xac&>X\xcf\xcd\x02\xfcr5\xb5?\x18\x97\xads\x0e\xc2\fq\x0e\x85\xb1\x06E\x04\x01C\x8f\x84\x18\xc5j\xa0<\x0e{\xe9|/˲o\x10\xd17\x17\xce\xccl\xbb\x15\xf5v\xd0\xf1ڴl\x1bطV\xa8\xae\x05\xfb\xba\n\xcaxO\xbc\x9e¸45\xf7\xef\x87N\x1e{\x0f\x11}\xd4{\xff83\xffb\b\xc1Ya\xc4\xc2謵@\xeb\xe5<\x995e\x15\x15+\xc8\xcb\xe7\xf0\xbcs\xeei\"\xfa\xd6\xe2\xe4\xecK{1_;V\xcf\x0e\x9f:~\x9f\x88\xbcOD\x1eȲ\xec\x01f>\x01\xa0\x06Ts\xe7\xad\x14\xb7n\x1f\xdb\r\xcbNH\x96e/2\xf3\xf3\x00\xbe\a\xe0\uf5e6\xe6n\xebBJ\x00\x87N\x1e\x1b\x03\xf0\xfe,\xcb>\"\"\x1fb\xe6{\xe3\x87V\x96*(\x00\x00\x05\x9fIDAT\xc6\nE\xbbї\x9f\x9fg\xe6\xa7\x00|\xeb\xc2م;\xbaQ&n\x8dç\x8e\xff,\x80\x0f\x028FDGC\bG\xbc\xf7\xfb\xac\xb0\xb6V\x9fM\x12Qb\xcb[\x85\xa8U*\x99\xb9\xc5\xccK\xde\xfb\xc5\x10\xc2\x02\x80\u007f\xbapv\xe1\xb6ƅ,\x87\xbep\xe2Q\xef\xfd\x93\xba7Yk\x11@\xe5\xb0\xe4VY\x95:F;G\xe5x\x9f\x9a\xff\xbd\x17>v\xa3\xbf\xffs\u007fp\xf4\xa0s\xeeWD\xe4\xe1,\xcb\x1e\x12\x91\x83V\x10\x01Մ\x0e\x9d\xf7\xf2\xef\x05\"z\x0e\xc0\xd3\xcc\xfcw\xcb\xd3\xf3;j\xa4w3\xecz\x0e\xe1\xd1?\xbc\u007f\\D\x8e3\xf3\x03Y\x96\xddW\x14\xc5O\x88\xc8A\xef\xfdA\":\xc8\xcc\a\xbd\xf7\x8e\x99WDd\x15\xc0\x8asn\x85\x88V\x99\xf9\xb5\x10\xc2\xf3ι\x17\x96\xa7\xe7\xb7l\xa1\x98\xb8s\x1c:y\xec\x00\x11\xddCD\xf7\x88\xc8=ι{\x01\xdc\x03`\x8c\x99/\x89\xc8%\"z\x13\xc0%\"z\xa3\xacŕ\x18\x01\x0e\x9d<\xe6\x88\xe8g\x9csG\x99\xf9(\x80{\x9ds\aD\xe4\x003\x1f \xa2\x03Y\x96\x1d`\xe6\x03!\x84}ι\x1637\xb2,k0s\x03@\x83\x99\x1bD\xd4@\u007f},\x02X\x04\xf0\x83\xa5\xa9\xb9\xdbW\x96\xe1\x06\x1c\xfe\xe2\xfd\x8f\x02x2N\x92\x897q\xebފcn\x83X\x84\xc9V\v!<\xb5\xf8\xa9\xf37\x14 \x96#\xa7Ox\x00?\r\xe0n\x00w\x17Eq\xb7\xf7\xfen\xef\xfdAf\xbe\x06\xe0\r\"\xba䜻\xc4\xcco\x88\xc8奩\xb9\xdb\xea\x1b\xbf=I\xe8\x89D\"\xf1c\xc0\xd1/\xbf\xfbQ\"z\xd2\xc65ĸ\xe84&d\xd3فj\x8cL\x05\x8e\xba\xe0K\xe1s\xcb\x02\xe4ǁۗ\x84\x9eH$\x12?\xe2\xd8TظK\xaa\x8d]\xe9\xf7\xb6\xaa֠Yfz>\xc8\xc6&F\x8d$@\x12\x89D\xa2\xc4\n\x0e\xa0Zj\xdd6\xbbR\x97\x96Z#63Ϟ_\xd2\xf7ܭl\xc0\x1f5\x92\x00I$\x12\x89\x12\x1b\xe8\xb7.)}M3\xa3\xac@\xb0\xf5\xf9\xe2\xb31q\xe2\xc0\xa8\x91\x04H\"\x91H\x94hv\x95\xcd\x1e\xb5\x99V6\x95\x1d\xa8\x96\xd9\x016\x17\x93̲\f\xbd^\uf39e\xf7\xd9K\x92\x00I$\x12\x89\x92\xb1N\x1d\xb5n\x86Z\x91A\xba\x02)L\ttS\x85B\xbf\x06\xaa\xe7CT\xd8h\xc5\r\x15\"\xa3*@v\xdei'\x91H$F\x84Z\xab\x86:\xeap\x9d\xe8lGF\xc89G6VC\xaf\xe8!\xab{xr`b\x88\xeb\xd7F\v\b@Vm\x8b\xa0Av[\xf6d\x94H\x02$\x91H$JB\b\xf0\xceo*S$\x85\xa0F5\xa0\x03Ըo\x9d\xd4|\xbf8\xac\xba\xb5\x802\x80N\xfd\x1ai\xf0\x00\x9c\x80\x89\xe1j\xa3\x19\x03I\x02$\x91H$JlI\x16%._\xa2'\xcd5\x0eb[X\x88\xf4\xab\xe0:\xa6\xb2\xb21\rʼ\x8f\"I\x80$\x12\x89\x84\xc1\x16\xe3\xb41\x0f[<Q\xcf{h\x8cC\xd1fxJ\xfc\x1e\xa3\xc6h:\xe6\x12\x89Db\x1blU 5>\x8d\xee\xbdG\xbd^\xaf\xa4\xf7\xdaC\x83\xa6\x04}\xa57\xcc(\x92\x04H\"\x91H\x94\xa8P\xb0\xc5\"m\xdf\x19\x1b\x1c\xb7\x02fll\xacr\xf8\xd0\xf6\x0f\xb11\x92Q#\t\x90D\"\x91(\xb1}^l\xd3(\xdb\xf7C\u007fFk]eY6(_\xa2B$nc\x11\xf7O\x1f\x15\x92\x00I$\x12\t\x83\xed壂\x01\xd8\xdc\xee\xd6V\xdbՒ&q\x8bY[|q\x14I\x02$\x91H$Jt\xc3W!\xa0օ\r\xa0\x03\xd8t\x98ЖqW\x01\xa3n/\xb5fF\x91\x94\x85\x95H$\x12\x06ku\xd8&x\x8a\xado\x15\xf7N\x8f\xddU\xea\xd6\xd2\xd8ɨ\x91\x04H\"\x91H\x94ؔ]-\x90\xa8\xc4}\xd0\xf55ۦ8n[\xac?kS}G\x89\xe4\xc2J$\x12\x89\x12kQ\xd86\xbc\xdavۦ\xee\xda~!\xb6d\xbb\xad\xd6k\xad\x94Q$\t\x90D\"\x91(\xb1\xc2\xc0\x16@̲l 0\xecY\x11k\xb1\xe8\x87E\xab\xfa\x8e\xaa\v+\t\x90D\"\x910ĥKl\tw\xb5(\xf4\xc0\xa0\x8do8\xe7*\x95wm<dT\x8b)\x8e\xe6\xa8\x12\x89Db\x9b\xc4\x19W\x8a\x9e0W\xc1\xa2\x8d\xa4,Z'K3\xaf⬭Qc4#;\x89D\"\xb1\r\xbc\xf7\bE@Q\x14\x95\x96\xb4궲=A\xb4\x0f\x88\xbe\xa65\xb4\xac\xf0Qa4\xaaq\x90d\x81$\x12\x89D\x89MŵYWZq\u05f6\xaf\xd5v\xb7\xde\xfb\x8a\xb5\xa1ߋ\x85\xc8(\x92,\x90D\"\x910h}+\x1b\xf3\xd0\xefٲ\xed\xeaʊ˟\xd8`\xba\xfd\xf9Q$Y \x89D\"\xa1\b\x02\x04\xa8\xd7\xea(\xf2\x02\x10@X\xc0\x81\xe1\xc8m\xfa<\x14\x01\x04\x02\x04\xe0\xc0\xe0\xc0 \xf3OX\xfa\x1f\"\xf9\x9d\x1e\xda^\x90,\x90D\"\x91(iu\x9a\xdf\aL\x89\x926W\x0e\x14Z\xb7\x94Z&\xfay\xadV\xab\x94n\xd7\x18IY\x0e\xe5\xbf\xef\xc4x\xf6\x9a$@\x12\x89D\xa2DSs\xe3\x02\x88\x1a8\xb7'\xd05E\xd7\xc6;\x00l\x126\x1a?\x19E\x92\v+\x91H$J4\x80\x1eB@\xadV\x1bX\x1f\xb60\xa2\n\x19\x15\x1c*h4F\x12\xc7?\xf4c\x14I\x16H\"\x91H\x948疙\xf9\x9d\x9ay\x05\xa0\x92\xaa\v\fO\xabk\xb7A[<\xd1\n\x16\xfd\xba\x14:Wn\xffh\x12\x89D\"\x91H$\x12\x89D\"\x91H$\x12\x89D\"\x91H$\x12\xdb\xe1\xff\x00a`\x0e\xb8q\xfd\x8e\xd6\x00\x00\x00\x00IEND\xaeB`\x82"),
321
        }
322
        file18 := &embedded.EmbeddedFile{
323
                Filename:    "tray.html",
324
                FileModTime: time.Unix(1535012730, 0),
325
                Content:     string("<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-355, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0\">\n{{if USE_CDN}}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://assets.statup.io/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css\" integrity=\"sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://assets.statup.io/base.css\">\n{{ else }}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"/css/base.css\">\n{{end}}\n\n    <title>{{.Name}} Status</title>\n\n    <style>\n        BODY::-webkit-scrollbar { width: 0 !important }\n    </style>\n\n</head>\n<body>\n\n\n<div class=\"container col-12 sm-container\" style=\"margin-top: 0 !important;\">\n\n    <div class=\"col-12 full-col-12\">\n        <div class=\"list-group online_list\">\n        {{ range .Services }}\n            <a href=\"#\" class=\"service_li list-group-item list-group-item-action text-truncate {{if not .Online}}bg-danger text-white{{ end }}\" data-id=\"{{.Id}}\">\n            {{ .Name }}\n            {{if .Online}}\n                <span class=\"badge bg-success float-right pulse-glow\">ONLINE</span>\n            {{ else }}\n                <span class=\"badge bg-white text-black-50 float-right pulse\">OFFLINE</span>\n            {{end}}\n            </a>\n        {{ end }}\n        </div>\n    </div>\n\n    <div class=\"col-12 full-col-12\">\n    {{ range .Services }}\n        <div class=\"mt-4\" id=\"service_id_{{.Id}}\">\n            <div class=\"card\">\n                <div class=\"card-body\">\n                    <div class=\"col-12\">\n                        <h4 class=\"mt-3\"><a href=\"/service/{{.Id}}\"{{if not .Online}} class=\"text-danger\"{{end}}>{{ .Name }}</a>\n                        {{if .Online}}\n                            <span class=\"badge bg-success float-right\">ONLINE</span>\n                        {{ else }}\n                            <span class=\"badge bg-danger float-right pulse\">OFFLINE</span>\n                        {{end}}</h4>\n\n                        <div class=\"row stats_area mt-5 mb-5\">\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.Online24}}%</span>\n                                Online last 24 Hours\n                            </div>\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.AvgTime}}ms</span>\n                                Average Response\n                            </div>\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.AvgUptime}}%</span>\n                                Total Uptime\n                            </div>\n                        </div>\n\n                    </div>\n                </div>\n            {{ if .AvgTime }}\n                <div class=\"chart-container\">\n                    <canvas id=\"service_{{ .Id }}\"></canvas>\n                </div>\n            {{ end }}\n                <div class=\"row lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}\">\n                    <div class=\"col-10 text-truncate\">\n                        <span class=\"d-none d-md-inline\">{{.SmallText}}</span>\n                    </div>\n                    <div class=\"col-sm-12 col-md-2\">\n\n                    </div>\n                </div>\n            </div>\n        </div>\n    {{ end }}\n    </div>\n</div>\n\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js\" integrity=\"sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js\"></script>\n<script src=\"https://assets.statup.io/main.js\"></script>\n\n<script src=\"/charts.js\"></script>\n\n</body>\n</html>"),
326
        }
327
        file19 := &embedded.EmbeddedFile{
328
                Filename:    "user.html",
329
                FileModTime: time.Unix(1538459587, 0),
330
                Content:     string("{{define \"title\"}}Statup | {{.Username}}{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <h3>User {{.Username}}</h3>\n        {{template \"form_user\" .}}\n    </div>\n</div>\n{{end}}\n"),
331
        }
332
        file1a := &embedded.EmbeddedFile{
333
                Filename:    "users.html",
334
                FileModTime: time.Unix(1538459610, 0),
335
                Content:     string("{{define \"title\"}}Statup | Users{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <h3>Users</h3>\n        <table class=\"table table-striped\">\n            <thead>\n            <tr>\n                <th scope=\"col\">Username</th>\n                <th scope=\"col\"></th>\n            </tr>\n            </thead>\n            <tbody>\n            {{range .}}\n            <tr>\n                <td>{{.Username}}</td>\n                <td class=\"text-right\" id=\"user_{{.Id}}\">\n                    <div class=\"btn-group\">\n                        <a href=\"/user/{{.Id}}\" class=\"btn btn-primary\">Edit</a>\n                        <a href=\"/user/{{.Id}}/delete\" class=\"btn btn-danger confirm-btn\" data-id=\"user_{{.Id}}\">Delete</a>\n                    </div>\n                </td>\n            </tr>\n            {{end}}\n            </tbody>\n        </table>\n\n        <h3>Create User</h3>\n\n        {{template \"form_user\" NewUser}}\n\n    </div>\n</div>\n{{end}}\n"),
336
        }
337
338
        // define dirs
339
        dirk := &embedded.EmbeddedDir{
340
                Filename:   "",
341
                DirModTime: time.Unix(1538894434, 0),
342
                ChildFiles: []*embedded.EmbeddedFile{
343
                        filel,  // "base.html"
344
                        filem,  // "dashboard.html"
345
                        filen,  // "error_404.html"
346
                        fileo,  // "favicon.ico"
347
                        filep,  // "footer.html"
348
                        fileq,  // "form_checkin.html"
349
                        filer,  // "form_notifier.html"
350
                        files,  // "form_service.html"
351
                        filet,  // "form_user.html"
352
                        fileu,  // "head.html"
353
                        filev,  // "help.html"
354
                        filew,  // "help.md"
355
                        filex,  // "index.html"
356
                        filey,  // "login.html"
357
                        filez,  // "logs.html"
358
                        file10, // "nav.html"
359
                        file11, // "robots.txt"
360
                        file12, // "scripts.html"
361
                        file13, // "service.html"
362
                        file14, // "services.html"
363
                        file15, // "settings.html"
364
                        file16, // "setup.html"
365
                        file17, // "statup.png"
366
                        file18, // "tray.html"
367
                        file19, // "user.html"
368
                        file1a, // "users.html"
369
370
                },
371
        }
372
373
        // link ChildDirs
374
        dirk.ChildDirs = []*embedded.EmbeddedDir{}
375
376
        // register embeddedBox
377
        embedded.RegisterEmbeddedBox(`tmpl`, &embedded.EmbeddedBox{
378
                Name: `tmpl`,
379
                Time: time.Unix(1538894434, 0),
380
                Dirs: map[string]*embedded.EmbeddedDir{
381
                        "": dirk,
382
                },
383
                Files: map[string]*embedded.EmbeddedFile{
384
                        "base.html":          filel,
385
                        "dashboard.html":     filem,
386
                        "error_404.html":     filen,
387
                        "favicon.ico":        fileo,
388
                        "footer.html":        filep,
389
                        "form_checkin.html":  fileq,
390
                        "form_notifier.html": filer,
391
                        "form_service.html":  files,
392
                        "form_user.html":     filet,
393
                        "head.html":          fileu,
394
                        "help.html":          filev,
395
                        "help.md":            filew,
396
                        "index.html":         filex,
397
                        "login.html":         filey,
398
                        "logs.html":          filez,
399
                        "nav.html":           file10,
400
                        "robots.txt":         file11,
401
                        "scripts.html":       file12,
402
                        "service.html":       file13,
403
                        "services.html":      file14,
404
                        "settings.html":      file15,
405
                        "setup.html":         file16,
406
                        "statup.png":         file17,
407
                        "tray.html":          file18,
408
                        "user.html":          file19,
409
                        "users.html":         file1a,
410
                },
411
        })
412
}
+204
func init() {
205
206
        // define files
207
        filel := &embedded.EmbeddedFile{
208
                Filename:    "base.html",
209
                FileModTime: time.Unix(1538458071, 0),
210
                Content:     string("{{ define \"base\" }}\n<!doctype html>\n<html lang=\"en\">\n{{block \"head\" .}} {{end}}\n<body>\n    {{template \"content\" .}}\n</body>\n<footer>{{template \"footer\" .}}</footer>\n{{template \"scripts\" .}}\n</html>\n{{end}}\n"),
211
        }
212
        filem := &embedded.EmbeddedFile{
213
                Filename:    "dashboard.html",
214
                FileModTime: time.Unix(1538459427, 0),
215
                Content:     string("{{define \"title\"}}Statup | Dashboard{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\" }}\n    <div class=\"col-12 mt-3\">\n        <div class=\"row stats_area mb-5\">\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.ServicesCount }}</span>\n                Total Services\n            </div>\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.Count24HFailures }}</span>\n                Failures last 24 Hours\n            </div>\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{ CoreApp.CountOnline }}</span>\n                Online Services\n            </div>\n        </div>\n        <div class=\"row mt-4\">\n            <div class=\"col-12\">\n                <h3>Services</h3>\n                <div class=\"list-group mb-5 mt-3\">\n                {{ range Services }}\n                    <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                        <div class=\"d-flex w-100 justify-content-between\">\n                            <h5 class=\"mb-1\">{{.Name}}</h5>\n                            <small>{{if .Online}} <span class=\"badge badge-success\">ONLINE</span> {{else}} <span class=\"badge badge-danger\">OFFLINE</span> {{end}}</small>\n                        </div>\n                        <p class=\"mb-1\">{{.SmallText}}</p>\n                    </a>\n                {{ end }}\n                </div>\n\n            {{ range Services }}\n            {{ if .LimitedFailures }}\n                <h4 class=\"text-truncate\">{{.Name}} Failures</h4>\n                <div class=\"list-group mt-3 mb-4\">\n                {{ range .LimitedFailures }}\n                    <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                        <div class=\"d-flex w-100 justify-content-between\">\n                            <h5 class=\"mb-1\">{{.ParseError}}</h5>\n                            <small>{{.Ago}}</small>\n                        </div>\n                        <p class=\"mb-1\">{{.Issue}}</p>\n                    </a>\n                {{ end }}\n                </div>\n            {{ end }}\n            {{ end }}\n\n\n            </div>\n        </div>\n    </div>\n</div>\n{{end}}\n"),
216
        }
217
        filen := &embedded.EmbeddedFile{
218
                Filename:    "error_404.html",
219
                FileModTime: time.Unix(1538457906, 0),
220
                Content:     string("{{define \"title\"}}Statup Page Not Found{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-12 mt-3\">\n        <div class=\"alert alert-danger\" role=\"alert\">\n            Sorry, this page doesn't seem to exist.\n        </div>\n    </div>\n</div>\n{{end}}\n"),
221
        }
222
        fileo := &embedded.EmbeddedFile{
223
                Filename:    "favicon.ico",
224
                FileModTime: time.Unix(1530546686, 0),
225
                Content:     string("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00@\x00\x00\x00@\b\x06\x00\x00\x00\xaaiq\xde\x00\x00\v\x92IDATx\x9c\xed\x9ak\x8c]Wu\xc7\u007fk\xed3w\xc6\xf3\xcexb\x1c)\t\x89\x89\xa8\t\xe6!C\xa3\xc8T\xd8q\x1d\x9a\x84\x14\xd1\b\x10\xad\xd4\x12\xb5\xa9P\x15\x12\xd3Z\x15TBB\x15\x1f\xe8\a\xaa\xe0\x98\xb4*\x16n\xfb\xa1T\x05җ҄\x94ď@R\nI_\xaa\"\xd7\x19\x9c4$\xe0Lf\xfc\x18\xcf\xe3νg\xaf\xd5\x0f\xe7\xee9\xe7\x9a\xca\xe9=3\xa6\xa8\x9d\xbfd\xcd\xf8\xdes\xd6\xde\xeb?k\xaf\xbd\xd6\u007foX\xc7:ֱ\x8eu\xac\xe3\xff-\xe4R\x0f\xf0\x86\u007f\x19gff\xeez\x11\xb9!\x04\xdeb\xe6W\xbb\xfb\xa6\x10t\xd0\xddUU\x9af,\xaa\xca)w^t\xb7\xe7@\x9f\x0e\xc1\x9e}\xf5\xddf\x97z~\x97\x84\x80\x81\xbf\x83\x91\x91\xb0Ý_\x8e\xd1\xdf\x0fl\x16\x01\x11\x05\fw\x10\x11D\x84\x18\rUp\aU!\xcf\x1dU\x018\v<\f<\xb8\xbc\xec\x0f-\xdcb\xadK1\xd75'`\xec1\xb9-\x04\xf9\x8c\x88l7s\n\xc7\x05w/\x06\x14A\xa4pجpֽ\xf8\x19\xa3\x93e\x82\x99\xe3^<g愠/\xb9\xfb\x01\x11\xff\xc2\xccN[\\\xcb\xf9\xae\x19\x01\x93\xc7t،\x83\xaa\xfaaw\xa7\xf0\xd7W\x9c\x17QD\x9c\x18\x8bϒ\xe3\xe9YU\xc1\xcd\xe1\x02\xc2\x121\xaa\x82\b/\xba\xf3볻\xe2߯ռׄ\x80\x8dG\xc3f3\xff\x06\xb0\r\x04\x91\xc2Ʉ\x14\t@\x85\x90\xee\xa8\x00V\xc8\bA\xc8s#\x04튒\xc26\x06\xfe\x89\xd9]\xf6\xb9\xb5\x98\xfb\xaa\t\x988\"\xa3\xaa\xe1Iw\xdf\xd6\xf1\a\x91\x14\x01e\xb8\x83\xaf\xbc\xa3\xaa]\xa4T\x89\xb0hhЕg\xdd\x1cQ\xadDDa\xcf\xdd\xef>}\x93\xfd\xc1j篯\xfd\xc8kA\x0e\xba\xfb\xb6\x18\x9d\"\xe4\x93äd\x86j\xf1\xbb H\x14l\xc9\xf0%\xc7\xe6\x1d_\x04\x96\x81\b\xe0\x1d\xe7\v\x03f\x8e(\xb8[\xc7\x06\xc4\xe8)\x89\xde7y,\xbb~\xb5\xb3\xcfV\xf3\xf2\xc4\x11\xbd͝\x0f\x81w&\xa8\xb8\x17;WJrn\x0e\x8b\x82\x9dwdA\x88MC\\P\x8adg\xe6H\x00\xed\x13\x18pd\xd4\xd1\x11\xa0Q,\x85\xb4\xfe\xcb\xe8\x12\n\x82\xa4a\xe6\a\x80\x9f]\x8d\x0f\xb5\x97\xc0\xa6o\x06b\xe4\x19w\xdf^]\xef\xe5\xfa\x06o9\xfeC!N;~\x8e\xdcs\x9e\x15\x93g\x89\x9cr\xf3y\\\x16\xdc=C٨\r\xb6H\x9f\xdc\xe0\xfd\xbeY& \\\x01ac\x99\x1b\xca\xe9zW\xceP\x95\x9f\x9e\xd9\x19\x9f\xae\xebG\xed\b\xc8snHΧDU\x9d\x1c9ؔ\xd0\xfe\xbeOiS>\xdb^\xb6\xbf\\\xfeC?{1\x9bW|jT\xcfN\x9f\xbf1\x9b\xd7}\xf1<wp\xad\xa3\xaf\x832\x978\xa1\x93\x1fR\x84\x89\xc8G\x81\xda\x04Ԏ\x80\x89#\xfa\x19U\xf9T\xda\xe2ܽ+c\xe7ρMɟ\xd8R\xfc\x8d\xc5\x034{\xb5?\xb8Wo\xd7I\xfe,\xbc\x99Q\x1d\xa7\xb3#XW\x01\x15\x82`\xe6\xd3ͦ]\xb1x+\xb5\xaa\xc6\xfaI\xd0y\xa7Y\xb15%\xe7W\xfe\xfam!\xfe'_c\xd9~\xad\x8e\xf3\x00\x8b\xfb\xed!='\xb7\xda\U000f4534\xee\v\x98\x19\xaa\xa9`b\xd3\xc0\x80\xbe\xb5\xae\x1b\xb5\t\x10\x917v\x19R]\xd9\xd6X\xa4is~\xf7\xfc~_U-?\xf7\xb9\xf8\x14\xb3\xf2i;\xeb\x95$\xd8]Mv\x8a\xaaw\xd6\x1d\xa36\x01\x16}2msE\x92\xaaD\xc1\b'\x96\x0e\xf8t]\xdbU\xc8R\xf6\xf98\xe3\xd3\ue38a\xe0m\xf0&\xe4s\x8e\x9e\x17|\xd6\xf1i\xa9\x9d\xcb\xeaG\x80\xc9p\n\xfd\xea\xbeo\xe6\xb8\xf8\xb6\xb1Ǻ#\xa4.\xe6\xee[n\xb2(_\xb1\xef\v\xed\x13N<\x01\xf19\x88\xff\x01\xf9\xb3\xd0\xfaWh\xfes\xfd@\xab͜\xb7ܤ!Z\x84\xa4w\xd6e\xc1\xa7\b\x1a\x82|i\xec1n>\xb7\xc7k\xe5\x80*\xe2)9\x12_\xf1;1Nb~\x92\\\xa6<\xe7{&\x9c\xcc\xdb~\xb2\u007f@_\xa8k\xbb\xf6.0\xf6U\xfda\xdf&ٜ\x12\xa1H\x99\x10)\x93\xd6S\xaa\xfa\x91\x99\x9d\xf9T\xddq\x00\x86\xf7\x065\x8b\xb6x`5V\xfe{\xd4&`\xfc\x90>\xa9\xd7ʎ\xb4?\v\x82h\x91\x94R##\x021ZKD\xbel\xc6_\x80\x1d>\xb3\xdb/I__\x17\xf5\x93\xe0\f\xdf\xf1\x96w\x1a\x13\xb0N'\x97j\x013'FÝ\x86\x88\xdc\t\xfe\x88\xaa\xbe:y,{p\xe3\xd1p\xd7ƣ\xe1\xea5\xf4\xa36jG\xc0\xd0o\xeb\x8e\xec-<\x19\xae\xaaV\x82\x1d\xa3\x9dv\xb8\xf8\xfcG;\xbfJ+|\x1c\xf8z\x9e\xfb\xa3\xfd\xfd}O\xbc\xfa\xee֚\x8a\x1d\xff\x13\xd4'\xe0^T^\xa7\xcf\xf4\xbd\x8d\xb73HE\xe0(\xbeO\xff/\x9dMy\x02̊F'EO\xa7\xa6o\xba\xfb\xb7@\x1e\rA\x1e\nA\x8e\x9fzW{-|\xbc(V\xa5\a\f\xed\xd3[\xb2k\xe5\x11\xbdΡ\xd1MB\x8a\b\x8b\xa9\xa5M\xe5l\xec\xa8Ct%\xcc\xd4@%\xb8\xfbT\b\xf2\x90\x88<\xe8nO]*\x81tՂ\xc8\xd0'\xc2\xc1\xf0z\xbf\xab\xefZ\x85\r\x85\a\xd5\xee-\xe9}E\xd5FWEW\n%\x82j\x91?\xd2;\xd5g\x81\x1f\xa8\xcaWD\xf8\xd2\xcc\xce\xf8\ufadds\x15\xab&`|_\u007f#\xcf\xda\u007f\xc5f\xbf-\xbbJ\xd0\xcb\x04\x94ʚ/\x15\xa2\xa2\x89)\xf3Ez&\xe9~\xd5ϊ(*\x96K\xf1\xcc\xca\xefG\xf3<~z\xeef\x9eX\xed\xdca\x8d4\xc1\xa1{\xa5a\x81\xcf\xf6]\xae\xbfŤ\xa1\x1b\x05\x19\x06\xfa\xca\xeaP\xb5\x9b\x80\xaa\xe8ٵd\xec\xc2(J\xd3,e\xb3N\xde8$\x12\xf6\x9e\xbe\xa9=\xbf\x9a\xb9\xaf\xa9,\xbe\xe1c\xb2+\x1b\xd1\xdf\xf7!߮\x97\x81\x8c\x03CN6\xac+5gW\xd7\b\x95\xa6\xa6\x9a\x13\xa0\xaa('hG\x1bL\x89S\x84\xa7ݹ\xf5\xccn\x9b\xa9;\xe75?\x17\x90\xbb\xd0\xc1\xc1\xb0\x9b\x86\xdf\x1d\x06\xf5\xb68\x18\x1b:\x02:&\x84\x11\xc1\xfb\x9d\xb0\xa1\x94\xca\xd3_<EE\xe7\x1c\xa0\xd3cx\xea\xf9\xbbT \x11%\xc6H\x96\x05\xdc\xfd;ͦ\xef\\\xb8\xc5j\x95ܗ\xf4hlxo\x98p\xfc\x0e\xe9烞\xb1+\x8cJC\x86\x81\r\x8e\x8c\x00\x03\x10\x06\x05\x0f\xdd\x11\xb0R]J\x99+RM\x01t\x91\xe3\xee\xe49\xf7\x9f\xdbc{\xeb\xcc\xf1\x92\x9f\r&\f\xef\r\xc3\xc0{\xa2\xda{À\xbc\x87\x86\\)#^\b\xa1C\x82\x8e\x80n\x10d\x03\x18\xa9p\xea^\xfbi\xb9T\x97Lg\x99\xe4\xaa\xfa晝\xf9\x89^\xe7\xf5c#\xa0\x8a\xf1}}\xb4Z\xf1\x8d\x1adO\f~s6 \xbb\xe8\xf7q\x86\x05\x19tt\ftX`\xb0P\x8c\x13\x11\xee\xe9g\xf1Yyt&\xb8\xf3\xf9\xd37\xc5\xdf\xecu.\xff+\x04\\\x88ὒ\xb9\xcbvT\xf6Ȁ\xbfW\x1ar#\xa3\xae:\n:)\xc8\x18H\xf0\xea\x0e\xb0\x92 \xdd%-\x85\x93\xb3\xbb\xe2\x1bz\x1d\xfb'\x82\x80\v1t\xaflr\xe4\x03\xb2\x81\x8f\xe8\xa8\xdc\x10\xae\x84p\x15H\xe8.\xaf/(\x960\xb3\xcb\xcf\xec\xf6\x9ev\x845!`\xfcq\xc9D\xe4:U\xb6\xba3\u007f\xfa&{l-\xec\x02\f~,\xec\x961?ط\x8d-\xe1\x8ab\t\x98\x91\x0eK+J4\x80\xbfcv\x97\xfdS/\xf6{V\x846\x1e\x95a\xd5pG\x9eۛTe\xab\x9bo\x15\x95-f\xde\xe8\x1ci\x1f\x06\u058c\x80\xc5/\xc4Ã\xf7\xe8\xbb\xecE\xf9G\xb9ܯ\x96\xd0\xddHA\x99\x18C\xd0qzT\xc7{\xd6\x03\xe24ט\xf1\xa7\"|\xd2\xdd\xdf/*[E\xa4Q\xa8\u008e\x99\xdf8yL\x1b\xbdڽ\x18\x16\x0f\xd8);\xeb\xfb\xc8\xcbJP\xe8V\x88͌<\x8f=\xfb\xd3\xf3\v\xf6\xbc\x8c\xd3N\xc5K\xd9\xd5\x15g\x82\x82\b\x831rK\xafv_\v}\xed\xeco\x05ZЩ\x17\xa4\xac\a@\bAɖC\xcfjS\xcf\x04\xb4Oq\"\x9e\xabfa*\xe1X$&U\xa9U\x94\\\f\xfd\xbf\xc0\x80\xf4\x17\",\xa4\xf3\x00\xed\x12bZ\xcf\xf9\\\xafv{&`\xe9>\x9b\xb63L\xa5s\x80\x94\x8d\x81\xce>-\x98\xf9\xee\xcb\x0e\xeb\xfbz\xb5}1\xb4Z\xf1W\xcc=+\x1a'\xa5\xdd6܍\x18;\xd2\xdb\"ė\xfd\a\xbdڭ\xa5\t\xda,\x0f{[:엵z\xa7RM\xa75\a'\x8fe\xd7Ա\u007f!&\x8f\x85+U\xf9\xdd2\xf9yg\xac\"\xf4C\x10\xec\f\xd3\xf9\xbc\xf5|\x18S\x8b\x00\x9f\xe5\xab6\x93z\xfcB\xe9Iˡ\x88\x86\xe2\xcc\xceݏ\x8c?.[댑0\xfe\xb8n\x06\x1e\x01&R\xe3\x94\bOw\x8cp\xb0i?\xdc|\xa0w\xfb\xb5\b\x90\x96\u007f\xcb^⸵|\xe5\x92C\xb5\x9bK\n\x8f;\xd7\x00\u07fd\xfc\x89\xec\xe3C_g\xa0\x971&\x8e\xc0\xe4\xb1p{\b\xf2]3\xb6\xa5\xc6\xc8\xccȲ\xf2ʌ\b\xe4\xaf:>-\u007f^˗:/\x01\f}R\xef\xcc\xde\xc4\x1fg\xaf\xaf^\x86\xb2\xceQ9+ˡli\x99v\xf7/\x8b\xf0h\x9e\xf3\xf4\xb9=?\xda\xc3O\x1e\xcb\x06\xddm\x9b;\xbb\xdc\xf9EUy{\xfa\xaej\xb3\x18\xabs_\xa8\r\xadg|\xca^\xe6\xa7\x16\xee\xef]7\xacM\x80\xfe*\xd9\xf0\x96\xf0\x8c^\xefo\xcd6\n\xee\xd2!\xa0HR\xc5\x05\xc8R\xe8\xac\\n\xa2\x13!s\xc0\f\xd02#\x13\xf1q\x90\t@c,[ݴ\xac\ne\xa9T\x8aB\x10<B{\xca\xe1\xa4~p\xee\xf7\xf2\xaf\xd5\xf2\xa3.\x01v\x88<\x9f\xf5\x8f\xdaIr\x9b\x87\xe2\x9eP)kU\xf5\xbej4\xa4\x9b$\xee\x8c\xc6\xe8[\xcc|\xab\b\xd7\x01\x93\x80V5\x80t\x9f\xb0\x10JS\x84\x15\xdf\xc7\xdc\xc9_r\xe2\v\xfc\xb57\xad\x96\xf3\x00\xa1\xee\x8b\x00\xedo\xfbK\xd9\xdbd\x816?'C \xfd\xc9\xd1\xf22S٬$ŷ\xbc\x17X\xaa<\x90\xda\xdbR-\x93\x15\x87S\xd4dY\x87\xc9\x1c\xece\xb0\xef\xc9q\x9f\x93\x9f\x9f\xdf_O\r\x82U\x12\x000\xfa3\xfd\xffО\xb3a_b\a}\x10\x86\x04\x87\x15\xf5&9\x9e\bIW\\\xca\x1dC\xaa\xcd\f\x89\x88\xf4Nq\xbeXl{n\x8e/\x80\xbd\b\xf6\xbc\x1c\x97\xf3z\xf3\xfc\xfe|U\xf7\x10VM\xc0ғ9}\xef\xf0o\xb0\xa4\v\xb2(\xbbc\xcbU3\x90\x06H\xa5.\x80R!N[e\xf1\x1d$\xa7˪N\xa8\n\xa7\xaa\x02K`\xaf@|\x1e\xe2\xcb<\xec\vr\xfb\xfc\xfe\xfc\x95\xd5\xce\u007fM\xf5\x80Ꮗ\x1d>\xe0\u007f\xa4\x97\xb1MƁq'\x1b\x16\xe8\x17\b\xddjpB\xb5vH\xe7\x88f\xc5m\x10ZB>op\x0e\xec4pF\xa6m\xc1\u007f\a\xb3C\v\xf7\xaf͜\xd7\\\x10\x19\xbc\x87LC\xf6Kް\xbd:\xc8v\x19\x13\xe8wd\x03ſ\x06H\x80N\xd5\fBq\xb4\xee\xe0\x06\x9e\x83-9>_\\\x85a\x1eX\x90\x93\xb6\xc4\x03\xb1\x1d\xbf\xd8|\x80U\x9d\x03\\\x88K\xaa\b\rݫף\xbcO\xfae'ʍ\x1e|\\\xfa:$\xf4\t\x8e\xa3\x01,\a\x8f\xa0.X\xd3\xf16-\"\xff\xe6\xcb\x1c&\xf27\xcb\xcb\xf6\xed\xf8\xc5z\xd7\xe0^\v?6Il\xf0\x1eȲl\xb3\xbbl\x01\xdfdf\x138\x03\x0e\x99Eoj\x90y\x119kf/4\x17}\xca\x0f\xf1\x13u\x91b\x1d\xebX\xc7:\xd6\xf1\u007f\x11\xff\x05\x1f2t\x13ȇz\xd2\x00\x00\x00\x00IEND\xaeB`\x82"),
226
        }
227
        filep := &embedded.EmbeddedFile{
228
                Filename:    "footer.html",
229
                FileModTime: time.Unix(1538458476, 0),
230
                Content:     string("{{ define \"footer\"}}\n<div class=\"footer text-center mb-4\">\n{{ if CoreApp.Footer}}\n    {{ CoreApp.Footer }}\n{{ else }}\n    <a href=\"https://github.com/hunterlong/statup\" target=\"_blank\">Statup {{VERSION}} made with ❤️</a> | <a href=\"/dashboard\">Dashboard</a>\n{{ end }}\n</div>\n{{ end }}\n"),
231
        }
232
        fileq := &embedded.EmbeddedFile{
233
                Filename:    "form_checkin.html",
234
                FileModTime: time.Unix(1538935644, 0),
235
                Content:     string("{{define \"form_checkin\"}}\n<form action=\"/service/{{.Id}}/checkin\" method=\"POST\">\n    <div class=\"form-group row\">\n        <div class=\"col-md-3\">\n            <label for=\"checkin_interval\" class=\"col-form-label\">Checkin Name</label>\n            <input type=\"text\" name=\"name\" class=\"form-control\" id=\"checkin_name\" placeholder=\"New Checkin\">\n        </div>\n        <div class=\"col-3\">\n            <label for=\"checkin_interval\" class=\"col-form-label\">Interval</label>\n            <input type=\"number\" name=\"interval\" class=\"form-control\" id=\"checkin_interval\" placeholder=\"60\">\n        </div>\n        <div class=\"col-3\">\n            <label for=\"grace_period\" class=\"col-form-label\">Grace Period</label>\n            <input type=\"number\" name=\"grace\" class=\"form-control\" id=\"grace_period\" placeholder=\"10\">\n        </div>\n        <div class=\"col-3\">\n            <label for=\"checkin_interval\" class=\"col-form-label\"></label>\n            <button type=\"submit\" class=\"btn btn-success d-block\">Save Checkin</button>\n        </div>\n    </div>\n</form>\n{{end}}\n"),
236
        }
237
        filer := &embedded.EmbeddedFile{
238
                Filename:    "form_notifier.html",
239
                FileModTime: time.Unix(1538552384, 0),
240
                Content:     string("{{define \"form_notifier\"}}\n{{$n := .Select}}\n<form method=\"POST\" class=\"{{underscore $n.Method }}\" action=\"/settings/notifier/{{ $n.Method }}\">\n{{if $n.Title}}<h4>{{$n.Title}}</h4>{{end}}\n{{if $n.Description}}<p class=\"small text-muted\">{{$n.Description}}</p>{{end}}\n\n{{range $n.Form}}\n    <div class=\"form-group\">\n            <label class=\"text-capitalize\" for=\"{{underscore .Title}}\">{{.Title}}</label>\n        {{if eq .Type \"textarea\"}}\n            <textarea rows=\"3\" class=\"form-control\" name=\"{{underscore .DbField}}\" id=\"{{underscore .Title}}\">{{ $n.GetValue .DbField }}</textarea>\n        {{else}}\n            <input type=\"{{.Type}}\" name=\"{{underscore .DbField}}\" class=\"form-control\" value=\"{{ $n.GetValue .DbField }}\" id=\"{{underscore .Title}}\" placeholder=\"{{.Placeholder}}\" {{if .Required}}required{{end}}>\n        {{end}}\n        {{if .SmallText}}\n            <small class=\"form-text text-muted\">{{safe .SmallText}}</small>\n        {{end}}\n    </div>\n{{end}}\n\n    <div class=\"row\">\n        <div class=\"col-9 col-sm-6\">\n            <div class=\"input-group mb-2\">\n                <div class=\"input-group-prepend\">\n                    <div class=\"input-group-text\">Limit</div>\n                </div>\n                <input type=\"text\" class=\"form-control\" name=\"limits\" min=\"1\" max=\"60\" id=\"limits_per_hour_{{underscore $n.Method }}\" value=\"{{$n.Limits}}\" placeholder=\"7\">\n                <div class=\"input-group-append\">\n                    <div class=\"input-group-text\">Per Minute</div>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"col-3 col-sm-2 mt-1\">\n            <span class=\"switch\">\n                <input type=\"checkbox\" name=\"enable\" class=\"switch\" id=\"switch-{{ $n.Method }}\" {{if $n.Enabled}}checked{{end}}>\n                <label for=\"switch-{{ $n.Method }}\"></label>\n            </span>\n        </div>\n\n        <input type=\"hidden\" name=\"notifier\" value=\"{{underscore $n.Method }}\">\n\n        <div class=\"col-12 col-sm-4 mb-2 mb-sm-0 mt-2 mt-sm-0\">\n            <button type=\"submit\" class=\"btn btn-primary btn-block text-capitalize\">Save</button>\n        </div>\n\n    {{if $n.CanTest}}\n        <div class=\"col-12 col-sm-12\">\n            <button class=\"test_notifier btn btn-secondary btn-block text-capitalize col-12 float-right\">Test</button>\n        </div>\n\n        <div class=\"col-12 col-sm-12 mt-2\">\n            <div class=\"alert alert-danger d-none\" id=\"{{underscore $n.Method}}-error\" role=\"alert\">\n            {{$n.Method}} has an error!\n            </div>\n\n            <div class=\"alert alert-success d-none\" id=\"{{underscore $n.Method}}-success\" role=\"alert\">\n                The {{$n.Method}} notifier is working correctly!\n            </div>\n        </div>\n    {{end}}\n\n    </div>\n\n{{if $n.Author}}\n    <span class=\"d-block small text-center mt-3 mb-5\">\n                            {{$n.Title}} Notifier created by <a href=\"{{$n.AuthorUrl}}\" target=\"_blank\">{{$n.Author}}</a>\n                        </span>\n{{ end }}\n</form>\n{{end}}\n"),
241
        }
242
        files := &embedded.EmbeddedFile{
243
                Filename:    "form_service.html",
244
                FileModTime: time.Unix(1538934599, 0),
245
                Content:     string("{{define \"form_service\"}}\n<form action=\"{{if ne .Id 0}}/service/{{.Id}}{{else}}/services{{end}}\" method=\"POST\">\n    <div class=\"form-group row\">\n        <label for=\"service_name\" class=\"col-sm-4 col-form-label\">Service Name</label>\n        <div class=\"col-sm-8\">\n            <input type=\"text\" name=\"name\" class=\"form-control\" id=\"service_name\" value=\"{{.Name}}\" placeholder=\"Name\" required spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_type\" class=\"col-sm-4 col-form-label\">Service Check Type</label>\n        <div class=\"col-sm-8\">\n            <select name=\"check_type\" class=\"form-control\" id=\"service_type\" value=\"{{.Type}}\">\n                <option value=\"http\" {{if eq .Type \"http\"}}selected{{end}}>HTTP Service</option>\n                <option value=\"tcp\" {{if eq .Type \"tcp\"}}selected{{end}}>TCP Service</option>\n                <option value=\"udp\" {{if eq .Type \"udp\"}}selected{{end}}>UDP Service</option>\n            </select>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_url\" class=\"col-sm-4 col-form-label\">Application Endpoint (URL)</label>\n        <div class=\"col-sm-8\">\n            <input type=\"text\" name=\"domain\" class=\"form-control\" id=\"service_url\" value=\"{{.Domain}}\" placeholder=\"https://google.com\" required autocapitalize=\"false\" spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"tcp\"}} d-none{{end}}\">\n        <label for=\"service_check_type\" class=\"col-sm-4 col-form-label\">Service Check Type</label>\n        <div class=\"col-sm-8\">\n            <select name=\"method\" class=\"form-control\" id=\"service_check_type\" value=\"{{.Method}}\">\n                <option value=\"GET\" {{if eq .Method \"GET\"}}selected{{end}}>GET</option>\n                <option value=\"POST\" {{if eq .Method \"POST\"}}selected{{end}}>POST</option>\n                <option value=\"DELETE\" {{if eq .Method \"DELETE\"}}selected{{end}}>DELETE</option>\n                <option value=\"PATCH\" {{if eq .Method \"PATCH\"}}selected{{end}}>PATCH</option>\n                <option value=\"PUT\" {{if eq .Method \"PUT\"}}selected{{end}}>PUT</option>\n            </select>\n        </div>\n    </div>\n    <div class=\"form-group row{{if ne .Method \"POST\"}} d-none{{end}}\">\n        <label for=\"post_data\" class=\"col-sm-4 col-form-label\">Optional Post Data (JSON)</label>\n        <div class=\"col-sm-8\">\n            <textarea name=\"post_data\" class=\"form-control\" id=\"post_data\" rows=\"3\" autocapitalize=\"false\" spellcheck=\"false\">{{.PostData}}</textarea>\n            <small id=\"emailHelp\" class=\"form-text text-muted\">You can insert <a target=\"_blank\" href=\"https://regex101.com/r/I5bbj9/1\">Regex</a> to validate the response</small>\n        </div>\n    </div>\n    <div class=\"form-group row{{if ne .Type \"http\"}} d-none{{end}}\">\n        <label for=\"service_response\" class=\"col-sm-4 col-form-label\">Expected Response (Regex)</label>\n        <div class=\"col-sm-8\">\n            <textarea name=\"expected\" class=\"form-control\" id=\"service_response\" rows=\"3\" autocapitalize=\"false\" spellcheck=\"false\">{{.Expected}}</textarea>\n        </div>\n    </div>\n    <div class=\"form-group row{{if ne .Type \"http\"}} d-none{{end}}\">\n        <label for=\"service_response_code\" class=\"col-sm-4 col-form-label\">Expected Status Code</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"expected_status\" class=\"form-control\" value=\"{{if ne .ExpectedStatus 0}}{{.ExpectedStatus}}{{end}}\" placeholder=\"200\" id=\"service_response_code\">\n        </div>\n    </div>\n    <div class=\"form-group row{{if eq .Type \"\"}} d-none{{else if eq .Type \"http\"}} d-none{{end}}\">\n        <label id=\"service_type_label\" for=\"service_port\" class=\"col-sm-4 col-form-label\">TCP Port</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"port\" class=\"form-control\" value=\"{{if ne .Port 0}}{{.Port}}{{end}}\" id=\"service_port\" placeholder=\"8080\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_interval\" class=\"col-sm-4 col-form-label\">Check Interval (Seconds)</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"interval\" class=\"form-control\" value=\"{{if ne .Interval 0}}{{.Interval}}{{end}}\" min=\"1\" id=\"service_interval\" required>\n            <small id=\"emailHelp\" class=\"form-text text-muted\">10,000+ will be checked in Microseconds (1 millisecond = 1000 microseconds).</small>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"service_timeout\" class=\"col-sm-4 col-form-label\">Timeout in Seconds</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"timeout\" class=\"form-control\" value=\"{{if ne .Timeout 0}}{{.Timeout}}{{end}}\" placeholder=\"15\" id=\"service_timeout\" min=\"1\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"order\" class=\"col-sm-4 col-form-label\">List Order</label>\n        <div class=\"col-sm-8\">\n            <input type=\"number\" name=\"order\" class=\"form-control\" min=\"0\" value=\"{{.Order}}\" id=\"order\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <div class=\"{{if ne .Id 0}}col-6{{else}}col-12{{end}}\">\n            <button type=\"submit\" class=\"btn btn-success btn-block\">{{if ne .Id 0}}Update Service{{else}}Create Service{{end}}</button>\n        </div>\n        {{if ne .Id 0}}\n        <div class=\"col-6\">\n            <a href=\"/service/{{ .Id }}/delete_failures\" class=\"btn btn-danger btn-block confirm-btn\">Delete All Failures</a>\n        </div>\n        {{end}}\n    </div>\n</form>\n{{end}}\n"),
246
        }
247
        filet := &embedded.EmbeddedFile{
248
                Filename:    "form_user.html",
249
                FileModTime: time.Unix(1538543370, 0),
250
                Content:     string("{{define \"form_user\"}}\n<form action=\"{{if ne .Id 0}}/user/{{.Id}}{{else}}/users{{end}}\" method=\"POST\">\n    <div class=\"form-group row\">\n        <label for=\"username\" class=\"col-sm-4 col-form-label\">Username</label>\n        <div class=\"col-6 col-md-4\">\n            <input type=\"text\" name=\"username\" class=\"form-control\" value=\"{{.Username}}\" id=\"username\" placeholder=\"Username\" required>\n        </div>\n        <div class=\"col-6 col-md-4\">\n          <span class=\"switch\">\n            <input type=\"checkbox\" name=\"admin\" class=\"switch\" id=\"switch-normal\"{{if .Admin}} checked{{end}}>\n            <label for=\"switch-normal\">Administrator</label>\n          </span>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"email\" class=\"col-sm-4 col-form-label\">Email Address</label>\n        <div class=\"col-sm-8\">\n            <input type=\"email\" name=\"email\" class=\"form-control\" id=\"email\" value=\"{{.Email}}\" placeholder=\"user@domain.com\" required autocapitalize=\"false\" spellcheck=\"false\">\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"password\" class=\"col-sm-4 col-form-label\">Password</label>\n        <div class=\"col-sm-8\">\n            <input type=\"password\" name=\"password\" class=\"form-control\" id=\"password\" value=\"##########\" placeholder=\"Password\" required>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <label for=\"password_confirm\" class=\"col-sm-4 col-form-label\">Confirm Password</label>\n        <div class=\"col-sm-8\">\n            <input type=\"password\" name=\"password_confirm\" class=\"form-control\" id=\"password_confirm\" value=\"##########\" placeholder=\"Confirm Password\" required>\n        </div>\n    </div>\n    <div class=\"form-group row\">\n        <div class=\"col-sm-12\">\n            <button type=\"submit\" class=\"btn btn-primary btn-block\">{{if ne .Id 0}}Update User{{else}}Create User{{end}}</button>\n        </div>\n    </div>\n</form>\n{{end}}\n"),
251
        }
252
        fileu := &embedded.EmbeddedFile{
253
                Filename:    "head.html",
254
                FileModTime: time.Unix(1538459085, 0),
255
                Content:     string("{{ define \"head\"}}\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0\">\n{{if USE_CDN}}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://assets.statup.io/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css\" integrity=\"sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://assets.statup.io/base.css\">\n{{ else }}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"/css/base.css\">\n{{end}}\n{{block \"extra_css\" .}} {{end}}\n<title>{{block \"title\" .}} {{end}}</title>\n</head>\n{{end}}\n"),
256
        }
257
        filev := &embedded.EmbeddedFile{
258
                Filename:    "help.html",
259
                FileModTime: time.Unix(1538459433, 0),
260
                Content:     string("{{define \"title\"}}Statup | Help{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n    <div class=\"col-12\">\n    {{ safe . }}\n    </div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<style>\n    pre {\n        background-color: white;\n        padding: 10px 15px;\n        border: 1px solid #a2a2a233;\n        border-radius: 7px;\n    }\n    code {\n        color: #d87e1a;\n    }\n</style>\n{{end}}\n"),
261
        }
262
        filew := &embedded.EmbeddedFile{
263
                Filename:    "help.md",
264
                FileModTime: time.Unix(1536974218, 0),
265
                Content:     string("# Statup Help\nStatup is an easy to use Status Page monitor for your websites and applications. Statup is developed in Go Language and you are able to create custom plugins with it!\n\n<p>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/github/stars/hunterlong/statup.svg?style=social&label=Stars\"></a>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/docker/build/hunterlong/statup.svg\"></a>\n    <a href=\"https://github.com/hunterlong/statup\"><img src=\"https://img.shields.io/github/release/hunterlong/statup.svg\"></a>\n</p>\n\n# Services\nFor each website and application you want to add a new Service. Each Service will require a URL endpoint to test your applications status.\nYou can also add expected HTTP responses (regex allow), expected HTTP response codes, and other fields to make sure your service is online or offline.\n\n# Statup Settings\nYou can change multiple settings in your Statup instance.\n\n# Users\nUsers can access the Statup Dashboard to add, remove, and view services.\n\n# Notifications\n\n\n# Plugins\nCreating a plugin for Statup is not that difficult, if you know a little bit of Go Language you can create any type of application to be embedded into the Status framework.\nCheckout the example plugin that includes all the interfaces, information, and custom HTTP routing at <a href=\"https://github.com/hunterlong/statup_plugin\">https://github.com/hunterlong/statup_plugin</a>.\nAnytime there is an action on your status page, all of your plugins will be notified of the change with the values that were changed or created.\n<p></p>\nUsing the statup/plugin Golang package you can quickly implement the event listeners. Statup uses <a href=\"https://github.com/upper/db\">upper.io/db.v3</a> for the database connection.\nYou can use the database inside of your plugin to create, update, and destroy tables/data. <b>Please only use respectable plugins!</b>\n\n# Custom Stlying\nOn Statup Status Page server can you create your own custom stylesheet to be rendered on the index view of your status page. Go to <a href=\"/settings\">Settings</a> and click on Custom Styling.\n\n# API Endpoints\nStatup includes a RESTFUL API so you can view, update, and edit your services with easy to use routes. You can currently view, update and delete services, view, create, update users, and get detailed information about the Statup instance. To make life easy, try out a Postman or Swagger JSON file and use it on your Statup Server.\n\n<p align=\"center\">\n<a href=\"https://github.com/hunterlong/statup/blob/master/dev/postman.json\">Postman JSON Export</a> | <a href=\"https://github.com/hunterlong/statup/blob/master/dev/swagger.json\">Swagger Export</a>\n</p>\n\n## Authentication\nAuthentication uses the Statup API Secret to accept remote requests. You can find the API Secret in the Settings page of your Statup server. To send requests to your Statup API, include a Authorization Header when you send the request. The API will accept any one of the headers below.\n\n- HTTP Header: `Authorization: API SECRET HERE`\n- HTTP Header: `Authorization: Bearer API SECRET HERE`\n\n## Main Route `/api`\nThe main API route will show you all services and failures along with them.\n\n## Services\nThe services API endpoint will show you detailed information about services and will allow you to edit/delete services with POST/DELETE http methods.\n\n### Viewing All Services\n- Endpoint: `/api/services`\n- Method: `GET`\n- Response: Array of [Services](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Viewing Service\n- Endpoint: `/api/services/{id}`\n- Method: `GET`\n- Response: [Service](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Updating Service\n- Endpoint: `/api/services/{id}`\n- Method: `POST`\n- Response: [Service](https://github.com/hunterlong/statup/wiki/API#service-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"name\": \"Updated Service\",\n    \"domain\": \"https://google.com\",\n    \"expected\": \"\",\n    \"expected_status\": 200,\n    \"check_interval\": 15,\n    \"type\": \"http\",\n    \"method\": \"GET\",\n    \"post_data\": \"\",\n    \"port\": 0,\n    \"timeout\": 10,\n    \"order_id\": 0\n}\n```\n\n### Deleting Service\n- Endpoint: `/api/services/{id}`\n- Method: `DELETE`\n- Response: [Object Response](https://github.com/hunterlong/statup/wiki/API#object-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nResponse:\n``` json\n{\n    \"status\": \"success\",\n    \"id\": 4,\n    \"type\": \"service\",\n    \"method\": \"delete\"\n}\n```\n\n## Users\nThe users API endpoint will show you users that are registered inside your Statup instance.\n\n### View All Users\n- Endpoint: `/api/users`\n- Method: `GET`\n- Response: Array of [Users](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Viewing User\n- Endpoint: `/api/users/{id}`\n- Method: `GET`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\n### Creating New User\n- Endpoint: `/api/users`\n- Method: `POST`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"username\": \"newadmin\",\n    \"email\": \"info@email.com\",\n    \"password\": \"password123\",\n    \"admin\": true\n}\n```\n\n### Updating User\n- Endpoint: `/api/users/{id}`\n- Method: `POST`\n- Response: [User](https://github.com/hunterlong/statup/wiki/API#user-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nPOST Data:\n``` json\n{\n    \"username\": \"updatedadmin\",\n    \"email\": \"info@email.com\",\n    \"password\": \"password123\",\n    \"admin\": true\n}\n```\n\n### Deleting User\n- Endpoint: `/api/services/{id}`\n- Method: `DELETE`\n- Response: [Object Response](https://github.com/hunterlong/statup/wiki/API#object-response)\n- Response Type: `application/json`\n- Request Type: `application/json`\n\nResponse:\n``` json\n{\n    \"status\": \"success\",\n    \"id\": 3,\n    \"type\": \"user\",\n    \"method\": \"delete\"\n}\n```\n\n# Service Response\n``` json\n{\n    \"id\": 8,\n    \"name\": \"Test Service 0\",\n    \"domain\": \"https://status.coinapp.io\",\n    \"expected\": \"\",\n    \"expected_status\": 200,\n    \"check_interval\": 1,\n    \"type\": \"http\",\n    \"method\": \"GET\",\n    \"post_data\": \"\",\n    \"port\": 0,\n    \"timeout\": 30,\n    \"order_id\": 0,\n    \"created_at\": \"2018-09-12T09:07:03.045832088-07:00\",\n    \"updated_at\": \"2018-09-12T09:07:03.046114305-07:00\",\n    \"online\": false,\n    \"latency\": 0.031411064,\n    \"24_hours_online\": 0,\n    \"avg_response\": \"\",\n    \"status_code\": 502,\n    \"last_online\": \"0001-01-01T00:00:00Z\",\n    \"dns_lookup_time\": 0.001727175,\n    \"failures\": [\n        {\n            \"id\": 5187,\n            \"issue\": \"HTTP Status Code 502 did not match 200\",\n            \"created_at\": \"2018-09-12T10:41:46.292277471-07:00\"\n        },\n        {\n            \"id\": 5188,\n            \"issue\": \"HTTP Status Code 502 did not match 200\",\n            \"created_at\": \"2018-09-12T10:41:47.337659862-07:00\"\n        }\n    ]\n}\n```\n\n# User Response\n``` json\n{\n    \"id\": 1,\n    \"username\": \"admin\",\n    \"api_key\": \"02f324450a631980121e8fd6ea7dfe4a7c685a2f\",\n    \"admin\": true,\n    \"created_at\": \"2018-09-12T09:06:53.906398511-07:00\",\n    \"updated_at\": \"2018-09-12T09:06:54.972440207-07:00\"\n}\n```\n\n# Object Response\n``` json\n{\n    \"type\": \"service\",\n    \"id\": 19,\n    \"method\": \"delete\",\n    \"status\": \"success\"\n}\n```\n\n# Main API Response\n``` json\n{\n    \"name\": \"Awesome Status\",\n    \"description\": \"An awesome status page by Statup\",\n    \"footer\": \"This is my custom footer\",\n    \"domain\": \"https://demo.statup.io\",\n    \"version\": \"v0.56\",\n    \"migration_id\": 1536768413,\n    \"created_at\": \"2018-09-12T09:06:53.905374829-07:00\",\n    \"updated_at\": \"2018-09-12T09:07:01.654201225-07:00\",\n    \"database\": \"sqlite\",\n    \"started_on\": \"2018-09-12T10:43:07.760729349-07:00\",\n    \"services\": [\n        {\n            \"id\": 1,\n            \"name\": \"Google\",\n            \"domain\": \"https://google.com\",\n            \"expected\": \"\",\n            \"expected_status\": 200,\n            \"check_interval\": 10,\n            \"type\": \"http\",\n            \"method\": \"GET\",\n            \"post_data\": \"\",\n            \"port\": 0,\n            \"timeout\": 10,\n            \"order_id\": 0,\n            \"created_at\": \"2018-09-12T09:06:54.97549122-07:00\",\n            \"updated_at\": \"2018-09-12T09:06:54.975624103-07:00\",\n            \"online\": true,\n            \"latency\": 0.09080986,\n            \"24_hours_online\": 0,\n            \"avg_response\": \"\",\n            \"status_code\": 200,\n            \"last_online\": \"2018-09-12T10:44:07.931990439-07:00\",\n            \"dns_lookup_time\": 0.005543935\n        }\n    ]\n}\n```\n\n# Prometheus Exporter\nStatup includes a prometheus exporter so you can have even more monitoring power with your services. The prometheus exporter can be seen on `/metrics`, simply create another exporter in your prometheus config. Use your Statup API Secret for the Authorization Bearer header, the `/metrics` URL is dedicated for Prometheus and requires the correct API Secret has `Authorization` header.\n\n# Grafana Dashboard\nStatup has a [Grafana Dashboard](https://grafana.com/dashboards/6950) that you can quickly implement if you've added your Statup service to Prometheus. Import Dashboard ID: `6950` into your Grafana dashboard and watch the metrics come in!\n\n<p align=\"center\"><img width=\"80%\" src=\"https://img.cjx.io/statupgrafana.png\"></p>\n\n## Basic Prometheus Exporter\nIf you have Statup and the Prometheus server in the same Docker network, you can use the yaml config below.\n``` yaml\nscrape_configs:\n  - job_name: 'statup'\n    scrape_interval: 30s\n    bearer_token: 'SECRET API KEY HERE'\n    static_configs:\n      - targets: ['statup:8080']\n```\n\n## Remote URL Prometheus Exporter\nThis exporter yaml below has `scheme: https`, which you can remove if you arn't using HTTPS.\n``` yaml\nscrape_configs:\n  - job_name: 'statup'\n    scheme: https\n    scrape_interval: 30s\n    bearer_token: 'SECRET API KEY HERE'\n    static_configs:\n      - targets: ['status.mydomain.com']\n```\n\n### `/metrics` Output\n```\nstatup_total_failures 206\nstatup_total_services 4\nstatup_service_failures{id=\"1\" name=\"Google\"} 0\nstatup_service_latency{id=\"1\" name=\"Google\"} 12\nstatup_service_online{id=\"1\" name=\"Google\"} 1\nstatup_service_status_code{id=\"1\" name=\"Google\"} 200\nstatup_service_response_length{id=\"1\" name=\"Google\"} 10777\nstatup_service_failures{id=\"2\" name=\"Statup.io\"} 0\nstatup_service_latency{id=\"2\" name=\"Statup.io\"} 3\nstatup_service_online{id=\"2\" name=\"Statup.io\"} 1\nstatup_service_status_code{id=\"2\" name=\"Statup.io\"} 200\nstatup_service_response_length{id=\"2\" name=\"Statup.io\"} 2\n```\n\n# Static HTML Exporter\nYou might have a server that won't allow you to run command that run longer for 60 seconds, or maybe you just want to export your status page to a static HTML file. Using the Statup exporter you can easily do this with 1 command.\n\n```\nstatup export\n```\n###### 'index.html' is created in current directory with static CDN url's.\n\n## Push to Github\nOnce you have the `index.html` file, you could technically send it to an FTP server, Email it, Pastebin it, or even push to your Github repo for Status updates directly from repo.\n\n```bash\ngit add index.html\ngit commit -m \"Updated Status Page\"\ngit push -u origin/master\n```\n\n# Config with .env File\nIt may be useful to load your environment using a `.env` file in the root directory of your Statup server. The .env file will be automatically loaded on startup and will overwrite all values you have in config.yml.\n\nIf you have the `DB_CONN` environment variable set Statup will bypass all values in config.yml and will require you to have the other DB_* variables in place. You can pass in these environment variables without requiring a .env file.\n\n## `.env` File\n```bash\nDB_CONN=postgres\nDB_HOST=0.0.0.0\nDB_PORT=5432\nDB_USER=root\nDB_PASS=password123\nDB_DATABASE=root\n\nNAME=Demo\nDESCRIPTION=This is an awesome page\nDOMAIN=https://domain.com\nADMIN_USER=admin\nADMIN_PASS=admin\nADMIN_EMAIL=info@admin.com\nUSE_CDN=true\n\nIS_DOCKER=false\nIS_AWS=false\nSASS=/usr/local/bin/sass\nCMD_FILE=/bin/bash\n```\nThis .env file will include additional variables in the future, subscribe to this repo to keep up-to-date with changes and updates.\n\n# Makefile\nHere's a simple list of Makefile commands you can run using `make`. The [Makefile](https://github.com/hunterlong/statup/blob/master/Makefile) may change often, so i'll try to keep this Wiki up-to-date.\n\n- Ubuntu `apt-get install build-essential`\n- MacOSX `sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer`\n- Windows [Install Guide for GNU make utility](http://gnuwin32.sourceforge.net/packages/make.htm)\n- CentOS/RedHat `yum groupinstall \"Development Tools\"`\n\n### Commands\n``` bash\nmake build                         # build the binary\nmake install\nmake run\nmake test\nmake coverage\nmake docs\n# Building Statup\nmake build-all\nmake build-alpine\nmake docker\nmake docker-run\nmake docker-dev\nmake docker-run-dev\nmake databases\nmake dep\nmake dev-deps\nmake clean\nmake compress\nmake cypress-install\nmake cypress-test\n```\n\n## Testing\n* If you want to test your updates with the current golang testing units, you can follow the guide below to run a full test process. Each test for Statup will run in MySQL, Postgres, and SQlite to make sure all database types work correctly.\n\n## Create Docker Databases\nThe easiest way to run the tests on all 3 databases is by starting temporary databases servers with Docker. Docker is available for Linux, Mac and Windows. You can download/install it by going to the [Docker Installation](https://docs.docker.com/install/) site.\n\n``` bash\ndocker run -it -d \\\n   -p 3306:3306 \\\n   -env MYSQL_ROOT_PASSWORD=password123 \\\n   -env MYSQL_DATABASE=root mysql\n```\n\n``` bash\ndocker run -it -d \\\n   -p 5432:5432 \\\n   -env POSTGRES_PASSWORD=password123 \\\n   -env POSTGRES_USER=root \\\n   -env POSTGRES_DB=root postgres\n```\n\nOnce you have MySQL and Postgres running, you can begin the testing. SQLite database will automatically create a `statup.db` file and will delete after testing.\n\n## Run Tests\nInsert the database environment variables to auto connect the the databases and run the normal test command: `go test -v`. You'll see a verbose output of each test. If all tests pass, make a push request! 💃\n``` bash\nDB_DATABASE=root \\\n   DB_USER=root \\\n   DB_PASS=password123 \\\n   DB_HOST=localhost \\\n   go test -v\n```\n"),
266
        }
267
        filex := &embedded.EmbeddedFile{
268
                Filename:    "index.html",
269
                FileModTime: time.Unix(1538522506, 0),
270
                Content:     string("{{define \"title\"}}{{CoreApp.Name}} Status{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-2 sm-container\">\n<h1 class=\"col-12 text-center mb-4 mt-sm-3 header-title\">{{.Name}}</h1>\n\n{{ if .Description }}\n<h5 class=\"col-12 text-center mb-5 header-desc\">{{ .Description }}</h5>\n{{ end }}\n\n<div class=\"col-12 full-col-12 mb-5\">\n    <div class=\"list-group online_list\">\n    {{ range Services }}\n        <a href=\"#\" class=\"service_li list-group-item list-group-item-action {{if not .Online}}bg-danger text-white{{ end }}\" data-id=\"{{.Id}}\">\n        {{ .Name }}\n        {{if .Online}}\n            <span class=\"badge bg-success float-right pulse-glow\">ONLINE</span>\n        {{ else }}\n            <span class=\"badge bg-white text-black-50 float-right pulse\">OFFLINE</span>\n        {{end}}\n        </a>\n    {{ end }}\n    </div>\n</div>\n\n<div class=\"col-12 full-col-12\">\n{{ if not Services }}\n    <div class=\"alert alert-danger\" role=\"alert\">\n        <h4 class=\"alert-heading\">No Services to Monitor!</h4>\n        <p>Your Statup Status Page is working correctly, but you don't have any services to monitor. Go to the <b>Dashboard</b> and add a website to begin really using your status page!</p>\n        <hr>\n        <p class=\"mb-0\">If this is a bug, please make an issue in the Statup Github Repo. <a href=\"https://github.com/hunterlong/statup\" class=\"btn btn-sm btn-outline-danger float-right\">Statup Github Repo</a></p>\n    </div>\n{{end}}\n{{ range Services }}\n    <div class=\"mt-4\" id=\"service_id_{{.Id}}\">\n        <div class=\"card\">\n            <div class=\"card-body\">\n                <div class=\"col-12\">\n                    <h4 class=\"mt-3\"><a href=\"/service/{{.Id}}\"{{if not .Online}} class=\"text-danger\"{{end}}>{{ .Name }}</a>\n                    {{if .Online}}\n                        <span class=\"badge bg-success float-right\">ONLINE</span>\n                    {{ else }}\n                        <span class=\"badge bg-danger float-right pulse\">OFFLINE</span>\n                    {{end}}</h4>\n\n                    <div class=\"row stats_area mt-5 mb-5\">\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.Online24}}%</span>\n                            Online last 24 Hours\n                        </div>\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.AvgTime}}ms</span>\n                            Average Response\n                        </div>\n                        <div class=\"col-4\">\n                            <span class=\"lg_number\">{{.AvgUptime24}}%</span>\n                            Uptime last 24 Hours\n                        </div>\n                    </div>\n\n                </div>\n            </div>\n        {{ if .AvgUptime24 }}\n            <div class=\"chart-container\">\n                <canvas id=\"service_{{ .Id }}\"></canvas>\n            </div>\n        {{ end }}\n            <div class=\"row lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}\">\n                <div class=\"col-10 text-truncate\">\n                    <span class=\"d-none d-md-inline\">{{.SmallText}}</span>\n                </div>\n                <div class=\"col-sm-12 col-md-2\">\n                    <a href=\"/service/{{ .Id }}\" class=\"btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right dyn-dark btn-block\">View Service</a>\n                </div>\n            </div>\n        </div>\n    </div>\n{{ end }}\n</div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"/charts.js\"></script>\n{{end}}\n"),
271
        }
272
        filey := &embedded.EmbeddedFile{
273
                Filename:    "login.html",
274
                FileModTime: time.Unix(1538454764, 0),
275
                Content:     string("{{define \"title\"}}Statup Login{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-10 offset-1 col-md-8 offset-md-2 mt-md-2\">\n        <div class=\"col-12 col-md-8 offset-md-2 mb-4\">\n            <img class=\"col-12 mt-5 mt-md-0\" src=\"/statup.png\">\n        </div>\n    {{ if .Error }}\n        <div class=\"alert alert-danger\" role=\"alert\">\n            Incorrect login information submitted, try again.\n        </div>\n    {{ end }}\n        <form action=\"/dashboard\" method=\"POST\">\n            <div class=\"form-group row\">\n                <label for=\"username\" class=\"col-sm-2 col-form-label\">Username</label>\n                <div class=\"col-sm-10\">\n                    <input type=\"text\" name=\"username\" class=\"form-control\" id=\"username\" placeholder=\"Username\" autocapitalize=\"false\" spellcheck=\"false\">\n                </div>\n            </div>\n            <div class=\"form-group row\">\n                <label for=\"password\" class=\"col-sm-2 col-form-label\">Password</label>\n                <div class=\"col-sm-10\">\n                    <input type=\"password\" name=\"password\" class=\"form-control\" id=\"password\" placeholder=\"Password\">\n                </div>\n            </div>\n            <div class=\"form-group row\">\n                <div class=\"col-sm-12\">\n                    <button type=\"submit\" class=\"btn btn-primary btn-block\">Sign in</button>\n                </div>\n            </div>\n        </form>\n    </div>\n</div>\n{{end}}\n"),
276
        }
277
        filez := &embedded.EmbeddedFile{
278
                Filename:    "logs.html",
279
                FileModTime: time.Unix(1538460210, 0),
280
                Content:     string("{{define \"title\"}}Statup | Logs{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n<div class=\"col-12\">\n    <textarea id=\"live_logs\" class=\"form-control\" rows=\"40\" readonly>{{range .}}{{.}}{{end}}</textarea>\n</div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<style>\n    @media (max-width: 767px) {\n        #live_logs {\n            font-size: 6pt;\n        }\n    }\n</style>\n{{end}}\n"),
281
        }
282
        file10 := &embedded.EmbeddedFile{
283
                Filename:    "nav.html",
284
                FileModTime: time.Unix(1534817721, 0),
285
                Content:     string("{{define \"nav\"}}\n<nav class=\"navbar navbar-expand-lg navbar-light bg-light\">\n    <a class=\"navbar-brand\" href=\"/\">Statup</a>\n    <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarText\" aria-controls=\"navbarText\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n        <span class=\"navbar-toggler-icon\"></span>\n    </button>\n\n    <div class=\"collapse navbar-collapse\" id=\"navbarText\">\n        <ul class=\"navbar-nav mr-auto\">\n            <li class=\"nav-item{{ if eq URL \"/dashboard\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/dashboard\">Dashboard</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/services\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/services\">Services</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/users\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/users\">Users</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/settings\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/settings\">Settings</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/logs\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/logs\">Logs</a>\n            </li>\n            <li class=\"nav-item{{ if eq URL \"/help\" }} active{{ end }}\">\n                <a class=\"nav-link\" href=\"/help\">Help</a>\n            </li>\n        </ul>\n        <span class=\"navbar-text\">\n      <a class=\"nav-link\" href=\"/logout\">Logout</a>\n    </span>\n    </div>\n</nav>\n{{end}}"),
286
        }
287
        file11 := &embedded.EmbeddedFile{
288
                Filename:    "robots.txt",
289
                FileModTime: time.Unix(1530546686, 0),
290
                Content:     string("User-agent: *\nDisallow: /login\nDisallow: /dashboard"),
291
        }
292
        file12 := &embedded.EmbeddedFile{
293
                Filename:    "scripts.html",
294
                FileModTime: time.Unix(1538453657, 0),
295
                Content:     string("{{define \"scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js\" integrity=\"sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js\"></script>\n<script src=\"https://assets.statup.io/main.js\"></script>\n{{ else }}\n<script src=\"/js/jquery-3.3.1.min.js\"></script>\n<script src=\"/js/bootstrap.min.js\"></script>\n<script src=\"/js/Chart.bundle.min.js\"></script>\n<script src=\"/js/main.js\"></script>\n{{end}}\n{{block \"extra_scripts\" .}} {{end}}\n{{end}}\n"),
296
        }
297
        file13 := &embedded.EmbeddedFile{
298
                Filename:    "service.html",
299
                FileModTime: time.Unix(1538970873, 0),
300
                Content:     string("{{define \"title\"}}{{.Service.Name}} Status{{end}}\n{{ define \"content\" }}\n{{$s := .Service}}\n\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n\n{{if Auth}}\n    {{template \"nav\"}}\n{{end}}\n\n    <div class=\"col-12 mb-4\">\n\n    {{if $s.Online }}\n        <span class=\"mt-3 mb-3 text-white d-md-none btn bg-success d-block d-md-none\">ONLINE</span>\n    {{ else }}\n        <span class=\"mt-3 mb-3 text-white d-md-none btn bg-danger d-block d-md-none\">OFFLINE</span>\n    {{end}}\n\n        <h4 class=\"mt-2\">{{ $s.Name }}\n        {{if $s.Online }}\n            <span class=\"badge bg-success float-right d-none d-md-block\">ONLINE</span>\n        {{ else }}\n            <span class=\"badge bg-danger float-right d-none d-md-block\">OFFLINE</span>\n        {{end}}</h4>\n\n        <div class=\"row stats_area mt-5 mb-5\">\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.Online24}}%</span>\n                Online last 24 Hours\n            </div>\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.AvgTime}}ms</span>\n                Average Response\n            </div>\n\n            <div class=\"col-4\">\n                <span class=\"lg_number\">{{$s.TotalUptime}}%</span>\n                Total Uptime\n            </div>\n        </div>\n\n        <div class=\"service-chart-container\">\n            <canvas id=\"service\"></canvas>\n        </div>\n\n        <form id=\"service_date_form\" class=\"col-12 mt-2 mb-3\">\n            <span id=\"start_date\" class=\"text-muted small float-left pointer\">{{FromUnix .Start}}</span>\n            <span id=\"end_date\" class=\"text-muted small float-right pointer\" style=\"position: absolute;right: 0;\">{{FromUnix .End}}</span>\n            <input type=\"hidden\" name=\"start\" class=\"form-control\" id=\"service_start\" spellcheck=\"false\">\n            <input type=\"hidden\" name=\"end\" class=\"form-control\" id=\"service_end\" spellcheck=\"false\">\n            <button type=\"submit\" class=\"btn btn-light btn-block btn-sm mt-2\">Set Timeframe</button>\n            <div id=\"start_container\"></div>\n            <div id=\"end_container\"></div>\n        </form>\n\n    {{if not $s.Online}}\n        <div class=\"col-12 small text-center mt-3 text-muted\">{{$s.DowntimeText}}</div>\n    {{end}}\n\n    {{ if $s.LimitedFailures }}\n        <div class=\"list-group mt-3 mb-4\">\n        {{ range $s.LimitedFailures }}\n            <a href=\"#\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n                <div class=\"d-flex w-100 justify-content-between\">\n                    <h5 class=\"mb-1\">{{.ParseError}}</h5>\n                    <small>{{.Ago}}</small>\n                </div>\n                <p class=\"mb-1\">{{.Issue}}</p>\n            </a>\n        {{ end }}\n        </div>\n    {{ end }}\n\n    </div>\n\n{{if Auth}}\n\n    <div class=\"col-12 mt-4{{if ne $s.Type \"http\"}} d-none{{end}}\">\n        <h3>Last Response</h3>\n        <textarea rows=\"8\" class=\"form-control\" readonly>{{ $s.LastResponse }}</textarea>\n        <div class=\"form-group row mt-2\">\n            <label for=\"last_status_code\" class=\"col-sm-3 col-form-label\">HTTP Status Code</label>\n            <div class=\"col-sm-2\">\n                <input type=\"text\" id=\"last_status_code\" class=\"form-control\" value=\"{{ $s.LastStatusCode }}\" readonly>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"col-12 mt-4\">\n        <h3>Edit Service</h3>\n        {{template \"form_service\" $s}}\n    </div>\n\n    <div class=\"col-12 mt-4\">\n        <h3>Service Checkin</h3>\n        {{if $s.LimitedCheckins}}\n        <table class=\"table\">\n            <thead>\n                <tr>\n                    <th scope=\"col\">Checkin</th>\n                    <th scope=\"col\">Report Period<br>Grace Period</th>\n                    <th scope=\"col\">Last Seen</th>\n                    <th scope=\"col\">Expected</th>\n                    <th scope=\"col\"></th>\n                </tr>\n            </thead>\n            <tbody>\n            {{range $s.LimitedCheckins}}\n            {{ $ch := . }}\n            <tr class=\"{{ if lt $ch.Expected 0}}bg-warning text-black{{else}}bg-light{{end}}\">\n                <td>{{$ch.Name}}<br><a href=\"{{$ch.Link}}\" target=\"_blank\">{{$ch.Link}}</a></td>\n                <td>every {{Duration $ch.Period}}<br>after {{Duration $ch.Grace}}</td>\n                <td>{{ if $ch.Last.CreatedAt.IsZero}}\n                        Never\n                    {{else}}\n                        {{Ago $ch.Last.CreatedAt}}\n                    {{end}}\n                </td>\n                <td>\n                    {{ if $ch.Last.CreatedAt.IsZero}}\n                        -\n                    {{else}}\n                        {{ if lt $ch.Expected 0}}{{Duration $ch.Expected}} ago{{else}}in {{Duration $ch.Expected}}{{end}}\n                    {{end}}\n                </td>\n                <td><a href=\"/checkin/{{$ch.Id}}/delete\" class=\"btn btn-sm btn-danger\">Delete</a></td>\n            </tr>\n            {{end}}\n            </tbody>\n        </table>\n        {{end}}\n        {{template \"form_checkin\" $s}}\n    </div>\n\n{{end}}\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://assets.statup.io/pikaday.js\"></script>\n{{ else }}\n<script src=\"/js/pikaday.js\"></script>\n{{end}}\n{{$s := .Service}}\n<script>\n\n    var ctx = document.getElementById(\"service\").getContext('2d');\n\n    var chartdata = new Chart(ctx, {\n        type: 'line',\n        data: {\n            datasets: [{\n                label: 'Response Time (Milliseconds)',\n                data: [],\n                backgroundColor: [\n                    'rgba(47, 206, 30, 0.92)'\n                ],\n                borderColor: [\n                    'rgb(47, 171, 34)'\n                ],\n                borderWidth: 1\n            }]\n        },\n        options: {\n            legend: {\n                display: false\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    },\n                    gridLines: {\n                        display: true\n                    }\n                }],\n                xAxes: [{\n                    type: 'time',\n                    distribution: 'series',\n                    time: {\n                        displayFormats: {\n                            'millisecond': 'MMM DD',\n                            'second': 'MMM DD',\n                            'minute': 'MMM DD',\n                            'hour': 'MMM DD hA',\n                            'day': 'MMM DD',\n                            'week': 'MMM DD',\n                            'month': 'MMM DD',\n                            'quarter': 'MMM DD',\n                            'year': 'MMM DD',\n                        }\n                    },\n                    gridLines: {\n                        display: true\n                    },\n                    ticks: {\n                        source: 'auto'\n                    }\n                }],\n            },\n            elements: {\n                point: {\n                    radius: 0\n                }\n            }\n        }\n    });\n\n\n    var startPick = new Pikaday({\n        field: $('#service_start')[0],\n        bound: false,\n        trigger: $(\"#start_date\"),\n        container: $(\"#start_container\")[0],\n        maxDate: new Date(),\n        onSelect: function(date) {\n            $('#service_start')[0].value = Math.round(date.getTime() / 1000);\n            this.hide();\n        }\n    });\n\n    var endPick = new Pikaday({\n        field: $('#service_end')[0],\n        bound: false,\n        trigger: $(\"#end_date\"),\n        container: $(\"#end_container\")[0],\n        maxDate: new Date(),\n        onSelect: function(date) {\n            $('#service_end')[0].value = Math.round(date.getTime() / 1000);\n            this.hide();\n        }\n    });\n\n    startPick.setDate(new Date({{.Start}}* 1000);\n    )\n    endPick.setDate(new Date({{.End}}* 1000);\n    )\n    startPick.hide();\n    endPick.hide();\n\n    $(\"#start_date\").click(function(e) {\n        startPick.show()\n    });\n\n    $(\"#end_date\").click(function(e) {\n        endPick.show()\n    });\n\n    AjaxChart(chartdata,{{$s.Id}},{{.Start}},{{.End}},\"hour\");\n\n</script>\n{{end}}\n"),
301
        }
302
        file14 := &embedded.EmbeddedFile{
303
                Filename:    "services.html",
304
                FileModTime: time.Unix(1538459465, 0),
305
                Content:     string("{{define \"title\"}}Statup | Services{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n\n    <div class=\"col-12\">\n\n        <h3>Services</h3>\n\n        <table class=\"table\">\n            <thead>\n            <tr>\n                <th scope=\"col\">Name</th>\n                <th scope=\"col\" class=\"d-none d-md-table-cell\">Status</th>\n                <th scope=\"col\"></th>\n            </tr>\n            </thead>\n            <tbody class=\"sortable\">\n            {{range .}}\n            <tr id=\"{{.Id}}\">\n                <td><span class=\"drag_icon d-none d-md-inline\">&#9776;</span> {{.Name}}</td>\n                <td class=\"d-none d-md-table-cell\">{{if .Online}}<span class=\"badge badge-success\">ONLINE</span>{{else}}<span class=\"badge badge-danger\">OFFLINE</span>{{end}} </td>\n                <td class=\"text-right\">\n                    <div class=\"btn-group\">\n                        <a href=\"/service/{{.Id}}\" class=\"btn btn-primary\">View</a>\n                        <a href=\"/service/{{.Id}}/delete\" class=\"btn btn-danger confirm-btn\">Delete</a>\n                    </div>\n                </td>\n            </tr>\n            {{end}}\n            </tbody>\n        </table>\n\n        <h3>Create Service</h3>\n\n        {{template \"form_service\" NewService}}\n\n    </div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n{{if USE_CDN}}\n<script src=\"https://assets.statup.io/sortable.min.js\"></script>\n{{ else }}\n<script src=\"/js/sortable.min.js\"></script>\n{{end}}\n<script>\n    sortable('.sortable', {\n        forcePlaceholderSize: true,\n        hoverClass: 'sortable_drag',\n        handle: '.drag_icon'\n    });\n    sortable('.sortable')[0].addEventListener('sortupdate', function(e) {\n        var i = 0;\n        var newOrder = [];\n        var dest = e.detail.destination.items;\n        dest.forEach(function(d) {\n            i++;\n            var o = {service: parseInt(d.id), order: i}\n            newOrder.push(o);\n        });\n        $.post(\"/services/reorder\", JSON.stringify(newOrder), function(data, status){\n        });\n    });\n</script>\n{{end}}\n"),
306
        }
307
        file15 := &embedded.EmbeddedFile{
308
                Filename:    "settings.html",
309
                FileModTime: time.Unix(1538947359, 0),
310
                Content:     string("{{define \"title\"}}Statup | Settings{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <div class=\"row\">\n            <div class=\"col-md-3 col-sm-12 mb-4 mb-md-0\">\n                <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n                    <a class=\"nav-link active\" id=\"v-pills-home-tab\" data-toggle=\"pill\" href=\"#v-pills-home\" role=\"tab\" aria-controls=\"v-pills-home\" aria-selected=\"true\">Settings</a>\n                    <a class=\"nav-link\" id=\"v-pills-style-tab\" data-toggle=\"pill\" href=\"#v-pills-style\" role=\"tab\" aria-controls=\"v-pills-style\" aria-selected=\"false\">Theme Editor</a>\n                {{ range .Notifications }}\n                    <a class=\"nav-link text-capitalize\" id=\"v-pills-{{underscore .Select.Method}}-tab\" data-toggle=\"pill\" href=\"#v-pills-{{underscore .Select.Method}}\" role=\"tab\" aria-controls=\"v-pills-{{underscore .Select.Method}}\" aria-selected=\"false\">{{.Select.Method}} <span class=\"badge badge-pill badge-secondary\"></span></a>\n                {{ end }}\n                    <a class=\"nav-link\" id=\"v-pills-browse-tab\" data-toggle=\"pill\" href=\"#v-pills-browse\" role=\"tab\" aria-controls=\"v-pills-home\" aria-selected=\"false\">Browse Plugins</a>\n                    <a class=\"nav-link d-none\" id=\"v-pills-backups-tab\" data-toggle=\"pill\" href=\"#v-pills-backups\" role=\"tab\" aria-controls=\"v-pills-backups\" aria-selected=\"false\">Backups</a>\n                {{ range .Plugins }}\n                    <a class=\"nav-link text-capitalize\" id=\"v-pills-{{underscore .Name}}-tab\" data-toggle=\"pill\" href=\"#v-pills-{{underscore .Name}}\" role=\"tab\" aria-controls=\"v-pills-profile\" aria-selected=\"false\">{{.Name}}</a>\n                {{end}}\n                </div>\n            </div>\n            <div class=\"col-md-8 col-sm-12\">\n            {{if Error}}\n                <div class=\"alert alert-danger\" role=\"alert\">{{Error}}</div>\n            {{end}}\n                <div class=\"tab-content\" id=\"v-pills-tabContent\">\n                    <div class=\"tab-pane fade show active\" id=\"v-pills-home\" role=\"tabpanel\" aria-labelledby=\"v-pills-home-tab\">\n                        <h3>Settings</h3>\n\n                        <form method=\"POST\" action=\"/settings\">\n                            <div class=\"form-group\">\n                                <label for=\"project\">Project Name</label>\n                                <input type=\"text\" name=\"project\" class=\"form-control\" value=\"{{ .Name }}\" id=\"project\" placeholder=\"Great Uptime\">\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"description\">Project Description</label>\n                                <input type=\"text\" name=\"description\" class=\"form-control\" value=\"{{ .Description }}\" id=\"description\" placeholder=\"Great Uptime\">\n                            </div>\n\n                            <div class=\"form-group row\">\n                                <div class=\"col-8 col-sm-9\">\n                                    <label for=\"domain\">Domain</label>\n                                    <input type=\"text\" name=\"domain\" class=\"form-control\" value=\"{{ .Domain }}\" id=\"domain\">\n                                </div>\n                                <div class=\"col-4 col-sm-3 mt-sm-1 mt-0\">\n                                    <label for=\"enable_cdn\" class=\"d-inline d-sm-none\">Enable CDN</label>\n                                    <label for=\"enable_cdn\" class=\"d-none d-sm-block\">Enable CDN</label>\n                                    <span class=\"switch\">\n                                <input type=\"checkbox\" name=\"enable_cdn\" class=\"switch\" id=\"switch-normal\" {{if USE_CDN}}checked{{end}}{{if .UsingAssets}} disabled{{end}}>\n                                <label for=\"switch-normal\" class=\"mt-2 mt-sm-0\"></label>\n                              </span>\n                                </div>\n\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"footer\">Custom Footer</label>\n                                <textarea rows=\"4\" name=\"footer\" class=\"form-control\" id=\"footer\">{{ .Footer }}</textarea>\n                            </div>\n\n                            <div class=\"form-group\">\n                                <label for=\"timezone\">Timezone</label><span class=\"mt-1 small float-right\">Current: {{.CurrentTime}}</span>\n                                <select class=\"form-control\" name=\"timezone\" id=\"timezone\">\n                                    <option value=\"-12.0\" {{if eq (ToString .Timezone) \"-12\"}}selected{{end}}>(GMT -12:00) Eniwetok, Kwajalein</option>\n                                    <option value=\"-11.0\" {{if eq (ToString .Timezone) \"-11\"}}selected{{end}}>(GMT -11:00) Midway Island, Samoa</option>\n                                    <option value=\"-10.0\" {{if eq (ToString .Timezone) \"-10\"}}selected{{end}}>(GMT -10:00) Hawaii</option>\n                                    <option value=\"-9.0\" {{if eq (ToString .Timezone) \"-9\"}}selected{{end}}>(GMT -9:00) Alaska</option>\n                                    <option value=\"-8.0\" {{if eq (ToString .Timezone) \"-8\"}}selected{{end}}>(GMT -8:00) Pacific Time (US &amp; Canada)</option>\n                                    <option value=\"-7.0\" {{if eq (ToString .Timezone) \"-7\"}}selected{{end}}>(GMT -7:00) Mountain Time (US &amp; Canada)</option>\n                                    <option value=\"-6.0\" {{if eq (ToString .Timezone) \"-6\"}}selected{{end}}>(GMT -6:00) Central Time (US &amp; Canada), Mexico City</option>\n                                    <option value=\"-5.0\" {{if eq (ToString .Timezone) \"-5\"}}selected{{end}}>(GMT -5:00) Eastern Time (US &amp; Canada), Bogota, Lima</option>\n                                    <option value=\"-4.0\" {{if eq (ToString .Timezone) \"-4\"}}selected{{end}}>(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option>\n                                    <option value=\"-3.5\" {{if eq (ToString .Timezone) \"-3.5\"}}selected{{end}}>(GMT -3:30) Newfoundland</option>\n                                    <option value=\"-3.0\" {{if eq (ToString .Timezone) \"-3\"}}selected{{end}}>(GMT -3:00) Brazil, Buenos Aires, Georgetown</option>\n                                    <option value=\"-2.0\" {{if eq (ToString .Timezone) \"-2\"}}selected{{end}}>(GMT -2:00) Mid-Atlantic</option>\n                                    <option value=\"-1.0\" {{if eq (ToString .Timezone) \"-1\"}}selected{{end}}>(GMT -1:00 hour) Azores, Cape Verde Islands</option>\n                                    <option value=\"0.0\" {{if eq (ToString .Timezone) \"0\"}}selected{{end}}>(GMT) Western Europe Time, London, Lisbon, Casablanca</option>\n                                    <option value=\"1.0\" {{if eq (ToString .Timezone) \"1\"}}selected{{end}}>(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris</option>\n                                    <option value=\"2.0\" {{if eq (ToString .Timezone) \"2\"}}selected{{end}}>(GMT +2:00) Kaliningrad, South Africa</option>\n                                    <option value=\"3.0\" {{if eq (ToString .Timezone) \"3\"}}selected{{end}}>(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option>\n                                    <option value=\"3.5\" {{if eq (ToString .Timezone) \"3.5\"}}selected{{end}}>(GMT +3:30) Tehran</option>\n                                    <option value=\"4.0\" {{if eq (ToString .Timezone) \"4\"}}selected{{end}}>(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option>\n                                    <option value=\"4.5\" {{if eq (ToString .Timezone) \"4.5\"}}selected{{end}}>(GMT +4:30) Kabul</option>\n                                    <option value=\"5.0\" {{if eq (ToString .Timezone) \"5\"}}selected{{end}}>(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option>\n                                    <option value=\"5.5\" {{if eq (ToString .Timezone) \"5.5\"}}selected{{end}}>(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option>\n                                    <option value=\"5.75\" {{if eq (ToString .Timezone) \"5.75\"}}selected{{end}}>(GMT +5:45) Kathmandu</option>\n                                    <option value=\"6.0\" {{if eq (ToString .Timezone) \"6\"}}selected{{end}}>(GMT +6:00) Almaty, Dhaka, Colombo</option>\n                                    <option value=\"7.0\" {{if eq (ToString .Timezone) \"7\"}}selected{{end}}>(GMT +7:00) Bangkok, Hanoi, Jakarta</option>\n                                    <option value=\"8.0\" {{if eq (ToString .Timezone) \"8\"}}selected{{end}}>(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option>\n                                    <option value=\"9.0\" {{if eq (ToString .Timezone) \"9\"}}selected{{end}}>(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option>\n                                    <option value=\"9.5\" {{if eq (ToString .Timezone) \"9.5\"}}selected{{end}}>(GMT +9:30) Adelaide, Darwin</option>\n                                    <option value=\"10.0\" {{if eq (ToString .Timezone) \"10.5\"}}selected{{end}}>(GMT +10:00) Eastern Australia, Guam, Vladivostok</option>\n                                    <option value=\"11.0\" {{if eq (ToString .Timezone) \"11\"}}selected{{end}}>(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option>\n                                    <option value=\"12.0\" {{if eq (ToString .Timezone) \"12\"}}selected{{end}}>(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka</option>\n                                </select>\n                            </div>\n\n                            <button type=\"submit\" class=\"btn btn-primary btn-block\">Save Settings</button>\n\n                            <div class=\"form-group row mt-3\">\n                                <label for=\"api_key\" class=\"col-sm-3 col-form-label\">API Key</label>\n                                <div class=\"col-sm-9\">\n                                    <input type=\"text\" class=\"form-control select-input\" value=\"{{ .ApiKey }}\" id=\"api_key\" readonly>\n                                </div>\n                            </div>\n\n                            <div class=\"form-group row\">\n                                <label for=\"api_secret\" class=\"col-sm-3 col-form-label\">API Secret</label>\n                                <div class=\"col-sm-9\">\n                                    <input type=\"text\" class=\"form-control select-input\" value=\"{{ .ApiSecret }}\" id=\"api_secret\" readonly>\n                                    <small class=\"form-text text-muted\">You can <a href=\"/api/renew\">Regenerate API Keys</a> if you need to.</small>\n                                </div>\n                            </div>\n\n                            <div class=\"row\">\n                                <a href=\"/settings/export\" class=\"btn btn-sm btn-secondary float-right\">Export Settings</a>\n                            </div>\n\n                        </form>\n\n                    </div>\n\n                    <div class=\"tab-pane\" id=\"v-pills-style\" role=\"tabpanel\" aria-labelledby=\"v-pills-style-tab\">\n\n                    {{if not .UsingAssets }}\n                        <a href=\"/settings/build\" class=\"btn btn-primary btn-block\"{{if USE_CDN}} disabled{{end}}>Enable Local Assets</a>\n                    {{ else }}\n                        <form method=\"POST\" action=\"/settings/css\">\n                            <ul class=\"nav nav-pills mb-3\" id=\"pills-tab\" role=\"tablist\">\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link active\" id=\"pills-vars-tab\" data-toggle=\"pill\" href=\"#pills-vars\" role=\"tab\" aria-controls=\"pills-vars\" aria-selected=\"true\">Variables</a>\n                                </li>\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link\" id=\"pills-theme-tab\" data-toggle=\"pill\" href=\"#pills-theme\" role=\"tab\" aria-controls=\"pills-theme\" aria-selected=\"false\">Base Theme</a>\n                                </li>\n                                <li class=\"nav-item col text-center\">\n                                    <a class=\"nav-link\" id=\"pills-mobile-tab\" data-toggle=\"pill\" href=\"#pills-mobile\" role=\"tab\" aria-controls=\"pills-mobile\" aria-selected=\"false\">Mobile</a>\n                                </li>\n                            </ul>\n                            <div class=\"tab-content\" id=\"pills-tabContent\">\n                                <div class=\"tab-pane show active\" id=\"pills-vars\" role=\"tabpanel\" aria-labelledby=\"pills-vars-tab\">\n                                    <textarea name=\"variables\" id=\"sass_vars\">{{ .SassVars }}</textarea>\n                                </div>\n                                <div class=\"tab-pane\" id=\"pills-theme\" role=\"tabpanel\" aria-labelledby=\"pills-theme-tab\">\n                                    <textarea name=\"theme\" id=\"theme_css\">{{ .BaseSASS }}</textarea>\n                                </div>\n                                <div class=\"tab-pane\" id=\"pills-mobile\" role=\"tabpanel\" aria-labelledby=\"pills-mobile-tab\">\n                                    <textarea name=\"mobile\" id=\"mobile_css\">{{ .MobileSASS }}</textarea>\n                                </div>\n                            </div>\n                            <button type=\"submit\" class=\"btn btn-primary btn-block mt-2\">Save Style</button>\n                            <a href=\"/settings/delete_assets\" class=\"btn btn-danger btn-block confirm-btn\">Delete All Assets</a>\n                        </form>\n                    {{end}}\n                    </div>\n\n                {{ range .Notifications }}\n                {{$n := .Select}}\n                    <div class=\"tab-pane\" id=\"v-pills-{{underscore $n.Method}}\" role=\"tabpanel\" aria-labelledby=\"v-pills-{{underscore $n.Method }}-tab\">\n\n                    {{template \"form_notifier\" .}}\n\n                    {{ if $n.Logs }}\n                        Sent {{$n.SentLastHour}} in the last hour<br>\n                    {{ range $n.Logs }}\n                        <div class=\"card mt-1\">\n                            <div class=\"card-body\">\n                            {{.Message}}\n                                <p class=\"card-text\"><small class=\"text-muted\">Sent {{.Time.Ago}}</small></p>\n                            </div>\n                        </div>\n                    {{ end }}\n                    {{ end }}\n                    </div>\n                {{ end }}\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-browse\" role=\"tabpanel\" aria-labelledby=\"v-pills-browse-tab\">\n                    {{ range .Repos }}\n                        <div class=\"card col-6\" style=\"width: 18rem;\">\n                            <div class=\"card-body\">\n                                <h5 class=\"card-title\">{{ .Name }}</h5>\n                                <p class=\"card-text\">{{ .Description }}</p>\n                                <a href=\"/plugins/download/{{ .Name }}\" class=\"card-link\">Add</a>\n                            </div>\n                        </div>\n                    {{ end }}\n                    </div>\n\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-backups\" role=\"tabpanel\" aria-labelledby=\"v-pills-backups-tab\">\n                        <a href=\"/backups/create\" class=\"btn btn-primary btn-block\">Backup Database</a>\n                    </div>\n\n                {{ range .Plugins }}\n\n                    <div class=\"tab-pane fade\" id=\"v-pills-{{underscore .Name}}\" role=\"tabpanel\" aria-labelledby=\"v-pills-{{underscore .Name}}-tab\">\n\n                        <h4 class=\"text-capitalize\">{{ .Name }}</h4>\n                        <span class=\"text-muted\">{{ .Description }}</span>\n\n                        <div class=\"mt-1\">\n                        {{ safe .Form }}\n                        </div>\n\n                    </div>\n                {{end}}\n\n                </div>\n            </div>\n\n        </div>\n    </div>\n</div>\n{{end}}\n{{define \"extra_css\"}}\n<link rel=\"stylesheet\" href=\"https://assets.statup.io/codemirror.css\">\n<link rel=\"stylesheet\" href=\"https://assets.statup.io/codemirror-colorpicker.css\"/>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"https://assets.statup.io/codemirror.js\"></script>\n<script src=\"https://assets.statup.io/css.js\"></script>\n<script src=\"https://assets.statup.io/codemirror-colorpicker.min.js\"></script>\n{{end}}\n"),
311
        }
312
        file16 := &embedded.EmbeddedFile{
313
                Filename:    "setup.html",
314
                FileModTime: time.Unix(1538459628, 0),
315
                Content:     string("{{define \"title\"}}Statup | Setup{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n    <div class=\"col-4 offset-4 mt-2 mb-5\"><img width=\"100%\" src=\"/statup.png\"></div>\n    <div class=\"col-12\">\n    {{ if .Error }}\n        <div class=\"alert alert-danger\" role=\"alert\">\n        {{ .Error }}\n        </div>\n    {{ end }}\n        <form method=\"POST\" id=\"setup_form\" action=\"/setup\">\n            <div class=\"row\">\n                <div class=\"col-6\">\n                    <div class=\"form-group\">\n                        <label for=\"inputState\">Database Connection</label>\n                        <select id=\"database_type\" name=\"db_connection\" class=\"form-control\">\n                            <option selected value=\"postgres\">Postgres</option>\n                            <option value=\"sqlite\">Sqlite</option>\n                            <option value=\"mysql\">MySQL</option>\n                        </select>\n                    </div>\n                    <div class=\"form-group\" id=\"db_host\">\n                        <label for=\"db_host_in\">Host</label>\n                        <input type=\"text\" name=\"db_host\" id=\"db_host_in\" class=\"form-control\" value=\"{{.DbHost}}\" placeholder=\"localhost\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_port\">\n                        <label for=\"db_port_in\">Database Port</label>\n                        <input type=\"text\" name=\"db_port\" id=\"db_port_in\" class=\"form-control\" value=\"{{.DbPort}}\" placeholder=\"localhost\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_user\">\n                        <label for=\"db_user_in\">Username</label>\n                        <input type=\"text\" name=\"db_user\" id=\"db_user_in\" class=\"form-control\" value=\"{{.DbUser}}\" placeholder=\"root\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_password\">\n                        <label for=\"db_password\">Password</label>\n                        <input type=\"password\" name=\"db_password\" class=\"form-control\" value=\"{{.DbPass}}\" id=\"db_password\" placeholder=\"password123\">\n                    </div>\n                    <div class=\"form-group\" id=\"db_database\">\n                        <label for=\"db_database\">Database</label>\n                        <input type=\"text\" name=\"db_database\" class=\"form-control\" value=\"{{.DbData}}\" id=\"db_database\" placeholder=\"Database name\">\n                    </div>\n\n                </div>\n\n                <div class=\"col-6\">\n\n                    <div class=\"form-group\">\n                        <label for=\"project\">Project Name</label>\n                        <input type=\"text\" name=\"project\" class=\"form-control\" value=\"{{.Project}}\" id=\"project\" placeholder=\"Great Uptime\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"description\">Project Description</label>\n                        <input type=\"text\" name=\"description\" class=\"form-control\" value=\"{{.Description}}\" id=\"description\" placeholder=\"Great Uptime\">\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"domain_input\">Domain URL</label>\n                        <input type=\"text\" name=\"domain\" class=\"form-control\" value=\"{{.Domain}}\" id=\"domain_input\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"username\">Admin Username</label>\n                        <input type=\"text\" name=\"username\" class=\"form-control\" value=\"{{.Username}}\" id=\"username\" value=\"admin\" placeholder=\"admin\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"email\">Admin Email Address</label>\n                        <input type=\"email\" name=\"email\" class=\"form-control\" value=\"{{.Email}}\" id=\"email\" placeholder=\"info@admin.com\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <label for=\"password\">Admin Password</label>\n                        <input type=\"password\" name=\"password\" class=\"form-control\" value=\"{{.Password}}\" id=\"password\" placeholder=\"password\" required>\n                    </div>\n\n                    <div class=\"form-group\">\n              <span class=\"switch\">\n                <input type=\"checkbox\" name=\"sample_data\" class=\"switch\" id=\"switch-normal\" checked>\n                <label for=\"switch-normal\">Load Sample Data</label>\n              </span>\n                    </div>\n\n                </div>\n                <button id=\"setup_button\" type=\"submit\" class=\"btn btn-primary btn-block disable_click\">Save Settings</button>\n            </div>\n        </form>\n    </div>\n</div>\n{{end}}\n{{define \"extra_scripts\"}}\n<script src=\"/js/setup.js\"></script>\n{{end}}\n"),
316
        }
317
        file17 := &embedded.EmbeddedFile{
318
                Filename:    "statup.png",
319
                FileModTime: time.Unix(1533786305, 0),
320
                Content:     string("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x90\x00\x00\x00|\b\x06\x00\x00\x00GN\xe6\x81\x00\x00\x01\x83iCCPsRGB IEC61966-2.1\x00\x00(\x91u\x91\xcf+\xc3a\x1c\xc7_\xdb\xc80MqppX\x1a\x17\x9bfjqQ&\xa1\xa45S\x86\xcb\xf6\xb5\x1fj?\xbe}\xbf\x93\xe4\xaa\\\x15%.~\x1d\xf8\v\xb8*g\xa5\x88\x94\x1c\x9c\x9c\x89\v\xeb\xeb\xf3\xb5Ֆ\xec\xf3\xf4y>\xaf\xe7\xfd<\x9fO\xcf\xf3y\xc0\x1a\xc9(Y\xbd\xce\a\xd9\\A\v\x8f\a]s\xd1yW\xc3\vv\x1a\xb1ы3\xa6\xe8\xeaH(4EM\xfb\xbc\xc7b\xc6[\xafY\xab\xf6\xb9\u007f\xady)\xa1+`\xb1\v\x0f+\xaaV\x10\x9e\x10\x9eZ-\xa8&\xef\b\xb7+\xe9ؒ\xf0\x99\xb0G\x93\v\nߙz\xbcį&\xa7J\xfcm\xb2\x16\t\x8f\x82\xb5Uؕ\xaa\xe2x\x15+i-+,/ǝͬ(\xe5\xfb\x98/q$r\xb33\x12\xbb\xc4;\xd1\t3N\x10\x17\x93\x8c1J\x80~\x86d\x0e\xe0\xc5O\x9f\xac\xa8\x91\xef\xfb͟&/\xb9\x8a\xcc*kh,\x93\"M\x01\x8f\xa8+R=!1)zBF\x865\xb3\xff\u007f\xfb\xaa'\a\xfc\xa5\xea\x8e \xd4?\x1b\xc6{74lCq\xcb0\xbe\x8e\f\xa3x\f\xb6'\xb8\xccU\xf2\xf3\x870\xf8!\xfaVEs\x1f\x80s\x03ί*Z|\x17.6\xa1\xe3Q\x8di\xb1_\xc9&nM&\xe1\xed\x14Z\xa2\xd0v\x03M\v\xa5\x9e\x95\xf79y\x80Ⱥ|\xd55\xec\xedC\x8f\x9cw.\xfe\x00\x1a\x80g\xc3\x17\xe1\xe9w\x00\x00\x00\tpHYs\x00\x00=\x84\x00\x00=\x84\x01լ\xaft\x00\x00 \x00IDATx\x9c\xec\xbdy\x98$Gu/\xfa\x8b\x88\xcc\xea\x9eю\x05H,\x12\b\x8cY\xb4\x8c4\x82ь\x84a$\xb8\x86\x87\xd9\xeck\x8c\xedk??\xaf`\xf9^\x1b\x84\x04\bc\xbc\x00bF#\xd9\xc6\x12\x8b\xfd\x8cͽ6B\xba\xc6\x17\x03\xc6\xd8\x06I\xc3&\x01\x96f\x1f6\vI#\t\x8df\xba\xa7\xf7\xae\xaǎ8\uf3ec\x93\xf5\xcb\xe8\xea\x99\xea\xeej\xeb\xcd\xf7\xd5\xf9\xbe\xfe\xba\xbb\x96\xcc\x13'N\x9c\xe5wND\x02C\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4!\riHC\x1aҐ\x864\xa4\xe5\x93y\xbc\x198\x1e\xe85\xfb~\xf6CƘ\xd7\xe9\xff\"\x82\x10\x02\x8c1\xb0\xd6BD\x00\x00\xd6Zx\xef\xe1\x9cCQ\x14\xb0\xd6\"I\x12\x84\x10 \"0\xc6T\u007f;\xe7\xb2O?\xef\x96g<^c\x1a\xd2\xd2\xe8\xaa\x03\xd7\xfe\xa8\x88l\xef\xcc\x1d\x00\xd4\xe6\xd3Z\vkm5\xef\xde\xfb\xea\xb7\xea\x00\x80\xea\xbb!\x04ա\xf7\xddx\xf6u7?n\x03\x1bҐV@\xc9\xe3\xcd\xc0\xf1@ιS\xbd\xf7g\xaa\xe3h4\x1a0\xc6\xc0{\x0fcL\xe5\x1cԸ\xa8A1\xa6\xeb\x9fE\x04\"\x82$IP\x14\x05D${\x1c\x874\xa4\xa5S\x12B8\x93\x9d\x06\xcf=P:\x05\x9d\u007f\x0e.TO\xa2\x00\x02\xd6Z\xe4y~\xc2\xe3<\xae!\ri\xd9d\x1fo\x06\x8e\a*\x8a\xa22\b\x9a]\x88H\xe5H\xf4G3\x11\xfdl\xc7@\x00@͡8窈tH\xc7\ay\xef\x01\x00IR\xc6\\:\xe7\x00\xaay\xd7\xcfāD\x92$\x95ð\xb6\\r!\x04\xe4y^]oHC:\x1ei\xa8\xbd}\x90\x88\xfc\x98F\x93j4\x8c1\xc8\xf3\xbc\x8a*\xd90(\x94\xa1\x86C\xe1\x8c\x10B\x15\x8db(\xfb㊒\x89\xe4\xc9\xe1GB\xe5,8X\x88\x03\x03\xce:4+\x01P\xe9\x80~7I\x12\xf8\xa6\u007f\xfe\xe30\x9c!\ri 44b}\xd0\xdc\xec\xec\x8f$I\x02Ai$\x9csH\x92\xa42\x1c\x9c]\xa8\xf1P\xc7a\x8c\xa9\xfeN\xd3\x14y\x9e\xab\xa1\x19f\u007f\xc7\x11\xd9Y{BvJ\x86$I\xaa\fC\xeb\x18\xaa\v\x1a4\x88H-ke\x87\xa2\xce\x04(\xf5\x06s\xf2\xc4\xc7qXC\x1aҊh\xe8@\xfa\xa0v\xbb\x8d\xf9\xf9y8\xe7*\xa8\x8a!,\xeb\x1c\x1ai\x8a$M+\x98K\xb3\x0e\xfd\xac\x1a\x11\xa0[@\x1d\xd2\xf1C>\x94\x01\x80f\x97q\x93\x04\x80\xea=\xfd[\xe7\xdd\x18S\x05\x0f\xda|\x11B(\x9d\xcc\xe39\xa8!\ri\x854t }\x90\x16\xbf\xf5oŶ\xb3,\xab \x8c\xe6\xfc|\xe5 FFF\x90$\t\xacsH\x9c\x83\xeb@YZ\x84WhkH\xc7\x17i\x10\xa0p\xa5\xbe\x06\xa0\x06m*T\xa5\r\x13\x00jP\x16\xd0u0\x90\xff\xc4\x01\fiH\x03\xa6\xa1\x03Y\"\xa9q\x00\xea\xc6B\xdfS(\xc3{\xdf\x13\xea\xb0\xd6\"IS$C\ar\\\x911\x06\x82n\xfdC\xb3L\x00\v\x1c\x05\xb7\xeer&\xa2\xef+\f*\"(\x90?>\x03\x1aҐ\x06@C\a\xd2\a\xc5\x06@\xfb\xfb\xb5\x95\x97\xb3\v\xcdV\x14\xaa\xe0V_\xed\xba)\x8ab\ba\x1dgd`\xaa \x00(;\xf3\x14\x96Ү<\xaeq\xa8\x13Q\xbdQb\xe7!\"pf\x18H\f\xe9\xf8\xa5a!\xb7\x0fR\x87\xa1\x06\x847\x8e)\xe9\xfb\xfa\x9a\x1a\x14Żոp\xf7\u0590\x8e\x1f\x1a\x97#h\x86\x16rߝ;\x9dW\x00\xd5\xdcrV\xa2\u007fk\xa6\xaa\xdf\xe1v\xdf!\r\xe9x\xa6a\x06\xd2'\xa5iZ-~\x8e.\x15\xa2`H\x83\xdbv\xf5s\\|\x8f\x9dϐ\xfe\xffO\x87\xe40\\\xbbӎ\v\x8b\x11\xdb@jR\xacIGѰ#\x18A\xa3\xca.\x14\xb2T\xa7\xa2\x1dY\xdc\xf2\x9b\xe79\x1a\x8d\x06\n\x19BXC:~i\xe8@\xfa$\ue80ak\x1f\x9ay\x84\x10*GÝ6\xfa\xbef2\x00*\xcc|H\xc7\a%6\xa9\x0e\xfe\t\x120\xef\x9bp.\xc3Ts\xba\xac}\xc1 \xb5)Fl\x03\t\x12\xa4&\xc1\t#' A\xb2\xe0T\x02\xd5\r\xef=\x02\x86P搎_\x1a:\x90>I3\x8d4MὯ\xa2J\xdeX\xc6\xd1'CV\xba{\x1d\xe8\xc2\x19C\xf8\xe2\xf8\xa2 \x01\b\xf5F\t\x0e$\xac\xb5\xc8B\x86V\xd1꾖[H\x10\x8c\xba\x11\x8c&k\x90\"A\x82\x04k\x1bk鴂\xf4\xf1\x1eڐ\x86\xb4l\x1a:\x90>H\x8b\xe3i\x9a\xd6\x1c\x06\x1b\x13\x00\v:o\xb8\xc0\xaeQ\xa7b\xe3C\ar|Q\x90\x00#\xdd#k4(\xe0ڇ\xea\x03\xeb\x00\fЖ\f\xcdv\xab\xcaB\xc3\\@b\x124L\x8a\x864\x1e\xef\xa1\riH˦\xa1\x03\xe9\x83b\x87\xa0\x99FQ\x14h4\x1a\xb5\x13w\xb9\x88\xae\u007f3|\xa1\x1bІ5\x90\xe3\x93t\x9e\xb9\xee\xa5u.\xee\xd6\xe3\xf3\xb14\v\xd5\x1d\xea\"\x82`\x02\n[`\x16s\x8f\xe7p\x864\xa4\x15\xd1Њ\xf5Aj\x04ԑp\x1dDk\x1cj<\xf8o>\xad\x95\x1d\f\x1b\x9a!\x1d\x1f$\xe8\x1d\x1c\xf0\x916\x9cyhV\x1a\x9f\xdc\xcc\xd0\xe60\x13\x1d\xd2\xf1N\xff\xe9\x19ȋ\xbf\xf2\xf2\x91\x10\xc2\x05Ƙ\x17\x8a\xc8\x19\"r\x1a\x80\xd3\x00\x9c\xea\xbd?\xcd9w\x92\x88\x8c\x8bȣ\xd6\xdaGC\b\x8f:\xe7~\b\xe0Q\x11yTD\x1e5\xc6L}\xfd\xa5\xb7\xff\xa7\xad<\xed\xedg\xe7\xc1\xce@?\xc3\xceCq\xf0\xf8\xb0\xc5\xe3\xd9y\\r\xfbKM\x92$'\x15Eq\xa61\xe6Lk\xed\x99\xde\xfb3\x00xc\xccc\x00\x1eK\x92\xe41\xe7\xdc\xc1$M'\xbf\xf8\xc2\xcf\x1e\x9f\x03\xedA\xba_\x83aHv\x1c\x9a\x85\xd4\xe0+\xa0\xb6G\x84\x03\v\xa0\xb3)uXD\x1f\xd2Q\xe8-\x0f\xbcc$M\xd33\x8a\xa28\xc3Z{f\b\xe1\f\x00'Zk\x1f\x03\xf0\xc3\xceϣ!\x84\xa9\x1bϾ\xee?}\xbd\xad\xba\x03y\xd1\xe7_|\xa2I쫌3\x1b\xad\xb3\x1bB\b\x17y\xef\x1b\\/\x887]q\xa4\xaf\xbfy\xf3\x951\xa6y\xe9\xf6+\x0e\x00\xf87c\xccg\xf2<\xdf\xfe\x8d+\xb6\xaf\xda\xf35\xd8(\xf0\xa9\xbc\xf1\x06C\xc6\xc6\xe3\xd3{\xe3\xd3[\x8f\a'r\xe9\xf6+,\x80M\"\xf2\xd3\x00^\x01\xe0,\xef\xfdZ}_\xe7%.(\x03@\xbbݞ\xdax\xc7\xe6/\x18c>k\x8c\xf9篽\xe4KG\x1e\x9fQ\f\x86\x82\x04X\xb1\xb5\xac3M\xcb\x02\xb8\xea(\x80\x05\xcf\b\x01\xea\xc1\x05?K$\xee\xce\x1aҐ\xae:p\xad\x13\x91\x17\x03\xf8i\x00\xaf\x01p\x16\x9fr\xa0\xfa\xc5[\x05:\x01n\xf3\xea\x87\u007f\xef!\x11\xf9\x17c\xcc߇\x10\xbev\xc3Y\xef\xf7\xab\xcd\xef\xaai\xef\xba[6\\h\x8c\xf9\x8d\x10\xc2/\x008\xc9Z[\x9ef\x9bZ\x88\x11\xd8\xc4\xc1&\x06\xc6Y\xd8\xd4º\xae#ᣰ\x81n\xe7\vG\xf7@w\xb3^\ba\x06\xc0\x17\x92$\xf9l\b\xe1\xf3_{ɗƗ\xca\xef\xc6;6\xbf\xd3\x18\xf3T~\x96\x03\xdd\xff\x97\xbc\xf7'\x01\xa8\x15O9\xb3\xe0\x16\xdd$I\x90eY\xf5\f\x888*\xa5M\x897\xb3c\xe1\xf3\x93\xe2'\x1d\x02@\b\xe1\xe6\xbb6\xdf\xf1\xed\xe5\xcc\xc7\x12\xe4\x90\x18c^\xe2\xbd\xff\xe9F\xa3\xf1\xfa\x10\xc2\x19*g>\a\xaa\xd7ò8\x12\x8f\x8e\xee\b\xd6گy\xefo\x01\xf0Wwm\xbe\xa3\xa7\xb3\u007f\xf9\xb7^}j\x92\xa6\xefՆ\x05v\xb6*S\x85\x8c\xf8@J6\xda\xce9\xe4y^u\xcbu\xf8\xfe\xd6\xe7\xce\xfb\xdf\x1f?\xd6\xd8_\xb3\xefg/4\xc6\xfc*\x80Z\x06)\"\xf0E\xf1\f\x01^\xa5\x87e\xea\xd8\xe2L4\xe6\x87;\xf2\xb8C\x8f\x8ev\u007f0I\x92\xcfq\r%\xbe\x16\xcb\xdc{\xff\x83ϼ\xe0\xd6\x1b\x17\x1bë\xf7\xbe\xe14\x11\xf9\xe3Z\xf3\x86\x0f\x18IF\xb0&\x19E\x82\xa4\xb3w\xa5\x01\x87\xee\xaey\x1dW\xaf\xa0\xads\xdf/\xfc\xe93\xb7|\xeeX2\\*\xbd\xed\xa1w\xfd\xa4\x88\xbc\x82\x1f\x83\xd0h4j\xf2\x8b[\xe6\xb5\xf6č-\xac\x9b\x9d\xef\xbe\xfb\x86\xb3\xde?\xb1\f~\x9e\x0e\xe0\xed\xbc\x11\xb8ױD<'|\xce\x19\xf3\xc7\xf3o\x8c\xf9\xfb\x1b\xcez\xff\x9d\x8b\xdd\xf7\xaa\x03\xd7^\x1aB\xf8ec\xcckE\xe4\x89z/\x9d\u007f\xd6i]\x0f\x00\xaa\xff{<n␈\xfc\x1f\x11\xf9\x14\x80;o<\xfb\xbaU\xd9p4\xd0\f\xe4\xfc\xbf{\xa1\xb1\xd6\xfe\xbcs\xeew\x8b\xa2\xb8\x98\x8d\xa3\x0e\xaehw\x1e\xf9\x99\x15P\xf7(\"0\xd6\xc0:\x8b\xdce0\xce\"i8\x04\blb\xe1RW\xedގ\x1f\x17\xda9!\xf5\xa4\xa2(~&˲\x9f\xb1ֆ˾\xfc\xb2\xafz\xef?+\"\x9f\xb9\xfb\xf2;\xbf\xd7'\xfbo4Ɯ\xaf]U\xec\xdd\xe33\x8d\xb8xʝV:V\xfd>\x1bY\x86<\xe8T\xdf+\xe3hU\x9d\x90^+\x8ah?\x03`U\x1c\xc8e_~\x99\r!\xfc\x82\x88\\\a\xe0\xa9\xec\x10u\x11\xa5iZ9F]б\xa2\xf3i\xb4@\xf5\x00&[\x14ŋ\x01\xbc\xd8Z\xfb֍wl~\a\x80\u007f\xb8k\xf3\x1d\xb54l~~~-\x80+yߌ\xe9\x9cd\x9bt\x1c\n\x9f\x88\xcc\xd9\x1do\xd2\xe3\xf6\xe9,\xcb\x00\xe0o\x01\x1cӁ\x88ȳ\xac\xb5W\xeai\x01z\u007fc\f\x92N\xb6\xc1N@\xef\xa5G\xf4s\xa0\xa3r\x8b\xa1K\x86\xaf:\x06\xe6l\xef\xfd\x95\xcas\xecd\xf4\xbb\xb41\xf1k\x00\x16u I\x92\x9cX\x14ŕ|?\x978\xe4\x92Wss$\xef<\x8f\xc4:\xa4&Ej\x1ah\x98\x14k\xd25\x18MF ^ju\x9a\xce؎\x00\x18\xb8\x03\t!l0\xc6\\\xa9\x81\x197\xa4\xa8\x9c8p\x8ce\xbbXSJ\b\xe1\x03\x00\x96\xec@D\xe4\x89y\x9e_\x19\xef\xe7\x8aϼ\x03P\xdbL\x1cw\xe1\xe9\xba \xe4\xe4\xbb\x00\xee\x8c\xefwՁk\x9f$\"۬\xb5\xbf\xa8\xaf\xc5M\x19\xba\x06\xd8Yęl|\xc8g\b\xe1I\x00~\xd3\x18\xf3\x9b\xde\xfb\x83W?\xfc{\xef\x12\x91\x8fo{\xfa\xfb\x06\x9a\x95\f́\xac\xbfmӳC\b\x1f5\xc6\\\x0et\x9dF\xbc0\x948z\x04\x00\b\xe0s\x0f\xeb-\U000a2342&\xa3\xed,`\x00\xd7p\x10\x03$\x8d\x04H\x05\xd6ؚ\x92w&\xda\xe6y\xfe\xe3\xd6\xda\x1fw\xce\xfdѦ;/?\xfb\xeb/\xbd\xfd\xf0\xb1\xf8W\xc3\xcfg\x15\xf1\x02\xe6\xdf\x00j\x8a\x1e;J&\x8e^\xf4\x1al\x10XI\x81\xfaa\x8d\xfa}\x8e\x86W\x83.\xdd~\xc5\x06\xef\xfd\x9f\x19c60\xb4\xc8{]4\xcaS\x83\xaa<\xb2\x93\xe1(\x8d\x1dk\xa4\xf4\xcf\x0e!\xfc}\x92$_\xbf\xec\xcb/\xbb\xea\xab?\xfeŻ\x95\x0f\x96\x1d\xcb\xc9{\x0f\x9beh\xb7\xdbUf\xa2\x11s\xa3\xd1\x00\x8cA#Ma\xe8\x18\xfd^O\x82<\x16q@\xc0\xed\xd6\xec\xfc\xf5s\\\xe3P^\xf4o5\x8414\xcb:\xc0\x0e*v.\xea\xfcT\xbe\x9c\xb1\xf43\x16\x8e\x8e\xf5\xfaz\x0e\x1b\xeb].\x82\xc2x4\xd1*\xf9\xca:|\xc2am\xba\x06#n\x04)\x12\x8c\x98\x11$f\xf5\xd0n\xd57]{\xbc\xc9V\u05f7\x8e\x8b#m\x96\v\x1bU\x96\xc1r\xa8\xd1hTs\xa7\xd7b\x9d\xd6y\xe09\xe4\xac(\xce^{\xf1\xf3\x96\a\xdea\xad\xb5\xbf\xe6\x9c\xdbR\x14ũ\xbc\xe6ئ0\"\xa1\xa4\xd7繌\xb3V\xb5g\x9d\x03\\\xcf\b!\xfc\x951淯:p\xed[n8\xeb\xfdۗ-\x9c\x88V\xac\x15\xebnِ\x1ac\xde\x1aB\xf8\x03\xe7ܨ\nZ\x15\x9d'\x9f\x85\xcf\xca͆\x9a\x0f)LӴ\x9b\x1a\xfa\x00\xdf*\xaf՜ͺ\x11\x9a\x01`\r\x92\xd4\xc1$\x16\x05\n4FS\x04/\xf0\xe2\xff\xfc\xee\xcb\xef<\xa6\xf3\xe8\xf0y\x12G]\xf1B娗\x8dk\x1c\x19\xc4Q\xa3\x8e=\xce^⬅\xe5\xc0\xd1t䐞\xb0\x94\xb99\x16]r\xfbK\x9f✻\xce{\xffKl\xf8\xd9\xc11?l4\xe3\b\x95ǯ\xaf\xf1\xd8\xe2\xa8]D6\x85\x10\xee\xbat\xfb\x15\xef,\x8ab\xcb7\xae\xd8.\"\xb2\x86#>\x951\x00dYV3\x12*\xc7N\x86Q\x9b'\x97$H\x9c\xab\x9e\xd3⒤\xaf\x876\x15Eq\xba\xf2\xaf5\x0e\xe6[\xefφCOX\xd6,\x84!P\x86?\xd4\x18\xf1w\x81\xfa\x13,\xd9\xc1\xa8#d\xdd\x01\x00\xef\xfd\xa9G\x1bC\ba-\xf3\xaa\x86.\x1e\vߋ\xb3M\x00\xf0\xf0\x98\xcef`\xed\\\xf5\xd9\"/\x9e\u070f\f\x97J\x12\u0093\x04]|_\r\xa8\xcaPu\xa9(\n\xe4y^\x83*u\x9d\xaa\x91\xe5CLMn\xd6,\x8f!\x9c\xac\xc0>w\xc9Yk+\xb8\x8c!I\x9d\x1f\x9d\xff\xc5\x1an:\x19\x01\x00\xe0w\xef\u007f\xfb\xe9Ƙ\u007f\f!l\xe2\xb5\x1e;\x1d^C\x1c\xa8\xa8L\xd8np\xe0\xa9<\xaan\x12\xfcw\xa1\x88\xdcyՁk?彿\xe6O\x9f\xb9\xe5\a˒\x11ъ\xdax\xd7ݲ\xe1\x04\x11\xf9\x17\x11\xf9\x801f\x94#\a\x1e\x98\xa6\xf7*\x98\x18\x12b\x83\xa5\xdf\xe1\xf7c\xd8@\x1d\x8b\xb5\xe5N_)\x02\xdasm\xe4\xb3\x19\xfcl\x81\xe6X\x13s\ag\xe7\xe6\x0f\xce\xdd\xd0\xefX\x9csg*\xdfqڪ\x8b_\xf9P\xc3\x16\xd7A\x98_}\x8d\x15\n@\xedh\x13&UN\xbd6;^\xfd\xed\xbd\u007f\xe6\x92&\xe8(t\xe9\xf6+^f\x8c\xf9\xb6\x88\xfc\x12G\xf5\f\x9fċ 6>\x1c\xe9ğ\xd7\xf7Y\xa9y\xfe\x81*\x8b\xbb\xceZ\xfb\x91\r_zI\"\x82\x935p\x88\x83\f\x86\vظ\xe8\xb5\xf5\x9aY\x96!\xcf24\x9bM\xcc\xcd\xce\xe2ȑ#8\xf4\xd8c\xcf\xe9K(3x\xb6\x1aw5\xaal\xfc\x95\x8e\x96MƵ\x04\xd6e\x00\xb5\xbf9\x9bS\xe3\xa7\u007f\xeb\xbc\xf7\x88d\x9f~\xb4!\x98\xc7̩U\xd6ֹ\xd7b\xcf]\xd79U\xa3\xcdđ\xbd\xf7\x1e\xe2\xe5y}\xc9p\x89df\xec\xf3u-\x03u\x990\x1fI\x92T\x0f\xf4\x8a\x8d(;\xe1ꨠ\xfb\x8b\xa3:\xda\xc5\xc8\xdf_<\x05@\xd5 \xa1\xcf\xeea\xdd\xd6\a\x8a\x01\xdd.;\xe5_y\x88\xb3E;n\x9f\v\x00o{\xe8]\xa7;\xe7\xbe\xe4\x9c\xdb\xc4\xc1\x15\xaf\x0f\xbe\x9f^Gu\"FC4@\xe0\xb5\xc0\xd7d9Қ\xfaik\xed\xfe\xab\x0e\\\xfbsˑ\x11Ӳ\x1d\xc8\xfa\xdb6\x9d`\xad\xfd\xac\xb5vs< ]\x80* \x15h/\xac\\'\n\xe8\x1aW6`l4\xf4>z\x94\bg3\xbc\xe0;\x8b\xf6\x04\xd9U\xec:\xef\xed\x17\xf6\x15}f\xb3\x19|\xdb\xc3\xe7\xdd\xe8\x93k-\xb13\xe4\xa8M\xef\xa9\xca̐]\x8cѦiZ\xdb\xd1\xceO\xb9\xd3\xcf\xe88\xb8\x96°\xd6Jiӝ\x97\xff\xb7\x10\xc2?\x1bcN\x0e! ˲ZQ\x12\xe8B\x8b\xbaX\x81n\xbb*\xcf+G\x83*\v\x9d\x13\xae\v\xb0NT\x10J\xa7\xae\xe5\x9c\xfb\x8d\xb2\x01\u009f\xc8Ή\xe1\n\xfdn\xbc\x9f\"vP\xf1\"\xeb\x05+.FM4\xd1j\xb5j\x90#G\xba<\x8e8\xc8QC\xad\xf3\xceQ!\xcf+\xcb6v\xd0lH\xf5s\f\xa3\xf43\x96\"t\x9d\xb9\xae\x11>\xccQ\xe7Q\xc7\xc1\xb5E%\xd5\xedŲ\xf1AS\xac\xdfq\xb0\t\xa0f\x94UO\xf5o\x96?G\xdc\xcb!g]Mf\f)\xe9\xcf\xc8\xc8H5\x1f\xbc^\xe2Z\t;\x06\x81\xe0\xad\x0f\xbe\xf3GD\xe4\x8b\x00\xce\u05cc\x93u6\xce^\x01\xd4\xe4\xc0\xf6Ee\x12\aW*?\xcd\xdaX\x16\x91]\x1e1\xc6|\xe2m\x0f\xbd\xeb\x9dW\x1d\xb8v\xd9\x13\xbc,\b뼿\xbd\xf8\x84\x10\xc2g\x8d1\x9b5\xfa\xd2\x01\xa8\xd1\xe3\bA\x05\xa0\x03el\x99\r\x86\xfeVAŞ\x9fa\x156(zo]\xc0E\x91\xc3}'\x81\x97l\xfbޭ;\xfb\x82\xb0\u009cG\xee\xb3\xee\x8e\xe1$\x87\x18\x81q\x06&\xb1\x90F\xa9\x04\x1e\xddT\x9f3\x0f\xfd\xcdΌ\xa3r%6\xb4lP8\x1d\xd5\x05\xa2\x8b\x86\xa3\xb3\x95\xd0\xc6;6\x1bc\xccۍ1ױ\xfc\xd9\xe8\xb3A\xe6q\xe8\xfcőN\f\x85p\xf6\xa4\xf0\x12\x1bc~\x8a#GK\xde\xfbW\x18c\x9e\xa7\x86\x8f\xf9b\xfeب\xe9\xfd\x99g\xa0\v\xb1\xa9\xbe-\x16\x81\xc74ۜ\x85mw\xe7/m4`\x00\xa4\x8d\xf2\xa4]6\x16\xb1\xb3b\xd9\xf1\xd8j\xddPqTj\xed\x02Ǡ\xbf\x19o\uf571.F\x06\xf5\xac\r\xe8\x1a2\x9e\v\x95a\xa3ѨA\x85:\xa6\x18\x8e]-\xd2:&;[\xe5=\xae\xaf\xe98\x92$Y\x00gq\xf3\x861\x06\xde,\xafV\x1c$\xc0\xc0֮\xcd\x0e\x17@m=\xb3l9ˌk\"\xb2&\x9c \x82/Zk/\xe0\x82;_\x9f\xafݫ\x99 \xceF\xf5\xf3\xecP\xb8\x19\x81\x1f\xb7\x1c##\x14$\xbc_D\x9euՁk\xdf|\xc3Y\xef_r\xa7֒\x1dȺ[6\x18\x00\u007f\x1bB\xd8ܫ@\xce\x1e\x98q\xd58Em4\x1a\v\xa2G^xz]\x1d8\x178\xb9Xɓ\xd05&\x06\u0379\xd9`\x8cyO\xbf\xe3\xf2\xde\xd7`#\xf1ݮ1\x00(L^\t=i$\x10\x03\xa4#\t\x8c\xb3\x80\x03\x04\x01I#\x05L\xd7Y2\xae\xad8tlh\xf8iv1\xcc\xc1\x11\xcdJ\x17\xf1e_~\x99\xf3\xde\xff\xb91\xe6\xcdzo\x1dw\x1c\x812\x0f\xfa\x9b\x8b\x8a1\xac\xa4\x9fS~\x19\x96\xe1\xebq$\xcc\xc1\x80R\x9a\xa6g\xab.1\x04\xa4\xf2c\xbeu.\xb8P\xcd\x19\x02;\xc8~#\xd2r\xd1w\xe7\"t\f\x80:=\x00\xb0\x1d\x9e\xd3$\x01\x8cA\x9a$H\x1b\x8dZ۰\xf2\xa7\xe3\xe0\f\x96\x03%6<\fY0\x84\xc5\xdf\xe1\xc8t1\xb2\xa6kh4\x82\xe6f\x868\x10\xd0\xf7\xf5\x01Y\xec\xb08\xf8Y\xad\"\xfa\xf7\xe5>4f\x1b\x18u#h\xd8\x06F\xd0@\xc36`Q\xdf\xf5ρ\x04\xeb%C\xc5l\x87\x96\xbb^\x12\x9b@,j\x01\xa0^OeV\xd5e\xa3\x80\x80\xf5\x9d\x83\x1c\xef=\x92\x93\x92\x9f\x00`c;\xc9\xc11;l\xce.\xb4\xf3\x91\x83(\x9eWv,\xcc7\axlsz\xac\x87_\xf5ޟuՁk\u007f憳\xde?\xb5$y-\xe5\xc3\x1dz\xad\xb5\xf6u\xbc0\xa8կbV\xb1l6\x06\xb1\xc04\xda\xe4E\xc7\xc50\x16v\f\x17\xc5\vK\x17\xbas\x16v\x9f\x83s\xee\xe3{\xb7\xee\xfc\xeeR\x06\xc6\xfc\xb2\xe1\xe1\xc5d\x8cA\x91\x95<\xb7\xb3zWF;\xb4\xe1RW\xeemI\flb\x91\xa1@\xd2H\x90&i\x8dw\x1d\xb7\x16\xdf\xd4\x10\xb2Q\x8c\xeb'쐗J!\x84\xad!\x847\xeb\xffzOv\x1c\xecLx\xaf\x8b\xce-/\x8a8\xa2\xe6T;vF\xfc\x1a\a\x00|\x1d\x86\xc1\x18\xf6\x02\xba]I,#}]\xa4\xdb\xd1\xc4\xd9@\xac\x1b\xfdP\xb9\a!\xad`\x1d\x8e\xda+\x03\xacM\x06\x1dY\xb4;\x90W9\x0e\xc1\xe8\xe8\b\xd2F\xa3ʈ\xe3\xfa\x1f\x1b:\xe6Q\r\x8a\xea \xcf\a;\xec\xb8i`\xc1<K\xa8\xb2\x90\xd8\x11\xa8>iC\x02\a\x0e*W\x96=g\x9f\x85\xac\xce\xe3\a\f\frɑ\xe5Y\xcd!\x88\x0f\x18q\xa3\xa5c)\x1a\x18q\r\x8c\xb8\x11\xf0\xc6}6\x86\xdc\xed\x16BX\xf6\x93\x1e}\xf00R\x87Kk|\x91#\xe1\xa0X\xd7\f\xf3\xa5sٙ\x03\v,\xdcT\xaa\xf3\xc2\xceA\xaf\xad\b\x04\aZ\xac\xcbl\x93b\x1b\xaa|\x18c\xaa\xeeE\xfd\x0e\a[@e\xf7^\x0e\xe0\xd3oy\xe0\x1d/\xff\x93g|\xa0\xef\xc9^\x92\x03\xb9\U000135dc\b\xe0\x83\x1c\x1drD\xc9\x11\xa8\xe2\xab\\3\x88\x05\xcc\xc50\xc6\xe05\xe2\xe3(\x83\x8d\x1d;%ƈK\x81\n|\xd6̍1\u007f\xb4\x94\xb1iZ\x1c\x17Hyc#+\x13\xf3S\x831\x8a\x00\xe3\x05E\xab\x9b=\xb4C\xe7$\xd6\xc4\xc2&\x0ebBg\u007fKRf/\xa6wʮ\x13\xad\xbc\xf5\v\xc5\xc4t\xe9\xf6+^\x1bBxk\f\x0f\xe8\xb5\xd5(\xb1\x93\x88q\xd58\x95g\xc3\xcc\xce$\x8e\xdat\x9e\xab\a(-\xb2dž#`\xcef\x18fS\b\x8c\xe7\x8a#9\xee$c\x9d\x8b3\x9d\xc5(\x86^\xe3\xc5\xca\xd1\xe6bYs\xd6i7\xe6\xef\xb03qIRe-l\xfc8[b\xf9\xf0}\xe3v\xce\xc5(\x86\xcft\xfe\xd8\x11q6\xc8|\xb2\xd3\xe0\xb9_I\xf0r4\n(\x8f\xc9g9\x02\x80q\x16mi#\x0f9\x10\x80\xa2U\xce\xe3H2\x82D\x1cF\\\xf9{M\xba\x16&ԝm\xbf\x19\xe7b\xb4\xd8<\xeb\xff\xdc\xe2\xcd\u0383\xf5\x81۸c8\x9bх8kf\xde\xd9\xd6\xf0\\\xe9{\x1c\x000\xcc\xc7\xef\x8bH\xb51\x13\xa8;=\xe5E\xc7\"\"/M\x92\xe4}\x00\xdeޯ\xac\x96d\x91B\b\xbf/\"O\xd7>\xe9\xcek5\x85\xef\x15\xc5p\xe4\xad\x13\x12{\xc1\x18*ae\x8a\xb3\x126\xdcu\xc1\x19\x98=\x82\x10\xc2_\xec߶\xfb\x81\xa5\x8c\x8d\x05̆\x83\x17-G\x8d\xbd\xc6\x1a\x1b=6\x10\x00 ^P\x14%\x14\x13L\x807]%4\xd6@l\xb9C?i8d!C2\x92 i$5Hl\xa9\xb4\xf1\x8e\xcd\xe7x\xef?\xceВ*\x8e\x1a\xe4\xb8%PǪQT<_q\xf4\x1c;:\x96\x89\xea\x80F@\xaa+1ƫ\xf7\x89\x8d'Ϗb\xcb|\xb4\x03\xeb\x95\xf2\xc4\xd8o\xbf\xce\x03P\xc3Q_\xc4q$\xaf\xaf\xf1b\x8d[:\xbb\xd7\xea~\xbf\xd5jU\x9fU\x03\xa3rԍ\x92\x89s0\xd6VP'\u007f\x9f\xef{4r֕A\x89tk\x92:\aq\x10\x10\xcf9\as\xf1k\x82թ\x83\x88\b\x12\xb7\xb0\xb6\xa6\xe3U^T^ͬ\t\xe7\x1cf\xf2Y\x00@h\x06\x8c4F`\x83Ś\xa4\xdca\x9f\x88\xc3(F\x97ŏ5\v\x83\xa3x~Yf\x1c\fs֢\xaf\xb1\xfcy<\x9c]0\xc2\xc2\xf7c'\x04,\x84\x9bu~\xd9>\xc4\xddZ:߱\x13R\xfd\xe5\xbdA\xde{\xe4y~\xcd\xdb\x1ez\xd7\xdd۞\xfe\xbe\xffӏ\xbc\xfav \xebo\xdbt\x8a\x88\xfcN\b\xdd\x0e\x05V\xe68\x1a\x8f\x175\x80\x9a\xc1b'\xa1\xaf\xe9\xf7\xb8\xb8\xae\x1e\x94\x05\x10\xe3\x93<\x91\xde\xe7Mc\xcc\xfb\xfa\x1d\x97\x92\n_\xef\xc9J\x11Gܽ\xa05\xe6\x81qG.j\xa92h\x94\xcc\x05\xcd\xc4$\bY\x80\xe4\x02\xdf\xec\x18\xc8Y\x8f\xb6\xb4`\x9d\x85X)\xeb-K\xa0K\xb7_1\x12B\xb8\xcd\x18sJ\xafh\x9a\xf9\xe3F\b\x9e[5\xf21T\xa5\xaf\xf1\x9c\xaaSⱱAb\xb8\x92\x9d\x18GM\xcc\x1bGw\xec\x14\xb8\x16\xc3Pg|\x04\fGYK\xa18\vU\x990\xa4\xa1\x9f\xe3L\x9b\xe5\xa9\xf7\x8f`\x82\x05\v:\x84\x80v\xbb\x8d,\xcbj\x91iU\xb0\xb7\x16\x8d4\xc5\xc8\xe8h_\xe3\b\x12\x90\xd8d\x01\xfc\xa1\xc1\x19\xb0p\xad\xc6ccȮ\n\x06V\xe9\xd4#\xc1\xc2n\xbe\x18\xb7\xe7\xe3M\xb8+Nǒ\x17y'\xd3oW\xef\aY^\x16R\x84\x02\x89\xe9\xc2=q\x00\xc1\xeb\x83\x1d{\x8c\x1e\x18ӭS\xb0\xbdT=\xe1.2\xce\xca\xf5Z\x9cU\xf7ʂbć\x9dZ%\xdb\bA`\x9e\x94\xf4\x9e\x8c*y\xef?\xfe;?\xb8fߟ\x9d\xb3\xf5\x98\xa7x\xf4m\x91B\b\xaf6\xc644\xe2\x03\xba]$\xb5\vR\x04\x1b\x1b*\x8ehY\x00|\x92\xa9~\x87\r\xb3\x16Pوk4\xdà\x04\xb2\xab\x80\x88ܴ\xef\xfa]\x8f\xf6;.%^h쨀n\xbb\\\xec\f\x81z\xbb\xa9\xf6\x80\xb3\x81\xd1\xdf\x1c]k\xb4\xce\x11\x85*\x81*\x8f\xde\xd7\x18\x03_x\x84,\xa0=\xd3ZҘB\b۬\xb5\xeb\xd9\xe8뜩\xfcT\xa9\x95\xa7\xce\xf7J\xb8%\xc2^\xd9X\xb3\\\x18\xd7ey\xb0\xc1R\xa3ʑ\xa6\xfe\xcf\xc1F/Y\xf4\x8a\xc2\xf9\xfa<\x8ex\xb1\xf5\x03\xf9\x90\xbcj\xf3\xa7\xf2\xd2 G\xef\xcf\xfc\xa8q\xe09\xe3\xf9挛\r\x1f\xcf3;%5,\xedv\x1b\xedv\x1bE\x9ecvv\x16c\x87\x0f\xe3\xc8\xf88\xc6\x0e\x1f\xbd\xa9\xd0\xc0T5\x1c\xbd\x8f\x06.\x9c\xadŲd\b%\xce\xc0\x96ꀗBڅ\xd5\r\x00\xeb{(\xf4=\xae\x19\xea\xeb\xb1-\xaa\xe9\xc42k \x9a\x81(\x0f\xb1\xcd\x01\xba\x8e\x8du\x8ek\xc0\xaaì\a,\u007f\xce>\xe3\f\x9e\xff\xe6\xe0\x87u:\x86\xbf\u2004\xbf\xc7m\xc8\xec<8\x1bQ\xb9+\xefI\x92\x9c\xd4h4>\xf5\xd6\a\xdfY\x1d\x9c\xba\xa8\xbc\xfa\x16\xac\xb5\xff56p,L\xf6b\f-p\xe7\x14;\t\x15\nO\x969b`\xef\xb70\xdf5\x90\x83\x02\xe4\xa5qp֡\xf0\x05\f\xea\xfb,\xf4\x1e!\x04X\x18\xc0`\xc6Z\xbb\xa5\xdf11qD\x11\xa7\xf9l\xe0t\x12y\xf3\x95*\x89\xee\xf1P\x19\xf1be\bI\xa4[\xf8\xe5hC\xf7X\xc40\x8e^g)5\x90u\xb7lx~\xf3\xb1\xf9+[cM\xe4\xd39\x8a\xd9\x1c\xf9\\\x06\x9fy\x14y}\x13\x14G6\xca'oN\xd2\xf9\x8d\xb3K>f!\x86\xbe8\x83aGɑ\x9c\x12à*c\x95g\xec\x00\x18\xc2d\x18!\xee4\x02\xea\xb8x?\xc4Δyb\xa7\xaf\xc4u\x025\nl\x10b\xe8\x8c\xf9fc\xc1k\x06@\xed\b\x16\xbd\a\x1b*{\x8c,tR&\x91\xb5\xdbh\xb5Z\xb5\xd6V\x8e\x909ӎ\x1d\n\xebB/\x872h\nR?\xa5\x98\x91\t\xce:9\x82gx\x8dad\x1d\xebJ \xb7\t;\x8d\xe9|\xa6\x84\x97!5C\xcb끃b\xfd\x9f\rr\xec\x84y\x9d\xf3g9\x00\xe9U\xbb㌆\xe5\xc0\x8e\x8d3\xf58\xe3\xe0u\x117pp\xf0\xa0\xfa\vTs\u007f.\x80\xdf:\x96\xbc\xfa\xb2H\x17ݺ\xf1\xe4\x10\xc2+bE\x8a\x0f\u038b\xa3O\x16(\x1bPUhk,쌅\xbf?C\xde\x19|\x86N+r\x13\xc8\x1e\xcdj\x8bߍ\x8e\x00ϯwߔ\x03\a\xb2\x1d-\xb8\xc4ݸ\xfb\x03\xf7.\xf9$^\xa0\x9e\xee\xc5\xce\t\xe8\x16:u\xbc\xac(\xdc\x06\xa9r\x88k\x16z\x1d\xc679b\xe04W\xefυN\xe6\xa5Oz\x97\x811\xf0\x80\xcf\n\x14\x1d\x05\xca\xe7\xcbM\x83\x995\x80\x05\x92F\x8a\f\x19\x8c\x05\x92\x91\xb4\xdc\xf7b{w\x84\xb01W\xa5f\\=^\xf8ʷ~\x9e\xd3d\x95\x13\xcb2ލ\xcdƔ\xa1\v\xbd\x06\xef9\x8a\xb3>\x95a\xbb\xdd\xee\xbb\x0eR~\xa7,\x84s\xc1_\xbf\xaf\xfa\x16w\x83\x01ug\xa5\x06\x83\x8b\xcf<\x8f\x1c1\xea}\xd9A\xab\x03\xe7V\xf0\n\xfe;\x86]l\xa3\x85\xf6T\xab\xbav\x95\x05w\x8ew1\x1dc\xa1H\x00\xeb!\x93ʕ1\xf8\xd5 m;Vy\xb3}`\x99\xa9\xbeq\xc0\t\xd4\xe1\xb7\x1a\f\x14\x96W\xf4?\"G`2\x83\xd0*\xbb\xd9\x12\x93`\xc46\x90\x9a\x14'\xad9\x11N\x12$fak8\xaf\x95\xd89Ď\x99ǡ\xd0\x1cg5@\xfd\xa0\xc6^'_\xc4:\xa3\xf7f^\x18q\x88\xed\x98ΫfwJ\xfa\xb9\xce\xf7\xaey\xeb\x83\xef\xfc\xf0\x8dg_\xb7\xe8c3\xfb\xd2\f\x11\xd9\f`\x84\x99ӿ\x999UH.\x14\xf1\x02\x04\xba\xa7\x97Zk\x81q \u007f\xa8U\xf3\xa0\fﰑ\xca\xf3\x1c\xf3\xf330\xf7t0\xe5'\x8dB\x9e\"\U0003e034\x00\x81\x1c\xf1\xde/zJ鱈\x17;G\x87:\xae8\xfa\x88!\x13n#Աp\xd6@\x9d\x0e\vڛY\xe9z\xc1\nq\x14r,:\xefo/\xfe1k\xed\x1bC\b\xd5\xfe\x93\x98o\xef=\x9cq(\x9aye\xec\x9a\xd3\xf3\xa5l\xd3\x14\xc1\x04\xb8\xd4\x01\xae<g\xcc&\x0e\xc1\x04X\xd7M\xcf{\x9d\x89\xc50P\xaf\xc8]eƊ\xcaΘ#>}\x9f\x95<\x96\x0fG\x82\xca\a\xcbs)Et\xcel\xd8H1_\x1c\xd5)\xf1\xdf\x1c|\xb0\xb3\xe3\xcc5\xce\xce9\x10\x89\x9dp\x9c\xd9\xf4C\xb1cף7ڨפ\x9cs\x801H\x9cC\xa3\xb3\xbb\x9aO\x86й5Ƭj\x11\xddXS\v\x16t\f\xb13\xd1יB\b\xb5\xf5\xa4\xd7\\.\x05\t\xd51\xf7֕\x0f\xfc\x9a\v\xf3\b!`\x06\xb3\xe5zr)R\x93bԍ`4\x19E\x02\x87\xd1dtA\xd6\x1aג8\xe8\x89\r;\xeb\n\a\x12\x9c\x95T\xf2\"{\xa0?\xbc\x0e8\x88\xe2\xe0\x80\xef\x05\xd4\xf7\xaa\x00\xf5\xb5\xd9y\xed\x89Ƙ\xdf\x02p\xfdb\xf2\xea7\xb48\x9b\x17\xbc\xfe\xcd\a\t*\x03\x9c\xaa+C\xea\xed\x14\x9b-'\xdc\xc3?\x9c\xeb\x80\xe7\x00\xdcf\xad\xdd\x0f\xe0a\xef\xfd\x9c1\xe6\x19\xd6\xdasB\b\xe7x\xef\xcf\x01pN\x92$k\xd5@e\x8f5a\x0e\x19\xb8\xa4\x01_\x1e߰e\xef֝\xd3}\x8eg\x01ѱ\x1a\xd5k\xf1\"g\xa3\xa5\v\x9c\x8d\x03\xe3\xf9l\x84\xb8x\xacΐ\xfb\xfd\xd9X\xb2\"\xb0\x01\xd1\xeb\xf7Ci\x9a^뽷|\x1dU8\x95_|\b$\x1b\xdbv\xbb\x8d\xd1\xd1QH&\x10\t\xc8M@\b\xedr\x01x\x0f\xe3\x00\xa7N\xc5y\xd8\xc4\xc15\xea\r\a\f\x05ŝ)q\xed\x82\x17^\x9c\xd1\xe8\xf7x!p$\xcfNQI\x8b\xee\xf1\x82<\x16\xc5\x19\x13\x1b/\x86\xe4bh\x89u\x9e\x8b\xd71\xe4\xc2FB\xff\xe7{\xb3\xfcb\x98\xc2ڲX\x9f\xb8\xa3/Yk\xcag\xebą\xd9^\xf7\xaa`\xb3\x100??_s\xba\xba\x939I\x92\xf2(\xfdU*\xa2'6A\xb0ݵ\xc5G\x1c\xf11+1D\xa4\xef7\x1a\x8d\xdasb\xaa\xf1\xd9\xe5\xf1\xab\xf6*\x0e\"X\xd7\x02\x02\xda\xd2F3k\xc2\xe4]\xe7ް)\x9c8\x9c8z\"\x1a&E\xea\x1b\x18I\x1a\xb5\xb9d{\xc0\xaf\xc5YW<\xff\xfc\xd9\x18-\xe1@\x9b\xd7Y\xacwq\xbb\xb8~\x8e\xf5\x8e\xe1\xce\xce\xf5\xaf\xb9\xfa\xe1\xdf\xfb\xf0\xf5O{\xefl\xcf\xf9\xebS\xa8O\xe5\x88*\x16\x04/\xa8\x18\x8b\xe3\xc5\xcf\xe9;\xba\x86\xe1\xdd!\x84?\u07fbu\xe7Qw@>\xffm\xe7\x1b\xef\xfd\xc5\x00~\xcd9\xf7\xf3\x00N4\xc6 +2\x98\xf2q\xaa7\xf73\x96\xc5H\x05\x1e\x1b-.:1N\xa9\xef1\xac\x15w\x14\xf1\xb8{e\x141T\xa6\x0e\x83\r0˶\x1f\a\xb2\xee\x96\r\xcf.\x8a\xe2\x17\x14\x12`#\xad{\x11b\xa7\xc6FK\xff\xaf\xed\xbe\xa6\x88\xd9\x1a\x03\xf1\xe5\xf5\x8a&\xef\xeb\x11\xb8\xc4\xc2\xcd8ȴ i\xa5\x90\x86\xc0\x9dl\x11N\x15\xc8\xe9\xf5c=\xd8\x01\xf0}8\xf3d\xe3\x1fˏ\xe7\xc1{_A\x01\xfc\xb9\xd8(\x1d\x8b\xe2l\xa7\u05f58c\x8a\x1d\x8bf\x97\xedv\xbb6\xa7\xfa\xf98\x1b\x8a3\x918\n\xe5\xeb\xf7\v%\x05\t0\xd25&\xfa\xdd^\xf2fc\x19;\xb5,\xcbjYA\xbf\xc1\xcbRi\xb1\xf5\xc0\xddX\x9c\t\xda\x0e\x04\xc7ϥQY\xc7\xd9\xcarȚ\xf2\x84\xef\xb8~\xc6s\xc8\u007f\xab\xfe\x19c\xd0*\xcayo\xb5\xda]\x1e\x04\x18q#\x18u#\x18q#p\xc1bM\xba\xa6*֫\xdc\xf5\u07b2W0\xfb\xc8$\x0eO\x1f\xc6\xc4\xdc\x04N^{2N[{\x1a\x9e\xf0\x84'A~\f0\xa7\t\x80\xfaI\x10\xf1\x01\xacl\x878P\x88\x1b7X\x1fx\x1cQv\u007fz\b\xe1\xb7\x00l\xed%\xaf\xbe\x1cH\ba\x1d\x1f.\xc8Q\xa2\n\x8a\xbb\x06b\xc3ʌFQ\xe1\x9b\xf7n\xdd\xf9\x91~xؿm\xb7\x00\xf8\x16\x80o=\xef\xaa\xf3\xaeJ\x92\xe4\rEQ\xfc\x9asn#\x80\xf7\xedݺs\x13L\x85Z\x00\x00 \x00IDATQ\x9c\xae\x1f\x12\x91\xc7\xd0ɴXQX\x818\xaa\xecȥ\x06\xb7\xe9x\xe3̂\x9dO\x05I\x84z\xd6\xc6\xf0\x0f\x1bR\xbd\x8e\xb5\x16&7\x0f\x1ek\x1c!\x84\xff\x91\xa6\xa9\x8b#g.H\x16E\x81\x91\x91\x91\x05N$v\x90l88\x10\xe8f\a\x801\x16\xd8\aH\x96\xa1\x00\xd0\xee|\xbf\xa50գ]\x03\xb0fd\r\xec\xba\x14f\xd4 7\x02\x97\x96\x9b)]RO\xf5\xe3(p1lWI\x95?N\xeb\xe3(\xf2Xd\x0f\xe0\a~\x8d\x87\x85\xed\xb6\xc3v\xb0t{\x8aE\xb2\xb6[\xd7b,Y\xe7Qe\xcb\xc5\xff\x98Oկ*0\x00 \x87\x05b\x050\xa8\ueb5f/|\x81\xc4&Hl\xa7C.\v\x8f\x1cm\f\v\xe7\xa8^\xb0\xe7Z\x92\xaee\x8d\xe0\x95\u007f\xfdN\xecHW\x83\xbcxHQ\xdfx\a,\xd4\xc7ة\xc6c\u2d7a\x12\a\"(\x9f3\xc4P\x1fP߸\xd7+\xa3e\xfb\xa0<h&\x9c#GVd\xf0\xed\xc9\xf2\x1a\xb9\x85\x15\x83\xd1ξ\x95\xc6\xe1\x06\xee\xbf\xf3\xfb88y\x10@=\x83\x1e\x9b\x1dG\b\xf7\xc1\xdco\x80{\x80F\xd2\xc0\xe6\xf3^\x06\xd9X\x87\xa48Љ!W\x1e\a\xdb\xec8)\xd0\xf5\xce\x1d\xa2\x9d\xdfo{\xeb\x83\xef\xbc\xe1Ƴ\xaf[\x10E\xf4\xe5@\xd24}:+\x13G]\xbc\xa8\xf5\x86\x1c\xcdsT\x11}WҋF\x8fi\x10{ѷo\xd83\v\xe0c\x00>v\xde\xdb/<\xb7(\x8a\xef/\xe7:L\xb2\xbb\x98j\xfbv\xa5\x9c\xb9\xe4\xd5\x18\x1b\x17\xadY\x00]\xb0q\xe7l\x84?\xa7\xc4\xd9L\x95\x99H@~o\v\x85iW\x8b\x9ea\x97\xaaK\v\x1d\xf8\xa24Tc}\f\xe5\xff\x8a7/\xb1\xc3\x0f!\xd4\x1e\x19\x1a+\x1e\xd7r\x80\xfa\xde\x16\x0e\x0e\xac\xb5\xc0\xb7\r\xdas\xf3\xb5\xb1\xc5Ε\xafU\x84\x02\xfe[m\x8c4F\xe1_ (\x00X\x9b\xc3X\x83\x00\xe9<\xd3\xc5T\xe7\x8c\xe9\xfd\x95T\xb9C\xa8\x9f0\xab\xbc\xeb|pd\b\xd4O|>\x1a\x8d\xef:t(~ι1%>\xffħ\x9f\x89\xb0\xbe^\x13ӌ#\x8e\xe4E\xba]v*\v]\x13\v\"\xe4Y\xc1\xdc=S\v2\x0e\xa0\x9e\x19\xd2<\x1c\xf3\xd9\xf2\xbd\xe6+\x0e\x804r\x8d\xbbo\xe2\xe6\x00\x86oW\x83\xac)\x1fi\xadM\x03l3\x14\xaa\xe2`(6xq\x10\xa4\xf3\xce\xebo\xa9\xfc\xe8\xf5\xf9d\x04\xa0\xde\b\x02,<\vK\xf9\x8d\x83!\xa0~rn\b\x01\x85\x04̴gP\xfcS\x13\x0fO<R\xcbBU\x0e:nn.)B\x81\u007f\xdb\xf5\x054\xf6\xa6\xd8\xfc\xe2\x97#\u007fn\tk\xc6k\x80\x9d\xa9\xb6\x86\xc7Y\xbb\x8e\x91!5\x0e4u\r\x17E\xf1D\x11y\x11\x80\xbbby\xf5\xe5@|\xe7aK\x8c\xef\xeaMx\xb0\x1c\x19\xe8\xe4r\x11Y\x17X\xc7p\x19\x11\xf9Njn\xdd\xf8~\x11\xf9\x9f;\xdex\xf7\xb2\x1en\xb2gˎ\xbd\xcb\xf9^L\xb1\x17\xe6E\x96F\xe3\x02\x16n\xc6b\xc5b\xa7\xa22\x887\x97\xe9\xc4j\x94\xc5\v\x9a#\x88\xf8(\xee\xa3Q穐ϊ\xb3 6L\xbd\x1c\xbe*\x12\x13+?;\x02U\xaa\xec\x9ef732\x06Y\x96M5\x1a\x8d\u007f\t!|GD\x1e\xb3֎\x018\x19\xc0\x19\xd6\xdasD\xe4\x15\"r\xa6\xb5\x16\xed\xac\x05\xff\xef\x1e\x8ds\xd7 \x8c\x06XXH\bȋ.\x9e[\x98\xb2\xb8\x1f$`\xcd\tk\x11\xc4\x03\x0e\bi\x80\x18)k0\xae~f\x16\xf3\xc8c\xed\x17\xc2\xd2E\xa8\xdfW}M\xd3\x14y\x91\xc3\xf8\x85G\xccsp\x10\xb7a*/\x9c\xc9\xc5s\xc9\x0e:\x86\x13⌁\xe1\xb5\xc5\xc8\x1a[:d2\x021\x9c\xc6\x06&>\xf3\xacW\xa6\xa9\xb2X\r\x9a\x9c\x99@\xdah 錳\xd1hԜ\x85ޛ\xdb]{5\x1ep\xc0`m\xe7As\xcb \x03S\xc9O\x83\x00\x95E<\x8f\xcc\x17\xeb`\x1c\x80\xe9g\x81n\x9b\xbb-,\x1e\xbe\xedAdEV]\xdf{\xdf6\xc6|\x11\xc0N\x00\a\x8d1\x87\x92$9)\x84pf\b\xe1l\x00\xaf(\x8a\xe2i\xce9̷\x9b\xf8ܿ\xfd#6=\xb8\x11\xa7\xbd\xf2\x89\v\xe0]\xa58\x90\xe7\xc0\x92\x031\xb6]\xac'\x94\xad\xbe\x12\xcbu \xd6Z\u1cca\x989\xfe_\x15<\xc6\xfc\xf9}\x8e\xa6\x00\xa4!\x84\xf7Xk\xdfs\xe1'/\xf9\x9a\xf7\xfe\xd3\xd6گ9\xe7\xee\xbd\xe7\r_o\xf7\xc3\xdb\x00\xe9\xd3\xd6\xda{\x98?U\xe8 \xe1g\xc4ˉ\xdc\b\xa0\xe3S\xc5\xe0\x85ȑ\xa6N\x82\x8e_\x15>\xcb2\xc0\xfb\xbf\xd6ϳs\xe2\x8c\x00\x00\xff\xfe\xe1\xd1\x06\xd01\xd2\xd5\xf7\x19\ag\x83\xc7\v!\xc6K9\xc2c\xe7\xc3\xd7i\xff\xfb<;\xa4\u007f\f!\xfcY\x9a\xa6_\xdd\xfd\x81{\x17=\x0e\xfa\x05W_`\x8d1\x17\x89ț\x00\xfc?\x8dF\xc3\x16\xfb۰\xcfJaO\xab\x9f\xe4˼8㐷\xb2n\xf6\xd1,wl{u\xf4\xa9\x83Mlْ<\x92\" \xc0\xb8\xf2 K6\x84\xfd\x90\xb5\xf6\x01\x00\u007f\xcd\x1b\xba\xaa\xc0`\x14O\xb7־\x8c?ϲ\xe4\xec\xabs\xad\xea5\xdeD\xc9F\x10\x00|\xc3?\x92$ɿ\xb2\xc1\xe6\x00&\x0e\x04\xac\xb5GͶ\x83t\x1b/b\xf8By\x8e\xbb\xf2\xf8>\xcc?\x1bN\xad\x87\f\x9a\x8a\xa2\xa8\xae\xcd\x10\xb9\xb5\xb6z\xa2\xe4\xc8\xe8h\xcdA\xebZ\xd3q\xb1\\\x81\x0e\xe4f\x96\xef\xf0z\xed\xd6\x06\xba\xeb\x97\xd7:\xaf+\xbdw\xecp8\xb2\xd7\xf7\xee\xfb\xc4w\xd8h\xef\xb2־\xcf\x18\xf3\xcf{\xb7\xee\xecY\xac\x06\x80s\xafYg\x00\xac\x0f!\xfc*\x80_\xb7ֺo\xdc\xf7M<\xf3\xd6g\xe0\xa9?}6F\x935H\b~cb=T\xddR=Q(6\xee\x1a\xd3\xf1td\xf1\n\x00\xbf\x1f\xf3\xd4\xd7\xcaZwˆ\x87\x8c1OS\xc5\xe7\xc8\x15\xa8ciJ,HU~\x8e(8\xda\xe2\xcfu~\xda\xd6\xda\u007f7\xc6|\xcd\x18\xf3U\x00_\xb9\xf7g\xef\x9a\xec\x87\xd7\u0560u\xb7lx \x84pv\x8c\xbb\x02\va<v\x9cq\x96\xc2\x11\xb2s\x0e;\xdex\xf7@[[\xce\xff\xbb\x17~.I\x92W\xe9\xd1\x0f\xbcّ\xe1\x10\xee c#\xc2Q\x12\xc3j\xaa\\>x\x84\x9d\xb9\xbew/\x80\xff\xbew\xebί/\x95\xcfs\xafY\xf7\\\x00\u007f\xe2\xcbg\x80 \xbdh\xb4v?\xa0\xdejȼǭ\x86\xec\xccu\x9c\xea\xfc\x93F\x02\x97:\x04\x84\xfb\xefy\xdd\xd7\xcfY\x89l/\xb9c\U000eb735\x9f\x8b\x03(\xe65>(\x12Xx\xb2\x01\xe3\xe4\x9dk}\xfe\xae\xcdw\xbcj%\xbc1m\xbc}\xf3\x06\x81\xdc\xcd\x06N\xf9`\u074c3R^\x9f*\xdb\xc8\xe8}\xe5\xae\xcdw\xfc\xf8\xa0\xf8\xac\xf8\xbdc\xf3W\x00\\\x06ԍ\x1c\xd0-\xdesc\t\x004FF\xe0:\x0e\xc69Wk\xa0\xa8 \xa3G\xfd\x8b\xfe\xe9e\u007f\xff\xad\xa5\xf2\xf3\xda/\xbf\xf1\xe7\xfdi\xfe\xef\xe2\x93\"Ա\xc7u9\x8e\xfc9#\x8a3N\xed\xbeL\x9c\xc3\xc4\xdf\x1f\xc2\xd8\xcc8Dd\f\xc0[\x01\xfcݾ\xebw-\ts;\xef\xed\x17\xfeX\x9e\xe7۬\xb5?\x99\xa6)\xce>\xe7\xd9\xc0\xc62\x03]\x93\xaeAäH\x90\xe0\x84\x91\xb5H\x90T\x0fʊ\x91\r\xd5\xe7\xf8\xa8\x1d\xe6\xbd3n\x11\x91'\xdfx\xf6u\xb5\xa3\x10\xfa\xca@\x8a\xb1\xdc\xd9\xd4\xc1%\x16y\xc8J\x8c\xbaQ>\x0f\xc1\xa6\xbd\x1f\xb2\xa2\xc2\xe5\xf4\x8d\x17X\x1c\xa9s1\xdaZ;\"\"\x97\x02\xb8\x14\xc05!\x84p\xe1'/\xd9a\x8c\xb9\xc3{\xff\xc5$I\xbet\xcf\x1b\xbe\xbe:\xe7K\xf7 N\x9b\xd9K\xf3\u0600\x85\x9dB\x1c\xb9\xb3\xf1\xeb7\"^\n\xad\xbbeè\x88\\\xaeF*>\x17\x8ayV\xe5\xd1n!\x8e\xac8:\xd518\xe7 A\xe0\x1ep\b\xc8\x11B\xf8$\x80_ٻugs9\xbc\xeeݺ\xf3;/\xb8\xfa\x82W\xa5i\xfaޢ(ޙ~7Ex\x81,\x88\xee\x80z\x17\x89\xc2|\x9c\xc9q\xf4\x17\xc3O\b\x80o\x0f\xb6{\x88#\xe1\xcaQQw\x14\x1b^\x86\x14T\xce*\xd7x\x9c\x83\"\x1f|\x951pF̺Ɏ,\xc6\xdbـ\xf0I\x05\xab\xa1\xb3@\xbdê\x96A\x90#ֶw\x85\x94\xe6\xe7\xe6\x16ԕ\xd24\xad2\x16\xeb\xeaOv\\*\xc5ȉ\xbe\x06\xd4\v\xdc\xcaw\x1c\xbc\xf0\xbcs\x94o\x8cA\xb1\xc3\xe3\xf0\xf4\x18\x00\xec\xb7־zϖ\x1d˅\xee\xbf{\xee5\xeb^\x13Bx{\x9e\xe7\xef\xbf\xef{\xdf1\xcf|\xc6s`\x9ff1\x97\xcfa\x0e\x9d\xe0%+\xe7.\x81\xc3\xda\xc6Z\x18o\xb0&Y\x83\x86m 5ݓ/t\\\\\xf3b\x94ED\f\x80\x9f\x00\xf0\xb7\xccG\xbf\x10\xd6!)\u0099E\xd1I\xcdL\xf9\xa0%k-\xf2\xd0ٍ\xee,`\r`\x046\xb1𡀷\x82\xa4\x91 \x0f\x19\x8c\xb3p\x89[ p\x15:\xd7K\x00\xc4\x03\xb3!\x84\xf5\x00\xd6[k\xdf\xe6\xbd\xffᅟ\xbc䯭\xb5\x1f\xbb\xe7\r__\xd6\x04,\x858\xd2\xe4\xc8\x02X\xd8T\xa0)8G\xf1\xbd2\x96Uh\x8b\\o\x8cY\x13Ä\xcag|\u007f\x91\xf2ќ\xcaG\x1c\xdd\xc7\x06R \xc8'Z\x00\xf0Qc̛\xf7lٱ\xa2\xaaj'\xe2\xba\xf6\x05W_p\xb8՜\xbb192\x82\xe4G\xba\xcf@\xe9\x05\xbf\xb0AT\a\xc9\xd0\n;hu6\x83\xc2\xeeCV\xc0\x8d4\xca\xe7E\x90l\xd9@p+\xae\x8e\x01\xe8vlqƽZ5\x85\xc4&%\x84\x17e\xc1\fEi\xa1W\xf9֮<\x0e>x<1\xba0HR\a\x10\a\x93܂\xce2\x8b\x1d\x87\xfe_\x14\x05\x8c\xf7ȳ\xb2\xa6\xb0\xdc\xc3\x14My$Rm}\xb3c\xd3{ǻ\xccYה\xb7\x05\xad\xe5\x85\xe0?v~\x1b\"\xb2\xd7Z{ٞ-;\x96\xf4\xf0\xa6\x98\xf6n\xdd)\x00>\xf0\x82\xab/\xf8\x1e\x80\xff=\xfeՃ\xf6\xf47<\x05 \xa7\xaf\xf7\xce|\x8e\"\x9b\x81\xb5\x16\xd3\xd9L\x05\xf3\x8d&\xa3\xd5\xf1\xf8#R>sŠ\v\xbf1Ҕ\xa6\xe9\xcb\x109\x90\xfe\xb4x\x12?\x88\xa3\xe9\x18+\x97 \x80\x17\xa0\x00\xa4\x15`\xda\x06\xa6\t\x14\x939\xc2T\x00\xa6\x04\xd9X\x1b\x98\x11\x84\x19\x8f0\x17 ̀\xd0\x0e0\xa1|\x8e\x86FMq\xe4\x16\xb5\x94\xc1\x18\xf3\x14c̻B\b\xf7\xad\xbbeç.\xf8ċV\x04O\xf4C\x12M\nP\xaf\x19\x18czv`0\x14\xc3\xceg\xd0\xc7C8\xe7\x9e\x12;5vn\xba\x1b\xb9\xd7{\\h\xe3\b\x8aq\xdc\xfc\xde\x16B\b\xdf\a\xf0֕:\x8f\x88\xfeLDn\xcf\xefkU\x06A\x8d\x1a/\\\xfd\xcd\xf0'\xd0ť\xe3z\x1c\xd0=\x98\xb0\xdf\"\xfa\xd1(\x9f\xc81\xf7\xe8,\xdac-\xb4\xc6[\xc8&\xdb\xf0\xf3\x05B;\xa0\xc8\nXS\x1a\xe78\x92\x0eT\x8c5\xc6T\u007f\xc7m\xa2\x83\"\xc1\xc2V\xce8\xa2\xe4s\xe9⚘\xfe\xd6bv\xbcwe\xd0\xc4Y\x8e\xeb@R\xf1<\xf3\xf1\xf6\xbc\xc6\xf8D[\xd5\x1dθ\x96C*?\xa0\xde\xf0\xa2sƐ\xae\xbe\xa6\x9f\x05\xeag\xc1\xe9\x9a\x0f!\x00\"8\xf2\xa9\xc7\x00\xc0\x1bc~\xf9X\xfbޖB\xfb\xae\xdf\xf5\x0fƘ\xab\xa7\xe6\xa6`\x1eDup#CPlSU\xbey\x91c>\x9f\xc7T>\x8dC\xad\xc3x\xb8\xf9C\xfc`\xee\x01<8\u007f\x00\x0f\xcf\xfd\x10\x13\xf9$f\x8b9\x14R\x05kό\xef\xdd\xdf>\x90\xa9\xe2\x11s\xca\xc2\xed\xf11\xfe\\1\x16=\x13\xa2\x8a\x10\x8cAy6S\xe7\x99١\xfe\xb8Mk-2\xdb.+3\xa9@\f\x80\xce32|Qb\xdaA\xbaim'B\xfa)\x11\xf9\xc9\v?yɍƘ\xf7\xdd\xfb\xb3w-Z\x84Z\t1\xf6\xa9\v.\xce4\xd8q\xc4\x10\x10G\xa0*\xc7A\x92\xf7\xfe\f\x00\v\x8c\xbf\xb5\xb6z\"\x19g\x17\xfaY\x8e\xb08b\x06\xea\x05v\x00\xd2Q\xfc\xf9A\xf2\xbd\xef\xfa]\xe1\xdck\xd6\xfd\xaa\xf7~\x8f\x8cɉɓ\xbb'\x02\xf3x\xb8\x1dUy\x8d\xeb\x11\f\xdb\xe9\xe7uѯ\x94*l=\xa7\xfd9\x99Ԝ\x80\xb1\x06\x85\xcba\x9c\xed\xec\xd6O\x00\vؤ\xcb+w\x10\xc5m\u0383\xa0 \x01\x89I*}ձs{n\fm\xb1\xacX\xa6\xab\xa9\xaf\x15\xbf\xa1{\xaa\x03\xbf\xc6\x193;9~\x82';DδJ\x94dy\x8eyL\x0e!\x9dj\x00Ơ\x91\xa6\xd5q\xfa@y\x9e\x18?͑\x9f\x84\xb9\xe0\xfe\x84\xaeXk!90>;\x0ec\xcc\xfb\xf7]\xbf랕\xc8l\x11\xfa\x13\x00\x1bZ\xbbf\xdep\xc29\xa7\xd6\xd6y\f\t\x03X`\xbf\x19\xfa͊\x1c\x19r\xcc\xe6\xb35\b{č<#\xbei_R\x16\x91\x1d\f\x85(s\x8c\x8b.\xe8oG\xbdUT\xbf\xab\f\xf3\xf5\x18\x9f7b \x85 \xb4\x02\xb2\xe96\xfc\xacG6ц\x99\x05\xf2\xb1\f\xf9X\x86l<\x83\x99\x03\xc2l\x80\x9f\xf3\x90vhH.\xef\xf0Yq\xf7\xfa[7-\x18\xe4\xa0(v\x14,\a\x8ez\x18\x93W٬\xe6\x81t\x1d:\x8f\xe5˽\xf0\f\xa1\x00\xf5MQ\\\xd4U\x9e+c\xa9\x06\xfb?\x00k\xed\r\xfb\xaeߵ\xe4\x82y?\xb4w\xeb\xce\a\xd24}\x9b?\x90Ղ\tVr\x86\f\xe2n'\x86\x10\xb8%Zuu\x10p!/\xb0\xb8\x9e\xa1<\x06\x1f`\xbc\x81\xb4\x03\x8a\xd9\x02\xd9d\x1b\xed\xf1\x16\xe6\x0f\xce#\x1bk\xa3}\xa4\x05?\xeb\x11\xe6}\xe9|2\x8f\xd5(-\xb0a\xe0z\rg$\x8c \xf0\xff\x9cݱQ\\-\xfd\xe5H\x9e\xb3\xca8\x8b\xeb\xb5\xee\x16\x1b{\ba\xd9gw\x85PvH\x16y\x8e\x99\x99\x19LMN\xe2\xf0\xe1\xc3\x18\x1f\x1f\xc7\xf8\xd8\x18\xe6\xe6\xe6\xd0j6\xd1lv\xcb\u007f,K\xe6\xaf&\xd7\xdd\x01\"\xb2[D\u07bb,ƎA{\xb7\xee\x94$I\xde\xfe\xf0\xf8\xc3y\xe1\xbb\xcd3\x9c\xa1\x01X`\u007f\xe3̝\xeb\xbd\xfa\xfd\xf2\x0f\xa0\x1d\xdaO\x8a\xefۗ\x03\xb1\xd6\xde.\a< \xf5g0\xf0b\xe2\xe2\vG.\xcc\x04G\x90\xfa9\xceV\xd8\x003\xdeXSd\x97\xc0\x04 d\x01\xc8\x04a\xde\xc3\xcfx\xf8\xa9\x02\xf9\x91\xfc\x05\xf9X\xf6\x8d\xf3n^\xbf\xb1/\xa9\xf7I\x9cy\xc4P^\x1c\x05\xf7\x1a\xffb\x10р\xe9\x19\xfa\a+\t/<\x95\xbf\xf2\xa1P\x11;AV8k-\x8c\xb5ȧ[\xff!\"\xef\x1e4\xc3L\"\xf2\x17ƚ/\x15yQ\xd31\xe5\x83[ku\f\xbcHԩ\xe8g5p\x19T\xbd!\xdep\xa7FO#`\xe5\x83k/\xb5\xe0\"\x94\xf0n6\xdbF{\xba\x8d֑&\xb2#m\xcc<<\xb3bޘ\xac\xa9\xc3Q\xf1\xdabb\xf8\x8f\xa1b\xa0\xfe\x1c\x89A9\xe1\xc5HDj\xcf0\x01\xba\x8e\x9a\xe5Νm\xca\u007f\xac\xe7U\xa6\xbf\x82\xb3\xbb\x18\xf6\x8c\xed[\xbb\xd5\xc2\xcc\xcc\f\xa6\xa7\xa60v\xf80\x0e\x1f:\x84Ç\x0eaff\x06s\xb3\xb3h6\x9b\xb5S\x85\x95\xc7\xe9\xfbǂ\xb5\xf6\x97\xf7]\xbf\xeb\xe8\x0f\xb5_\x01\xed\xfe\xc0\xbd\x0fXk\xff\x12\xd3u\xa8\x8f\xb3<vv\v\x82w\xaa\xe7(\f\xc6\tC\ba\xf45\xfb~\xb6\x16I\xf4\xb5\xb2\xf6l\xd9\xf1\x80\xf7\xfe\a\xd6՟2\xc77gC\xcf\xcf\x1b\xe0\xcd=q\xd4\xc6\v\x9f\xa3^N\v\xe3HD'G\x95\x9a\xa3\xa6\x8e\x91y\x92\xb3\xee\x8b/\xf8\xe0\x85\xe7\xadxF:\xc4\x06\x8b\xa3\xba8\xbd\xd7I\xe1\xa8T?\xc7-\x81\x8c\x93\x0f\x8a\x9csOb\b'^\x8cJ\x9c-i\xd7E\fc\xf1u\xc4\a\x00\xf8\x9b\xbd[w.\xediVK\xa4=[v\x88\x88\xfc\x99\xae{\x9d\xe7xw2\x1bB\xd6\x1d\x8e\xfa\xe2\x831\aᬵ\xbe\xc1\x05\\uP|\xfc\x06w\x1a\x1e\xad\xf6\xb2\x12\x9c\xfeh\x14\xa4\x1e\xa4pA\x9c\x8d\x1a\xcb$\xfe\f\x1b\x9a\x18z]-\x8aa\x14\x95/\xef\xa7\xe2\xcf2|\xa5\xc6n\xb1\xa3\xe9\x97B\xbc\xce9\xd3U^bǢ\xeb\xa9\xd5l\xa2\xd5jazj\n3\xd3\xd3\x18\x1f\x1b\xc3\xf8\xd8\x18&&&0=9\x89\xb1\xe9\xf1;\xf7nݹcٌ\xf5O\u007fe\xa6\xeb\x1b\x90\xd9\t2\xc5vM\xf5%\xce\x00Y\xdeI\x92\x9c\xce\xd7\xe8;43\xc6|\xa8\xb8?\xab\x8cQ\x9c\xfa\xb0\xb7cLP'\x97\x9d\x8d*\x83~\x86\x8bR\xfa\xf9^8=_7\xc6\x1c\xf5\xef\xceg\xd7:\xe7\xfe\xe1\x82\x0f\xbd\xf0\xd4~\xc7w4\xb2-\x03?\xe7\x91\xcff\bYyX]\x91\x17\v\xd2Aδؠ\xf1{j\x84\x06\r\t\x14E\xf1\x84\xb8\xfe\xa1\xb2\xeb\xb5 \xac-kU\xb1\x93\xe3h?\x84\xa0\xe7T\xf5\xf5|䕒\xf7\xfe߬\xb5m\x8e\xf4\x81nG\x16\xcb4\x1e\x9f\x1a>\x86B\xf4\xbb\x830\xd4q\xa1\x9eOXЧ\x15\xc6\xf5%\xe6C\x1d\n\aO\xacσ\xa2\x90\a\xa4IZ\xddC\xf9T\xec\x9e\xefY\xabM\x12\xcfi\x9a\xd6\x0e\xdeT\xfeW\x8btnYoUޱ\xbc8\b\xe3L\x8b\x83Օ\x12g\xb9\x1c\xa4h\x91\x9f\rl\x9c\xfd\xa8\x1e\xaaSγ\f\xadv\x06\x18|j \xcc\x1d\x83B\b;e^\xa6\x95\x1f\x1dG\x96e\v\x9a'8\xd0P[\xa0\xfa\xa2\xef\xe9\x0fP\x95/\x9e\xcc\xf7\xeb[{E\xe4#Ƙ19\xd0\xed\x94\xe1ݠq\x14\xa8\x91\x99zm\x15|\x1c\xa5qT\x17G\x9a\xeaH\u0603\xb21`\xef\xcaE\xb5\xce{\xcf\x16\x91\xbf\\\xe1|\x00\x00|\xb3ĭM\xcb\xc0O\x15\xc0\xb4@&C\xf93\x15\x80YA1S\x00\xad\xb2vc\x83Eb\x1c ]G\xa7\xe3\xd21\f\xa23\x88ID\x8c\x1a\xfe\x1a\x04e\xba\xbb\xea\xb9\xd8\xc8\xd9\x12C\x861\x94\xd0n\xb73\xe7ܷ\a\xca\xec\"\xb4\u007f\xdb\ue588|\x9f\xf1Z\x86\xaa\xd8h\xb0\\Yg\x18\xe7\x1f\xa4\xd1\xe3H\x98\xaf\x9b\xd0Ù\x94\x1f\x0e*\x94\x18\x06Y\xcdh\xbe\x98,\xbbŚ\x8f5\xd1\x1eo!\x9f\xca\xe0\xe7=laP\xb4\n\x04\xbf\xf0\xb1\x04,;\r,\xd4\xe8\xb0a_\rR\x03\xad|(\xf1\xfc\xb11\x03\xea\xba\v\xd4\xed@\xf5\xfde\xb6\xf1\x02X\x800\xa8|\x18\xfd\xe0\f\x8f\x11\x18\x866\xf5Z\x1dy\u007f~\xd9\f-\x81\xf6o\xdb\x1d\xcc\tf\x1f\a\x8b1BĶH\x03\x05\xde\x00\x19B\xa8u02|\x1f|\x18\xe1\xfb\xf5\xad\x15\xfb\xb7\xed\x9e\xf3\u07bf[D`;\xe7\x81\xfa\xa2\xfbHI.\xbepԧ\x93\xcd)?\x1b\xaa\xb8w\x9f\a\xc8\xe93/\xdc8\xa3\xd1\xfb\xb31\xec|\xfe\xbf\x9ew\xd3\xfa\xf5+\x98\x8fj\x02\x98*/\xee\xcb\x16Nm]\xf6s\x1e\xc5t\x8e0\xed\x91\x1f\xc9!\x93\x01\xf9x\x06?Y\xc0\xcc\x03\xf9t^\x15P1xHY4\x82\x88\x17<G\xa3\xbd\xa2;}\x8de\xa8\x9fO\xd3\xd4\x0f\xb8m\xf7X\x94\xa9^0\xfe\r\xa0\xb689(\xe1\xac+\xa68\xf3Z.\xe9\xde\x04\x8er\x19J\xe5̈\r\f\a6\xac\xb3|V\xd6j\x90\x01ʎǖ\x87\x9f+Кh\xc1O\x17\xc8\xc6ژ{t\x16\xf3\x87\xe6\x90M\xb6\x91Mg(\xe6s\xa0@\x95U\xc7-\xaa\xc0``\xc0^\xa4\xf3\xa8\x01\x0eg\x1al\xc0\x95\a\x8e\xf2\xf9\xb5\x98G=\xbdx\xa9\xc4\x198\xb7\xde3\xec\xdb\v9\x01\xba\x8e\x8eaz\x00\x10\t8\xe1\xccS\x8ez\x8a\xf2 \xc9>\xc9e:\x8f̧R\xdc\xfd\x17\u05ee\xf5\xc8&\xbd\x06g3\xa6ejP\xf6\x92\xc2\nk\xedG\x01\xfc\x8d\xf7\x1e\xe1\xc1\x02v\xde\xd6\x1e\x14\xd5\v/唔\x9d\x04\x17lb\xbc\x98qX\x00\v\xf0<\xfd>;\x95\x91\x91\x91jSY\x04\xe5\xbcg)c\xecE\x1cU\xc6\xc7N+\xef\x1c!)OޗO\xfd\x93B`\n\x03\x9b\x1bH\xb3\xdc\a\xe3'\a\xbe\x91\xder\x1aώ\x9c\r+\x1b66^\xbc yA\x14E\x91\\\xf0\x89\x17\xad.\x00N\x14Bpl\x84\x95T\x8fT\xb1\x95\xd4\xe1i\xc0\xa1\xdfc\x18n\x10\xd9\x1eװ\x80\xfa\xa6\xb2^p\xaeʘ\xb3k\x0e\x98FFFV\xa7\x06BN\x8d\xa3e}OD\xf7l\x01\xf9|\x0e?_:\x97\xf6\x91\x16\xb2\xb16\xe6\x0f\xcea\xee\xe0,\x9a\xe3\xf3Ȧ3\x84V@\xd1ʑ\xb5V\xa7\xf6ˁ\v\xb7\xbb\xc7\xd8<\xc3k\x8bes\x9cY\xad\x948\vџF\xa3\x01\xa0\xbbF\x94\x17\xb6\x0fq\xf1Z\xf5#\xb9(9e\xc5L\xf5I-i&|\xfeZ܍ș\x1b7\xac\xf4\x1a{\x8c\na{V\x8bƖ\xe4@\xf6n\xdd)!\x847\x1bc\xbed\x8c\x81\x1f\xcf!\a<\xd0\xee\b\xd5\xd8\x05\x9eM'Y\x8d;GȜA\xe8\x80┹\xc6<\xba0\x86N\f\xb7m6\x1a\x8dZ\xe4\xd4\x11«Ͽ\xf9\xe2g-e\x9c1\xc50P\x1c\xf5\xaaB\xeb\xc40\xd4ƛ!5r\x8e\x9d\xec \xc8\x18\x93\xc7i>+\fgi\f\x11q\x8d$\x8e\xfc:\xe3J\x93$Y7Pf\x17\xa1\v?y\x893Ɯ\x13+/G\xa2\xaa?l@\x18\xd3\xe7\xc5\xcb\x11\xffJ\x89\xe1G\xa0\xbe\xb91\x8e\x96\xd9q\xf7ʮ\x192\\\rh\x88\xa1I\xbe\x17\xbf\xcf|\xb1\x11t\xd6\xc1\x19\x87\xd0\x0e\xf0\xf3\x05\xf2\xe9\f\xc5T\x81bbu\x0eS\xe4\x00G#\xfe؆\xe8\xda\xc9\xf3\xbcּ\xc3uV\xb6\x13ι\xe5\xefD\xefȂO\xa7V\x87\xa4\xc1\xae\xae-.8+\xcf|\xd8j\xa4+/Y\x16CK\xa4K\xb7_a\xa6&'\x9f391\x81Ç\x0ea~n\x0e333(\xf2\xbc\x82&\xd9I\xc7\xd9y\f\xc7q\xc0\x04\x00\xdf\xfb\xe1\xf7\x1b\xfc\xf9%k\xef\xfem\xbb[\x00^!\"ۀN\xbb\xdfc\x1e\xc5\xfd\x19̡:$\xa2\x91\xa02\x16\v\x9b\x17\x1f+<\xb0\xf0H\xee\x1a\xd3\x14e\xe8\xc3{\x18\xfbgat\xee\xf1\U000a5393\x89\xa3ZΜbG\xc7\xe3e\xc3\xc5ІFY\x83&\x99\f\xe3f\x16\xd5.\u007f\x97\xdb\xf2q\x9b\x85@\xbcTY\x92\xf2˵\xa3^\x06N\xc7\xd0\xf9\xfck\x06\xcepo\xba4I\x92\x93t\xd7<\a\x14ʏ\x12g\x1b,\xe7\xd8\xc8\xc7E\xf5\xe5\x92\xde'\x9e_\xbe_\xbc!.\x867\x80\x85'\x1e\x0f\x02^\x8bI\xf5\x8d\x8356|\xbc\x0e\xd9\xd9\xc500끈\x9c0pFK:\x91\xa3\xe08\xa3\u0ff9\xc1&v:\xfa7\xb0\xb2\xa3\xe7u\xec|\x12\x82\x06~1z\x12C\xf6q\xd6\x11\xc9\xfeu\xcbfj\tT\x14Ņ\"\xf2Dͼ\xb3,Cs~\x1eSSS\x98\x9d\x99\xc1\xd8\xe1\xc382>\x8eɉ\t\xcc\xce\xceb~n\x0eEQ\xa0\xd9lւ\xae<\xcfk\xe7\xcei\x82\x90\xa6i\xed\x99D˒\xf4ޭ;\x8b\xfd\xdbv_-\"\xaf\xb7\xd6\xfe\x87\n\xabhf0\x0f\v\xfc\x039\xfc\xfd9l\xa8\xd71X\x91ِr\xa6\x12\x17Ҹ\x10\ft#A5 \xaa@\x1cUq\x1a\xdfQ\xc8\x159\x10\x8e\xe8\xe2\xe3\xeacL\xbc\x97\x12\xf5ʞ\x06\x8d}\x87\x10\x1e\xf3\x99\x87\xf5\x16\xd2\n%\xb6=\x9d\x97G\xc7Lz\x98)\x00\xd3\x02?Y@fˍn&\x03\xac\xb7pp@\xe8>|\x86\x9dKG\xa1~\xfe\x82O\xbch\xd5wB\x02xS\x9c]\x02\xa8a\xe3:\aZ\xf8댽\xf6Y\x9d\xafA9\x0f\xa0\v\xa1\xf1^\t\x86\xc7\xd4\xe8p֣|\xa9\xae0$º\xbbZ\x14;X\xa0kp9\xabg'\xc2\xfcFY\xcb\x13V\x87G9Me\xd2\v6\xd2\xd7t.\xb9\xbdW\x03\x06v\xd2+m;f;\xc4\xf8\u007f\x92$\xb5\xfa\a\a\x85@7X\xe1Ca9\x90\t!\xbc\xf6\xd2\xedW\f\xa4+\xf4h\x94\xa6\xe9\x9bX\xdf8 g4$\xcb2\xb4\x9aM\xcc\xcc\xcc\xe0\xc8\xf8x\xb9a\xf2\xd0!\x1c\x19\x1f\xc7\xf4\xf44\xb2v\x1b\xadV\xab\xaa\xfb\x85Pn\xce,\x8a\xe21\xbeߊ\xf2\xe7\xfd\xdbv\u007fZD\x9e/\"\xbf\x0e\xe0!\x11\xe9n\xf5\xb7\x06\xf9\x816\xe4@';9\u0099Fɐb\x8al08\x8ac\\;\x8e8\xb83\x80\x8d\vGv\x84\x83\xbfx%㌍\x13\xc3Sl\xac\xf4\xe9i\x1c\xbd1>\x0ft1\xdfA\xb7\xf1J\x90\x878\xb5\x8fa \xef=\x10\x00x\xa0h\x16\xb0\x99A{\xb2\x8d0㑍\xb7\xe1'\n`J\x90\x1fɑOd\xc8&ې\xa6@Z\x01E\xabx\x0e\x02~q\xa0\fGtѭ\x1b_\v\xe0\xe7\xf4\u007f]\xc0\xfa\xc3\x0e\x97\xc7\xd5k\x1f\x8b\xca;\xcejWB1$\xc8-\x9d@\xf78l\x8d\x94\xf9\xf3l\xa8\xd9a\xacF\xf6\xc1\x0e\x8a\xd7\x15\x1bE\x86z\xb8\xce\xc0\xfcr\xf6\xd7\xe1\u007fU\x1cH>\xd6~\xc2\xfccs\xc8&\xda\bs\x1e\xf9\\\x0e\xdf.\x1fs\xcb<\xb2\x1d\x88\xf7{0\x14\xee\x9cC\xbb\xdd^v}\x89\xf7\xf4\xe8\xf8\xf9^|\xbfx\x1dǎCe\xd7y\xb4\xc2I\x00\u07b9L1\xf5E\x9b\xee\xbc\xfce\"\xf2\xeb\x9a1)1$\xad\xfcs\xf6ę\xaa\xf7\xber,\xd3SS\x98\x9c\x98\xc0\xf8\xd8\x18\xa6&'199\xe9\xf7o\xdb];*j\xc5\x00\xec\xbe\xebw\xe5{\xb7\xee\xfc\u007f\x01<\xcb9\xb7\xd9Z\xbbMD\xbeÆ\f\x00d\xae,\xbc\xe3\xa1\x009\x10\x80\xc3u\x83,\"\x95\x01fH\x8a\a\x1eGM\xecT8\xad\x04\x16\x1c\x1ex\xfa\xf97_\xbc\xa2\xb1*.ʩ\xa9*v\xdc\x19\xa2\xbcr\xe6\x15GÃ\xce@\xec\xa3v\x0f\xf3Î\x8e\x9d\x18/6}\xaf2\xc2>@\x8a\xb2\r\xd9\xe4\x06\xa6\r\x143\x05\xcc\x1cP\x1c\xc9\xff༛֯\n\x8cqѭ\x1bO\x17\x91\xbf`H'\x863c\xfe9{U\xa3\xa2\xef\U00061703\x82\x89bh\x853\x0f\xe5M\x0f \x04\xba\xf5\x9a\xb8~\xc7\x1d0\xb1a\x1a\x041\xb6\xad2T\x1eb9*O\xfa\xbd\xb8) 2,'\xaf\xbbe\xc3\xe8 y]wˆ5EQ\x9cd\xa4l1\xcef3dSm\xe4\x93\x19\x9a\x87\xe7\xd1<8\x8f\xd9Gg\x90O\xe5\xf0\xb3\x05\x8a\xb9\x02y3G\xc8}\xf9\xe4@\x82`\x81\xfa\xeeug\x977\xe7\\'d\x1d\xe2yd\x1d\xe4c\xf39+\xe6\fXO@\xf6\xde\xffΦ;/_Q=v1\xdax\xc7\xe6SP>\xe6{Q\xbb\x19\xa3;<\x8e8[6\xc6T\xa7\t\x03\xe5>\xa2|<[\xf0L\xa6\x81U\xf0\xf6]\xbf+߳eǝ\xfb\xae\xdfu\xf5ޭ;\x9f\x17Bx\xb6\x88\xfcN\x9e\xe7\xff*\"\x99\x1a6\xdd9\xea\xe7r\xd8G\x80\xe2\xfe\fr\xa8\x9c\xa4\"\xefzM>Q\x92'\x903\x8f\xb8_;\xfe\xad\x023\xe5\vˎ\xa0xQ\xa9B1/\x1a\x850N\x1a\x17\xd6t\xb2\xe2\xe7t\f\x8cB8\xc8\xd1e\\\xbc\x8fSj5\xac\fǰ\xb1\x89\x15\xceZ{\x16\x80\x8f\x9dw\xd3\xfa\x81wd\x85\x10n\xf6\xde?\x89!\"\x96\x8f\xf2\xc1\x9b\xf9hn\xab\xcf\xc6N\xb3W\xedd\x05<ֺYX\xb6\x8a\x97+\xef\n\xb9\xe9\xc2d8\x86\xb1u\xe5\u007f\x90$\"\xf3@\xf7\xd9;\xfa\xb7\xdeKaJ\xbd\xaf\x8eI\x1d\f\xff\xa8\xdeҹb?:`^\x9f\xc3\xd92Н\xebJ\xf7\x02\x10\xdaefR\xcc\xe6(\xa6r\xcc\x1f\x9a\xc7\xcc#\xd3\xf0\x93\x05\xf2\xc9\x1c\xf9t\x86|6C\xdȇ5\xdb00(\x1e+\xe6\x96\xcb\x17;ZF9:<\xd7`ʸv\xc4-\xb3\xec\x9c;\xaf\x8f\x00\xf8\xf4\xc6;6\x9f\xbc\\ގB7\x02x:;\x00\xa5^\x0e\x90\xd7P\x1c\x98+qW\xab\x88\xc0~\xcf>\x14\xdftuv\a\x01\xd8w\xfd\xae\xfb\xf6]\xbf\xeb\x83\u07fea\xcfO\x88ȏ$I\xf2\xfa\x10\xc2G\x00Ԟa\x1eB\x00Z\x01\xe6a\x81\xb1\xf5\xa3M8\xf5\xe6\xc9\xe0\xbf\xd5\x10\xc6\x1d-<ᝅSۂ\xbf\x14\xe2\b\x8e\r\x03\xdfG?\x17\x17\xcf\xd8\x11\xea\xff\xaa\x98\x83\xa4\x10\xc2A\x9dh\xde%\xcdNE\u007f\xf3\x93\xe6:\xdf]\xb0\xf9\x89#)2\xd0oH\x92d\xa0i\xf8\xb9\x1f\xbd\xe8\x17\xd0\xc2\x1bLV\x9enkBy\x8e\x91f{@]ᕗ\xaa\xeeF\xc5\xf6xN8KY)\xa9>\xaa\xf1e\xdeb#\xc3\xd90\xe3\xf9\fu\xf2\x02\x1e$\xb9\xfdv\xca\xd9:\xec\xc7NB\x1d\x02\xaf#\xae)r\r\x80\u007f:\xe3\xbbz\x90\xbc&Ir5\xf3\xc5N66̱\x93K\xd3\x14Y+\x83\xf1@{\xa6\x8d0\x1f\x90M\xb4\x91\x1d\xc90\u007fp\x0e\xd9\xeeֲ\x0e\x19c\x98/\x0e\xf8b\x84A\xa9W\r6\xde\xd3Bk\xf0\xdc$In\xbb\xe4\xf6\x97\x0e,\x9b\xbf\xe4\xf6\x97\xbe\x0e\xc0\xafp\x90˙n\x9c\xf1\xc6g\xc5ŁV\\;3\xc6\xc0:\x87\xc9\xc7\xc6\x0e\xc4\xf7^2\x10\u007f\xee\x9f_\xf4\xca$I\xee\xd8\xf9\xe6o\xf6}6R\a7\xfbt\xe7\a\xe7^\xb3\xee\tƘ\x8d\xde\xfb˒$y\x9d\xf7\xfe\xb9\"\x02\x1c\xf0\bg\x99\xea$M\xc6\x1fc\\6\xa6\xf8\x8c\x1a\x9e\xf0\x8e\x82.\xfb\xd4:\x9d\x10\x8e<c\x85\x89a\x02\xfd[kB:\x1e5փ&k\xed\x0e3e2\x9c\x8a\x86\xf2\xcc\x066\xe6\x81\xf1\xf18\xab\x02\xba\x11,+Qg\x1e\xdew\xdeM\xebO\xb7\xd6^\xbd뷾\xb5\xec\n\xf0\xf97_lD䷑\xe3O\xf3vV\x19\x8c`|Ն\xe9\xd2\x04A|\xf9\xa02+\b\xae<\xe2\xdf\xd8r\xd3[\x92&\xb5c\xca5\x98Ь`A4\xbb\x02\xe2\xb9V\x83\x1b\xb7\x12\xc75<\xa0\xbe\x18U/\x18b\x1b\xb4\x13i\xb7\x9b\xe2B\xa3\x06\x9fr\xe3\x86\x1aH\x005\xe3\x1cgѽ\xeatƘ_\\wˆ\x8f\xec\xfc\xb9o\xac\xf8T\xe6\xf5\xb7m\xba\xb4(\x8a_\xe0\x00\x85\r\x1d\x1f\xb1\xa2\xf0\xa0Ω\xca\xdd\xda\xee\x93\x17\xeb\x8c\x02\xed\xac\xb9\xac\xb4\x93\x83*\xad\x0fp \xabA\x00g\xbd\xca3\x9f\x04\xc1z\xa9\xef\xbb\xce\x06\xea$I~\xc2\x18\xb3{ӝ\x97\xff\xca\xd7_z\xfb\xf6\xe5\xf0\xa9\xb4\xe9\xce\xcb\u007f\xc5\x18\xf3\x11`\xe1\x9e\x0f\x9d\xdf4M\xab\xccW\xf7\xa9\xf0V\a\x0ef\xd8~\xb1\xfd5\xe5{ߌ\xef\xbf$\xed=\xef\xa6\xf5\xe7\xa4i\xfa\x99\x10\xc2\xde\xf3o\xbe\xf8\x95\xcb\x1d\xf4ޭ;\x8f\xecٲ\xe3\x9f\xf6]\xbf\xeb\x9dY\x96=\xdfZ\xfb\xf2\x10\xc2g\xe34\x91\r\\\xdc\xeb\xcd\x11T\xac\x80\x1a\x01\x00\xd4\x1a\xd8²\x1e\xbf\n\xd4\x1fU\xa9\xff\xf7\xe2A'\x86\x95\x8b\x1f\x13\x19\xa7\x95\x83\xa4=[v\xcc˴\xbfS(\xfa\xe1HJ\xf9稜\v\xfe\xb1\xbc\x19\xde\xe2h\xbbCo\x01\xf0\xf9\xf3nZ\xbf,H㼛\xd6?\x19\xc0nj1\x1f\x14\x11\xdb\x03r\x04\x04(\xda\xe5\x0ei\xdf,\xca\r\x98\xb3\x012\x13\xaa\a\x94\xf9#\x05\u0094\x87\xcc\x06\x98\x96\x81\xcbm\xb9\xf1\xad]\x94{\x19\xc2\xc2ξ\xe5\x12w\x01\xa9|\xe2\x8e:ΞU\xa6q\xb1\x9d\x17n\fg\r\x88\xda\xd6\xd4\v\xbfj\xd8b؏\x1b;\x94\xef\xf8aDq4j\xad\xfd\xe0\xba[6\xacH\xa0\xebo\xdb\xe4\xbc\xf7\x1fdhX\xafϧ\x0f\xb0\xc1\xe6\xec(曑\bc\f$\b\xac\xb5\xed\xe5\xf0\xd6>\xdcB6\xd1.\x1bL\x9a\x1e\xed\xd96\xa4\x10xr\xac\x1c\x10\xc4p\xa5ʕ\x03Eu.z\xf2xǎ\x9d#\"w^\xba\xfd\x8a\x9b.\xb9\xfd\xa5'.\x95\xcf\x17\u007f\xe5\xe5\xa7m\xbcc\xf3M\"\xf2W\"\x92r&\xc7땳O\x00U݆\xb3<\x955\xeb)C\xde\xd6Z\xe0\xbb\x00\x80\x05DZ,I\x11\x8c1\xef\xf1\xde'\x00\x9e\x15B\xf8\xfc\xf97_\xfc\x0f\x17|\xe8\x85g-u\xf0L\u07fea\x8f\xf0y>8\x00\x00 \x00IDAT\xec\xfe\xc0\xbd_ܿm\xf7kD䆀n\xeb.G\xcf\xdaN\x16\xc3\x031\xb6\xa7\x93\xcb\xfbO$\bp8,\xbb\x06»\x9f\xe3\xc9\x00\xba\x8a\x1c\xe3\xf7<\x19\xec\x84xq\x0f\x98\xbe\xe0h\x87|,/Κ\xd8\xd11\xf4\xa6N/\xc6o\xe3\xb1x\xef\xff\x8b\xb5v\xff\xf97_\xfc\xe1\xf3o\xbe\xf8\xc7\xfaa\uef1b\xd6?\xed\xbc\x9b\xd6\xff\x91\x88\xdc\a\xe0\x97\xf5Z5\xc7AĐ\x1bGDJ\xbe\xf0\x80/\xa1/=JF\xe6\x02d:\xa08\x92#\x1c\xf1\xf0\x13\x83\xdd\x04\xb7\b,Q\x19>\x9e{\x9dg\xde\\\xa6\xf5\x04.\xbe\x0e\x98\xc6A\xebC\r/w3q\x96\xa1\xbc\xc6{)\x9cs\v\xb2\xd7\xcew\xd6[k?\xba\xee\x96\r\xcb\xdaY}ѭ\x1bO\x11\x91\x8f\x00\xb8\x88\xf51Θk\xf0I\x04\xc1\xea\xfbj\x90\x81n\xc6\xd0\xf9\x91\x10\xc2\xf8\xb2\xa4'\x82\xa2U\xc0\x16\x06\xed\xa96¬G>\x91\xa1u\xa8\x85֡&\xf2\x89\f\xc5L\x81|&+\xbb\x19ea\x81Z[~9\x88c\x98\x98m\x81\x88\\i\xadݽ\xe1K/\xf9\xa9\x8dwl>f\x93¦;/?}×^\xf2\xb6,\xcb\xee3\xc6\\\xc9\xeb\x9231Θt\r\xe9\xfdU\xee\xf1A\x9a1\x9c\xa8r\xf5!\xa0\xf5\xe0\xecA\xe7\xdcΘ\x9f\xbe!\xac\r[.{^6\x99\xfd78\x03\x9bZ\x04\x13 V^/V^\xb1\xee\xe6\x17\xfe\xa5\x97\xf0\xc1=\xbf}\xcf}\xfd^\xaf\x17\xc9\xd3̻\x9c\xb1o\x01`5\x85\xe6\xc8C\x15]\x1d\x8a\x0eP\x85\xa4\n\xc6\x13\x1aBy\xa2l\x1e\x96\u007f\x9e\x05\x9f!\x15G\x9fqD\x14\xd7g\x80z-\x821\xcaA\x93\x88|\xc1\x1f\xf17ʉ\x82$Mj\xb2`c\xa0<\xc70\fw\x9d(1\xfe\xcc\n\xd9\x19c\x12Bx\x931\xe6M\xe7\xdf|\xf1\xf7E\xe4\x9fD\xe4\xbbƘ\x83\x00\x0e;\xe7N\xf1ޟ\x19Bx\xa6\xb5\xf6\x95\xd6ڋ\xd8\x11\xc7Ƙ\xc6Q\x8b~\xd9Ȱ\xd3\xebe\xf8\xf8=\x00\xd5\xe1\x81\x03\x90mŧ:g\x95\xabs\xae:\x91\x17@\r\xcaP~\xf4\xb7f\x1d\f\x83\r\x92\xf6n\xdd\xe9/\xbauc\xab(\x8aQ2\xa8\v!\tc*X\x88uV?\xcb\x01\b\xd0}(Z\xe7\xb5_3\xc6\xfc\xe4\xba[6\xfc.\x80\xdbv\xfe\xdc7\x8e)\xe0\xf5\xb7m2y\x9e\xbf\x01\xc0\x9f\x8a\xc8\x19q@\x15C\xaa\xbc\x9680\xe3\xd6y\xbe\x06\xd7q\xac\xb5\xad\xfd\xdbv\xaf\xc83svY\x9b\xf7̗\x19\xaes\b!\xef\"\x0f\x89\x83K\x1d<\x02\\b\x01\a\xa4#\r\x04t\x1fn\x15?\x93\x03\xa8 \xb3g&I\xf2)c\xcc̥ۯ\xf8'\x11\xf9\xa6\xb5\xf6\x87\x00\x1e\x15\x91Qc̙\"rV\x9e\xe7\xff\xc5{\xbf\xc9Z[\xcb\xda㵩:\xc9\xe3`}\xe4\xda\x12ˎ?˿C\x1e\x90\xfb\xfc\xf3\xbd\xce\xc4\xebۊ\x85\xd9\xf0\x87\xa3ɨ\x95\\ MA\x92\x8ch\x14\xb5\xc6Z\xfb?\xf2\"\xff\uf5fc\xf7ş\x0e\b\u007f\x12L\xf8꿿\xeb\xae%\xad\xda\v>\xf4B\a\xe0oB\b\x95%\x89\xa3$\x8e\x8cc%\x8b#\xa68\xc5\xecLȲ(Ɛ\xb9\b\x1ec\x9e<I\xfaY\xfd_\r^\xdc\xd2;(\n!|\xc7N\xe1@rZz\x96\x1a)6v1\x14\xa5\x0eC\xa3%퐋\vk\x9c\xad\xa8\xe2qM\xa83O?j\x8c\xf9]\xe5\x85\xe1\x1e\x8ezx1\xaa\\\xa2豒\x9d\xfe\xcf|\xebw\xf9\xd4`\x86\x87b\x87\xc3\xe3]\x91l'=lj\x01ga\xad\x81\x97\x00$\x80\xebQ@g\xf91O\xbc\xd0٨\x0f\x9a\xbc\xf7\xe3\xd6ڧ\xea\xb5;\xb8{\xed\x9e\xdcz\xca\xd1'g\xff\\\xecg\xbe;\x06\xfd\fc\xcc'\xbd\xf7\xbf\xb9\xee\x96\r\xb7\x1bc\xbe/\"\xdf3\xc6|\u007f\xc7\x1b\uf7bd\xe8֍'\x1ac~\xd4{\xff\x1cc̏\x86\x10.7\xc6l\xd6{\xc55D6|\xaa\x13*O\xe6K\r\x9d\xea\x8566Ԑ\x81\xe0\xc7\x16\x15N\x1f\xc4\xfc\x01u8\x87y\xe2\x9aW\xf0\x01\xbe(\xd7v\xde*3^o;\xeb\x03\x021\x82\x90\x06xx\xa4\x8d\x04&\xb10\xce H\xad\xf3\xf1\xa4\x10\xc2\x1b\x9dso\xe4\xf1\xa8\x81\xd7\xe3U\"\xe7S\xf1\xa4Y-;\x8cx-\xc75$F\x18b\xe82I\x12\x04\x11د\x06\x84\x10z\x9e&ܗ\x03y\xd1\xef_\xba\x0e\xc0\xcf\xf0\xc2\xd4\x01U-\x820Ʒ\xfd\xeb\x9ds\xaf\x17/\xdf\xd9\xf0\x9e˾`\x8c\xf9W\x00_\xbe\xfb\x0f\xberԖ\xba\xf5\xd7m\\\x1f\xa6\xc3\x1f\xc2\xe1U\xd6Y\x04xX:\xb4\x90暑S\x0f\xcb\x18\x1f\x1b\xbfH\x01g\xf7nٱ\xec\xd3\xe0\xb8\xe0\xc9J\xc5Q3\xa7\xde1\xa6ˑ\x96v\xf1h\x8b\xdc i\xff\xb6\xddr\xfe;.\xfaB1V\xfc\x06N\xc1\x02#\xb5\x18\\\xc2P\x92.\xde\xd8бC\xd2\xd7c|\x15\xa8\x9f\x14\xa0\xbf\x81n\x16\xc6\xf5\x19\xfd\xbbW\xe19\xae\xcb\xc4Q;\x1f)\xc2s\x12;\xf7AE\xf8\x12\x04\xbe\xe5\x01x\x92Uw_\x8a\x982\n\r\xf00\xceBl\x80q\x16\x05\n\xb8\xc4\xc1&ݬ\x993\xd0Հ2\xed\x03\xf6\xfe\xf0\x8c\xf0Tv\x16j\xa0\x15n〆\xe7^\x83.5\xcaqWd\x1cH\x18c6\x03\xd8̺v\xe1'/\x99,\x8a\xe2\xd4\x1eEx\x00\xa89-\x86V\xf5>\xfa;F\x12\x80\xfazb{\xc0\x81\x83\xfd\x81\xbd\u007f\xb9\xb2\xd35\nt7\x06\xc6\x067v\x82\xfa:\x9f`\xab:\\\xe9m\xee\x11\xf2N'\xd9|\xf7Ad!\x04\xa4\xa3)\x8c3\xf0\bH\x1b\t\nS \x19IJ\xc7#\v\xeb\x1a,k\x9e\x0f\xcd(\xf9s\x1c\xe8q\xf0˶\x8b\x03:ՉF\xa3Q\xca7782s\xa40\xc6|\xb1\x97\xbc\xfa\xcd@\xfe\x98a\x1bU\xb28:UeK\x92\xe4\xb9!\x84\xe7\x86\x10~\xd79\x97\xbd\xf0ݛ\xbei\xad= \"\a\x9ds\a\x8b\xa2\x18\xb3֞\x0e\xe0lk텡\x156\x89ԟ5\x1dB@\x82Nˣ\t\x80\x03<<\xc4\x02p\x80\x98\x001\x028 \b\xe0\x8d\x87I\xba\xe7T\xd5`\x83CŲ\x15\n\xa8\x1f[\x10C=\xb1b1\xf6\xcc\x11@<\xe9\xab\x11yvx\xfdK\xcc\xc8o$\xa7\xa7\x00\xea'$\xc7\xf7d\xe3\xcb\xddX\xbd\"\xf9\xaa@)\xd2SƬ\xc8\xfa\x1a\x8f\x9d\xef\xc1\x0e\x9e\x15We\xc9\vV\xdfk4\x1a\xb5\xd7\xf4\xbb1\xec\x16\xd7vbG\xbf\\\x12\x91jsZ\b\xa12\xb2\xd5\\\a\x81\x0f\x9dlS4\x98\xe8\xe8\x88\x05\x8a\x90\x03\xd6\xc0\xa5\x160@&\x19\x92\xd4\xc1%\x83\xef\xc8\xcb'[\x0f\xa5f\x14b\xba\x19\x9bs\xf5\x93\x12\xd8\xf8\xc6\x01\x03\xeb/\xeb\fG\xa9\xac+*\x1f\x95\xb7\xf7\xfeT\xb5\x17\xfcY\xce\xd2hs]-\x18`}Pb\xa8P\x1d\xa1\xf2\xa2\x81\b\x8f\xb351\xb7`\xbfB\xbfTf\xe1\xe9\xa2\xf5L\xe5C\x8dql\x17\xf5\xffxm\xa91\xef\xf5DâݭIy[\x8e\xad--\xc0\x94\xfaR8\x03\xe3,\x8c\x03\x92F\nq\x02\xeb\xba\xe8\x86\xeawܖ\xab\xb2$\x94\xa0\x1a'\xdb/M\x048\xd8j\xb7\xdbp.\x81\xdfބs\xee\x13{\xb7\xee\x9c\xea%\xafc:\x90\x17\xbe{\xd3%I\x92\xfc$\xf7C\xb32pڤ\xccs\vh\b\xa1a\xad\xbd\x8c\xa3\xdbZ\x8aDƙ=\xbbR\x15\x15\xb5\nXðQ\xb7\x1d1\xa5\xc92\x89\xe9\xd4g\x00\xe3\f\x8c\x13\xe4\xb3\xed\a\x8f5Σ\x91\x1a4\xe5\x97\xc7\xc7FT\v\x94\xaa(\x1a]\xe9\x18X\xa1V#\xf2\x04\x80\xbd[w\xfe\xfb\v\xae\xbe\u0cd80\xafƩ\xa8);\x13\x1b\x006\xe8\xfa\x9eF!\xec\x04b\x8c\x14\xa8\xb7\xfd\xc5i1Gg\xfcY\xbd\aG>\xfa\x9a*t-\xa2\xb4\xdd\xe38\x18\xdb\xe5\x8cHy\xe3\xac(vV+!\xe7\x1c\x82\xafg\x96:&\xa0[?\xd0q\x14E\x81\xd1\xd1\xd1\xea\xa1L\xd6Z\x84\xc2\xc3\x19[^\a\x80o{\x142\xf0c\xfd!\"\xf7\xc0\xe0\xe7 \v\x8d\xb2\xca_\x8d1G\xdbl09{\x8c\xb3X\x86T؈Ŷ!\x0e,8\xf3\xe8\x95\xe1\xe8w\x98?\xbe'G㬓Zs\xa2\xcc\xea\x9e\xe5ʎ\xb3&\xbe&ý\xac뜙s\r\x873:\xfd;F)z9a\x9e\xa3\x10\x02B\x1e`\n\x83\xf2\x1c\" \vYy?\t\xb0\xce\xc25\x1cr\b\\\xc3A \xb0I\t\x99\xc5\xed\xed\xb5\x9a\x06͡f\x1al\xc3+\x9b\x96\x19L\xb5f\xbd\xb5\xf6\x8f\x17\x93\xd71C3k\xed{Y`ʈ\x0eT\x15\x81\xa3s\xa0\xbe\xa0x\xa1\xeb{l\x14T\x88q\x9a\xa6\x8a\xcfu\x04\xeed`R\x0fo\xc5\xc2y\a\xd3\x02\\\xcb\xc2\xcd'p\xce-\xe8_^\n)\x9f\\\x00\xd5\xf1\xb0\x11V>\xf8)^|\xc0\x1eCm\x83.\x9e2\x89\xc8\x1f\xfa\xa9\x1c\x82n1\x94\x17\xa3\xf2\x1dgNʿ\xf2\xcb;Qkx/A\b\xb1a\xe7\xe7\xc3p\xe6\xd5\xeb\x18{\xce0\x18Έ\x17\x1a\a\x1d:\x0e&\xd6\v\xe5E\xf9\x89\x1f\x02\xb5RR\xdd\xe5\b36~*\a\xe5[\xff\xe6vZ\x1d\xdf \xb2\xa3\x1e<~\xc6>\xb2\xf0\xa1kʫ\xea\x04P?[Nǧs\b,\xec:dX&\x86\x1d\xd9x2)\x0f\xfc\\y^\xd3\xfa]\xcepb{\xc1\xf2U\bS\xef\xc5|\xd9G,\xac\xb5\x9fY\xae\xecbx*ַx=\xb3\xdc\xf85\xb5\x15\xea8؉\xc7NV\xdf\xe7 \x9b3\xc3\xf8yC\xde{\x14y\x81P\x04\x14\xcd\x02\xf9lypj6\xd1F{\xac\x85\xe2H\x8e\xb9\x83\xb3\b\xb3\x1e\xed\xa96\x8a\xf9\x02E+G\x91uO\xcaУ\x9e\x18\x1eֵ\xa3\xf7mm\x9f\x05\x80\x8f\xefݺ\xf3?\x16\x93\xd7Q\xb5w\xc3{.\xdbl\xad\xbd\"\xae\xe4\xebb\xe5\xcd):\xe9\xbc\x03S\x05\xd6kW&O\x18OL/\x03\xc3)\xb8\x92\x1a\x9a\x18\x02\xd1\xebi\xed$\xcf2\x88\xc8'\x8e6\xcec\xd1\xda\xc3k\xb0fl\x14k'\xd7btr\x04\x8d\xa9\x14#s\r\xb8Y\v;o\x81& m\x81\r\xb6l\x19F]QbH\x85\x17\xf0j\xd0\xfem\xbb\xef\x11\x91\xcf\xc8\x01\x0f\xdb1\xa6|\x14=\x1b|v,\x8bAVq\xe0\xc0?\xfa:?\xc0\x86\r\x81ރ#1\xde)\xcfN\x82#L\xe5\x89\x1d\xad~_\x8d\x9e\xf2\xc9\xc1\x87\xf2\x91e\x19\x8c\xe9>\xdf{\xa5\xc4\xfc\xc5\xc1T\x8c\xe3\xc7\xd9\x19gFld{\x19\xa8A\xd0ޭ;\xbf\xdf:8\xf7\x1d\xdb4\b\xf3\x01h\v\x8af\x01\x13\fB\x11*\xb9\xf0\xbdu\\\x9ca\xc7\x19%\xaf\xdb8#\x89\xb3\t\xd6\x1d\xdd[\xa2k6~\xa6\x0e\x80Zdφ\x92\xaf\xc5k\x9d;\xd88\vn?6\xbf\u007fϖ\x1d\xcb\xee\x06\x8d\xb3ט\xf4\xbc3\x9dw5\xc0l\x88\xd9^\xc5\xebF\xaf\xcd\u05cf\x83\xed\xd8)q0\xa2\xefŏ\x15\xa8ɦ\xf0Hl\x82|>/\xe7~&G6\x91\xa1\x98\xc8\xd1|l\x1eّ\f\xf9dV=\x82[\U00080b15Uk'I\x13\xf8oz4\xb3f\x91\xa6\xe9{\x8f&\xafEW\xd6ſ\xb7\xd1\x00xo\x8c\x8d\xa9\x90\x19\xef\xe3\xc8O\a\u008b\x84\x8d(/\x1a62z\x0f6\xb2qt\x1cu\xfd,\nϨ C\b\xc8|v\xf7ޭ;W\xd6^,R\xf6{\xe7\x02\xdb\xf1\xb9\x0e\xf5{\xabC\xb5֖\xbb\xa5\x1d V \xb6\xacӔ\u007f\x97\xc5X8,\xfb\xb0\xb7~\xc9\x18\xf3\x87\xde\xfb\xd74\xc6S\x14\xa7\x140\xb6\x1b\t\xf3B\x15\x91\x1aT\x15\xa7\xbb\xea\x1cTa\xe3\xc2y/(\x82\xb3KU\xfa\xf8H\xf6\xd8\b\xa8\xc3b}\xe2h\x94\x17\x95\xde\x17\xa8;\xa1ب\xf3\xfb+%k\xcb\x13\xa6\xd9Xq6\xa1{\x12\xe2\x05\xcf\x1d|\x1c\xf4\xb0\x0e\xaf\x06\x89\xc8g\xc2\xc1\xf0\\\u007fb\xb9c_B@&\xe5\xde:\xb1\x01\xdey$\xa9C\x11|\x19F\x1a\x81I,\\ja\x12\x8b\xbc\xc8k\x86\x89\xd7g\x9c9j\x10ɭ\xbe\xfa\x1d\xce>93\xe4,\x833\vޥ\xaf\xf2\x03\xea\x8faedB\xed\x10\x04p?p\xc8E\x96\x9d}(_\"\v\x9f\x8b\xae\xf3\x1d\xd7\x1d\xb8S\x8du[\xe5\xc2h\x03g6\xfay\xbdO\x04\xfb\xf3<\xd6\xe4ş\x89\xed/;\"\x86\xafj\xd7\x12 \xe4\xe5{y\xb3+k\xef=\xd2F\x8afh\xc2\x16\x06~<\x03\x80\x8f\xed\xba\ue7a3֏\x8f\x96\x81\xbc\xd2\x18\xb3\x89;_8\"P\xe2t7.ز\xa7\x8d#rV.V\x16\x8e\xd2\xf8\xbbl\xf0t\x02y\xe1\xc6F+\x04\x8f\xb9\xe6,D\xe4\xef\x8e&\x80~\x88\v\x82\xba\x10tҙ\x17] \x89up\xe2\xe0\n\x87$K`\xe7,\x92\xd9\x04\x8d\x99\x14kfG\xb1vz\rF\xc7G\x8eqו\xd1ޭ;\xef\xb5\xd6\xdeZ\xccd\xa5\x1c\xb1\xf0AA\xaa\xdc:\x0f\xbc\x10\xe2LP\xffgE\xe7\xefi\xe4\xda+\xe5g\x88\x01\xa8w\xb7pF\x1b;\r\xa0\xbb\xe8X\x87\xf4\xfb\x9c\xda3\xbeΙ\n/ƕ\x90\x8e\x93\xe5\u008b\x95\x9f\x15\xa1\xc4\xce#v\x8e\xfa\xb3Z\x99\xa81\xe632\xe3al\x8f\x83)\x05\x80\x17\x84,\xc0w\x8e\xf67-\x03\x99\t(&\n\xb4\x0f\xb5`g\f\xfcDQ>~y֗\x9dC\xad\x00\xe3\r\x10\xeagR\xf5\n\x06t.\x18B\xe4\x82y\x8d\x1ft\xb3\n>\x01X\xa3xv:\xb1a\xac\x82S\x03\xb4&琦\xe9\x8a\x1d\b\a\xc3qv\x1c\a\xb7\xdayů\xb1\xe3`\x9b\xc5Y\x1b\xc3\xe1\xf1\x1a\xe0u\x1a\xa3\x00,O\xd6{\xfd\x9f\x1d\\\xec\xfct\x0ez\xa1#Ɣ\xa7?8Xd;\x9b\xc8\xf3|\xca9w\xd4\xec\x03Xālx\xcfe\xd69\xf7^\x8e\xb2\x18\xd7慢=汧TA\xe9\xc0YQ\xd8\xd8s\xe4\xcaB\xd3\xcf\xf2k\x9c\xb61|\xa5\xc2\xd0G\xda\x1a\x18\x00\x06\"\xd2\xf2\xde\xdfv,!\x1c\x8bb\a\xa8cc\x05a\xe8\x85'\x87\x17/+\xc4 \xa2\xe2>\xe8M\x00\xee3\x8f\b\x82\x84\x1a\x8f\xf1\xc2\xe8U\x83\xe2\x80!\xee,Q\x99\xb0A\xe0E\xa7\xca\x1cC;\xec\f\x94\x18>a\x05\x8f\xe1\x04\xfd\x9b\x9f\x8b\xcdp\x98\xf2\xc0\x86Hy])1\xa4\xa7c\x89q\xedŢT\xfd\f\x1b\x89X\xe6\x83&\x11\xb9\xab(\x8a\xbb\xcd#\xdd\xe7\xef0\x84\xa4\xb2ֵȎYa\x10\v\v\xe4\x00\xda\xe5\xde/\xd3\x04\x8a\xc9\x1c\xed\xc3md\x87\xcag\xc8\xc8t@\x98\xf1@\x13\xf0\xf3\x05\xb2\xb9\xaclW\xf5\xd2s\xed\xab\x1daH\x93\xe7_\xd76Эϰ!Wb\xc8RB@~O\vƘ\xbb\x8a\xa2\xf8\xc6\n\xe5\x06`\xe1S\x1dy\x1ds\x16\xce\x01W\xaf`'\xaeip\x80ú\xa2\xf7\xe6\xac6\xb6\xab\xfa\x9b\x9dv\xbc>\xe3qp\x10\xae\xdfg\xfb\xac\xb2\xacjI;+\xc7\xf6\u007f\xefٲ\xe3\x98\xddl=\xb5\xd7\x18\xf3zc̅\xec0b\xe7\xc10\x16\x0f<N\xe7\xbc\xf7U\xf1\x8c\x17Oŀ\xedv/\xe9\xf5\x19\x06\xd0ϰAQ\xc18\xe7*\xa7\xa1<\x15E\x01\x81`\xbe5\a\x11y\xf7\xfem\xbb\x0f\x1dK\b\xc7\"n\xd3S\xa5V\x1e\u0600\xb2C\xe3蘣\x1a\x9d\xc8\xd5,\xa2+\xedݺs\x12\xc0O\x89H\xd3>\x02\xd8i\v7_fE\xa9O`r\x03+\v\xa3u\xee\xd0\xd1q\xeb\xbc)\xdc\xc5\v\x9f\x8d\xa0\xfe͆\x83\xbf\xaf\xf2P#Q\x93[\x90\xdaao\x1c\xa93n\xae\xfa\xa2\xf3͎\x8c\x17\xafF\xafqV\xb4\x12\xe2l\x82\xb3c\xd6M\x8e\xfc\xe2\xccK\xe5\xc1\x19\xfdj\xd0\xfem\xbb\x83s\xeeJH\bI֍\xe2\xf9\x98\r\xceF\x81z\xb3K\x9c\x1d\xb1a\xaft\xb7\xf3\x802\xc9\x04\xa1Y>J\xd96M\xf9\xd4˩\x80\xecP\x1b2%\xe5\xf3d\xa6s\xf89\x0f\x9b\x1b\x14\xcd\x02EVvU\xf6\x82\xb1yM\xb1\x8c\xd9\t\xb3\xa15\x8fX\b$\x88ȕ\xfb\xaeߵ┓\x03<\x86\xdf\xd8>)o\xbc\xe6\x95\x18\xb2U'\xc4\x01\b\a\xd6<nv(,\u007f\x0e̸\x01\x81O<\xe8\x95ų3\xd4\xf1\xf0Q\xfez\xffʞ}[\xe0C\x81$I\xb6\xecݺ\xf3\x1f\xfb\x91\xd5\x02\a\xb2\xf1\x0f\u007f\xdc\x19c\xfe\x98\x9d\x05G\xdd\xecEY\x01\xe3hC\aޫ=LI#\x12\x1e\xb8\xb5\xb6\xc2SY(q\x14\xc9\xc6<6\xea\x1d\xe7\xf1-\xe7ܟ\xf6#\x84c\x11\xc35\xbd\x1c \u007f\x8e\xfff\xde\xe3\boP\xd0ʱh\xef֝\xbb\xad\xb5\xbf\x99\xe79\xf2#m\xa43\t\xd2\xc9\x04\xa3S\xa3X;\xb5\x06k\xc6G\xb1\xf6\xf0\x1a\x9c0\xb1\x16k&G\x91N$h\xcc4\x90Υ%\xf4\xd6.;ڐ\x01V\xba2瀁#1\x00Uj\xcfN#>\xd6^\x17T\xa5܂\xaaư\xd8&K^\xc4@W\xe78\xdb\xe1\x05\xad:7\b\x98\x88\xa1\x848\xaac\x87\x17\xebx\x9cy\x03\xa8\x05L\xab\xa9\a{\xb6\xec\xb8\x17\xc0\x87\xfd\xa1\x1c2\xb30S\x8e\xf9S^bx\x85e\xa0\xf2䢷\xfep`Pe<Y\x0e\xc9\x05\xc8\x00i\x06ȼ\x94\x8fT>\x92\xa3}\xa8\x85|,\x83\x9f\xf4\xf0S\x05\x8a\xe9\x02aޣ\x98/\xbfc\x02`P\x87\xbc9\x90\fA`\x1e,\xf1z\x11\xf9\xd0\xfem\xbbw\xacTfq\xa0Ǚ\xa5\x8eKm\x94~\x9e\r2G\xf7\x9c\x91\xfa\x1ev\x92\xbf\xcb\xf0f/g\xa12\xd0\xcf\xeak\x1a\x8c\xf4\xea\xe4R=\xe5\xf5\xa2\x14\xa3\x11~G\x01\xdf\xca\x00\xe0Nc\xcc\xef\xf5+\xaf\x05\x0e\xa4(\x8a\xcbB\b\xcfc8\x81;\fb\x0f\xa9\x03fe\x8a!(`aڧ\x82\x88\x8fXP\x03\x15\x17\xd2\xf8:<\tU\x81\xaa\x03Ѵ\xf3\x16\xbc\xf79\x80_ٳe\xc7\xc0\x9a\xecc\x88\x8a\x1d#Gg:\xee8\x82\x03\xea\x13\xf8\x9f\xe5@\x00`ϖ\x1d\xff\xcb9\xf7\xe1\x10\x02ZY\xb34\xe6\xa6\xde\x05\xe4\xe0`\v\v\x979$-\a;c\x90\xce$p\x13\x0e\xa3ӥ\xb3\x19\x1d\x1b\xc1\xda\xc3kp\xf2\xf4I\x18\x9d\x18Ac\xb2\xf1\xff\xb5w\xae!v]\xd7\x1d\xff\xaf\xbdϽ3#K_T\x88mZ\\ZB\xa0z\x9b@\xdcGH!\x1fR\xbbNH(\t8\xae)\r\xa5\r-qh\xa8\xa4\x12ZSH\xa1hf\x14h\x1e\x1f\xf2h\xa1\xfd`5\xa4\x8e\x9b>▒\x96\xbaP\x97\xd8ռG\xc6\r8vd[\xb6\xf5\x98ǝ\xfb<g\xaf\xd5\x0f\xf7\xac{\xd7\xd93\xaa\xa4yH\xc9e\xffĠ\x99\xb93w\xce\xdeg\x9f\xbd\x9e{-\x8c7\xc71\xd6\x1a\x83\xdfp\xc8:\x1e\xbe\xe71\xeeƑQU;\xb2\x9a\xb8\x9d\x87Z\xad\x06\x0e\ft\x01Z\x1d\xf6ˈ\x95\x17\xe7\x1c:\x9dNE\xe8Xal\x85\x95}\xc0\xb6\xf2\xbbo\a\xebZ\xd3\xf7\xb6\n\x94}\xddj\xb0VX\xeax\xecƱז\xa8\x88<\xc1̗\x8b\xcb=`\x1d T[\x1fX\x8d>\xb6\xe4\xacU\x15[\n6U\xddλZ\x90\xd6M\xa7s\xa0\xf3\xa6\xf7V\xd7!\xe7\x01\x14\b\x94\x03\xdcb\xb8\x8eC\xb1\x9a\xa3X)\xfa\x15\x97W\x03\xd0\x10\x84\xf5\x02h\xf7\xcf'P\xe1\xc0/\a\xe4\xd7:\x10\x91\xcb\x00\x9e؍\xf9\xb2q\x86XqV\xb6r\xa9\xd9{\x1f\xbbj\x89\b\xa2J7\x0f-\xf0\xd8Ka\xf7N}Om\xfbm\x95#\xbb\x0f\xe9\xde\x13[F\xb1{P\xef\x8f~n\xc3\x01X\b\x10\x04\x10\xd1%\"zd\xe1\xcc\xccM\uf6db\x04\xc8\v\u007f\xfaܳD\xf4\x18\xf3\xf0샕\x8cV\xa3\xd6Iҋ\xb1\x12X\xbf\xb6\x83\x8d5p\xfb0Z)i\x17\xa4\x95\xa2\xaa\xb9\xe9\xffz3\xb3̃@\xd8h5\xf4\xc6\xff\xf1\xd2\xd4\\\xa5q\xd5N\xb1\xfev\x00\x95<\xf9ؕa\xad\xa9\xd8J\xd3\xf1\xdc\x0e\x17\x96\xc59\xf7\x99,\xcb\xfe\xa1(\n\xac5V\x118@\xb8\x1a_\x88ﭵ2\x14\xe6\xfe\xe1\xa6:\xea\xf0=\x87z\xaf\x86\xac\xe51ѝ\xc0Dk\x02\x13\x8dq\xf8\xb7\x1d\xc6.\xd71\xf1\xf68&\xae\x8e\xa3v%\xc3\xd8\xea\x18\xc6\x1bc}\v\xa8\x95!\xebxP\x87\xe0\n\x87Z\xa8\x81ߪ\xfa\xe5\xadŪף\xe6w\xfca7B;\xff\xfa\xbb\xbb\xe1&\x8aݳ:\x17\xfa\x9an\xaa\x8a\r*\x0f\xe6\xcdXW\xb1\xb5\xbeW,Mͭx\xef?\xe1\xbd\xcfõ\x1c\xc5Հ\xcc\x0f\x0f\xf0Z\x85к\n\xb7rO\xc6J\x8f>õZm\xcb\x03\x89[=\xe3\xf1\xbd\xb0_[m\xbf\xf2\xf3\x8c\xfei\xed\xd2U\xd6Y\xed\x80\u007fX@\xd6\v\x88HOD~syz~S\xbb\xd5\xed`k\xac\x01\xc3\xe3\x00VyP%7v\x01\xd99\xb4\xe3\xd1\xf7i?\xbf\x014\xcb^6\xd1Y0+\xac\xec~\xab\aQ\xb7J,\xb2\x9f\xeb\xb5\xe4y\xbee\xb2S\x1cs\xe1P\xc6\x1c\xe7z\b\x1cP\x14ś\"\xf2\xf0\u0099\x99\xb7ne\xbe\xb6\\\xc1\x8d\xe6\xfao\xb4:\xad\x8aD\xb4\x99\x10\x006\xf9\xa4\xad\x1bJ\x1fx\x95\xb2:\x99\xfa\x1e\xb6\f\xb3]`ֽa\xad\x10\xf5u덈\xfd\xf2!\x0fhu\x9az}\u007f\xb4457u+\x93p\xb3\xd8ִv\xa3\xb5\xae:}(c\xf3юu/}\xdf\xd7c\xe1\xccL\xb7(\x8a_\xf3\xde\u007f\x01\x00\x1a\xcdu\xa8\x92\x00\xd3\xc0\xcb\xde/{\x9dv<ֺR\xad\xc6f`\xa9\x89\xef\xbd\x1f\x1c\xect=B\xd6\xcb\xe0[\x1e\xbe\xe1Qo\xd41\xbe6\x86\xfa\xd5\x1a\x8a7{\x10\x910\x11Ɵ\x98X\x99\xc0\xc4\xda8\xc6\xd6\xebp\xab\x04Z\a\xc6\xf21p\x93\x81\x1e\xc0=\x1eTص\x0fT\xaf\xd7\x1b\x9c\xfe\xd7q\xc4\x1b\xfeN\xd9\xca]\x19k~V\xf3\xb4\xe5^\x94\xadb\x86{\xcd\u0099\x99\xef\x10ч\x9ds]Y\x0f\xa0פ\xe2\x82\xd1\x18\xa5\xddt\xe2Mӎ\x85\x99+\xf1\xa5\xd8\xfa\x06\xaaq\x84\x8a\xb6\x8b\xeb\x9f\xef\xb1V\x9d\xdd\xfc\xac\x05\xc7\xcc\xc8.9\xf4\xaeu\x00\xa0\xeb\xbd\xff\xf0\xf2\xf4\xfc\x96\x85\xfe\xb6C\xac\xdcY\x97T\xec~\xb2V\x9b\xbd\x97\xb1UW\n\x80\x9c\x88\xd0{\xa9\r\xf7\xa6\x83\xa0z\xf6*V:cE.^\xc3\xfa\xb3:W\xfa\xbfƸ\xecu\xe8\xfbW\xbc&\xaf\v\xf2\x99\x8eދ\x17\xbd\xf7?\xbf45w\xcb.\xc0M\x02\xe4\xf0\xa9\xe3\xef\x05\xf0\x01\x11\xc1F\xab\x81v\xb7UY$v#\xb1\x03\xd5&%ַ\x1dkYvAY\r\xcd.L5!m9\v}\xd8\xf45\xe7\xfa7 \x84~\xaan\xb3\xdb\xd4k\xfb\xcc\xd2\xd4ܟ\xdd\xea$\xdcp\x92\x9c\xab,,+L\xad;B\xc7`\xb3$\xf4\xf7m*\xf0nnj\xb7\u008b\x9f_\f\x8b\x93\xb3\xbfOD\x9f&\"n\xf7\xdah\xb67\x00T\x9b\x0f\xe9x\xd4|\xbe\x9e\xb6\x1ck\xfb\xd6\n\x03\xaagB\xecB֏n\xaf\x83f{\x03!\x84\xe0\xbd\u007f\xc4\xc1}\x87\n \xb4\x02|ףޭc\xa2;\xd1O\u007fn\x8ccbu\x1cw\xad\xeeþ+\x13ؿ\xb2\x1f\x13\xd7\xc61\xb6RGm5\xc3]\xdd}\xa8\xb52P\x93\xfa\xbf+u8v\xc8|V\xb9?\xdb%\xd6\xfe\xec\x1c\xc4\xcd\xcet\xbc[\xf5\b\xb1\xbf\xa7J\xd8\xed`qr\xf6\x9f\x01|\x90\x88\xdaE(\x10^ɑ\xbfַ\x86\xec\xb3\x06TcMz\xdfl\xc0V\x85\xa3\xf5\x1c\xd8ZU\xf6^o%$u\xcc\xd6\xdaT\xb7\xca\xf5<\x11!\x04\xe0-\x00\x17Y\x15\xd063?\xbcpf\xe6_vs\x9e\xc2J?\xabLZ\x02i3\xb8\xc3p\xec\xe00TJT\xc8\xc5^\x04k9X\xa1Z\xce\xe33\xde\xfbsD\x84\xe2\xed.\xa4\xac6_\xaf\xd5+?k\x05\x16PMW\xb6Ϧ\xfe\x8e\xf5~螣\x16\x8b^\xc7P\xe0\x01\xae\xe5\x10\xe6z\xc8\xdf\xea\xe8\xef\xfeG\bᗖ\xa6\xe6\xb6U\xeeiӮ\xe0\x9c{^D~\xd79\xf7\xba>\xfc\x1b\xadF\xb9є\xfeO\x93\xb1\x13\xe7\x1dǧLcS/\x8e\x83\xc4~;]\xa0q\n\xe8p1\xf67\xe1v\xbbi\xad\x8e\x00\xe0w.\x9c]ؕ\xa0y\x8cՎ\xac\xfbM7\xcb8\xa5\xd8j\x16vA\xe8F\xb3W\xb9\xff7\xcb\xd2\xd4ܗ\x00|\x84\x99[DT\xb9\xbf\xceh\xef\xf6\x01\xd7\xfba\xcfpX\x8b\xc4\xdeO[\xf2\xc4\xc6'\xfa\x9f\xf7\u007f\xae\xd1\\G\xaf聈\x82s\xee㋓\xb3OY!\x16k\x81\xb1\x9fXB\xff\xc1\x96\x8e\xa0^\xd4A\x1b\x84z\xab\x8e\x89V\xdfz\xa9]\xcd0qm\x1c\x13\x97DZ\xff\xda\xce\xdbO\xdb\xcdAǢ\xd7i-S\x00\x83\x18\xce\xf5,Q\xbb\xd6o\x87\x1bKY\x9c\x9c\xfd\xaes\xee!\"\xea\xbb{z\f~\xb5@X/3ʀ\x8a\x10\x04\x86\x15\"t-ر\xeb|\xd8Tj\xbb\xfe\xb7JÍ\xc7k\xf7\a\xbd\xb7\x83\x98\x99*\\-\a\\dP>\x98\xaf\x15\xef\xfd\x83\xcb\xd3\xf3\xff\xb6\xeb\x93\xc4\x02\xe9\t\xa8\a\xa0\x03\xa0%(Vs\xe4Ws`U k\f^\v\xa0\x16P4\np; t\xfa=B\xc0\xd5d\v\xa0\xe2\xa2\xcb\x01<&\"\u007f\xe2\x9cC\xaf\xdbF\xef|\x1b\xf2\x92\f\xaaW(Vp\xeb\u05fa'Z\x8f\x90\x9dkUZ\xad\x12\xa0\xffk܋\xe7z\xc8\xff\xb7c\xef\xc79f~pyz~e\xbbӵi\xf5.N\xce\xf6.\x9c]\xf8\x8a\x88\xbcSD\x1e'\xa2K:!\xadN\x13\x1b\xad\x06Z\xed\x8d\xe1\x03N\xd5\x1ce\x9b\xae\x16\xbb\xb4l)\x12\xab\xf1l\xe5\x1f\xb5\x82ƹ\xe1f\xd5\xe9u\xb0\xbe\xb1\x860p\xbf\xe0\xbf\x00ܿ45\xf7\xf5\xedN\u008d\x10\x91Wl`V\xb5\x0f벱c\x8a\xcd\xf7\xad\x02\xadY\x96\xddQ)\xb2<=\xff\x8f\xde\xfb\xf7\x10\xd1w\xf5\xc1n4ױ\xde\\\xaf$0\xe8\xbds\xce\r*\xa8ƽ@\x80\xeaحeBD\xfd\"\x98\xe5\xbd\xdch\xad\xa3\xddm\xe9\x02n3\xf3\xa3KSs\u007f\v\x00Y\x96m\xe8߱\nD\xfc0\xa9Eg\xad\xdc؟l\xdd E^\xbc\xb2\xd3\xf9\xf2M\u007f\xcdu\x1c\xa8G\xa0\x02\xf0\xe47\xa5\xa7[\v:\x16\x9e\xd6\xe26k\x00EQ\xbc\xbc\xd3k\xbb\x15\x96\xa6\xe6\x9e%\xa2w\x85\x10\xbeFD⽇_#\xe0\"C.2P\xaeJ\xad\x94`㛱\xa2d\xad\x11\xbbVb\xc5B_\x13\x91A\xe3\xadX\xc9\x1c\xccKyHQ\x82 \xbcZ\x00\x17\x19\xe1\xca\xc0\xc5&y\x9e\u007f\xd5{\xff\xae\x8533\xff\xb9\x17\xf3c\xaf\xd5*.\x833\x19\xdcO8A\xde?\xf7\xc2M\x86l0\xc2j\x81\xe2Z\x8e\xe2J\x0e^c\xf0z@\xb1\x9e\xf7\x85PW\x10:\x8c\xc5\xc9YY\x9e\x9e\xff\x1c3\u007f\xdc9\xd7\x15\x11\xb4V\x1b\x90\xc5\x02\xf2\x03\xdd\xfb6\x1f\xc0\xd4\xfd\xc6*\xa4\xfa\\\xd8\xfd\xc5>\x0f,\xfd\xc3ò\"\xc8g\xbb\xc0b@\x11\x06\xc9\x13\x97\x9cs\x9fȲ\xec\xb1\vg\x17\xb6\xd5\xfaW\xb9nz\xca\xf2\xf4|\a\xc0\x97\x0f\x9f:\xfe\x97ιO2\xf3gE\xe4\x1dz\xd3\xd77\xfa\xd5}\xbd\xf7\x98\x18\xdb7,U,\x02\x8a\x82K\xf6a\xaa\xd5j\x83ÇV\x13\xb7f\xaes\x04熾\xbf\x8dV\xa3\xb2Y\x97Z\xcf\xd5\x10\xc2i\xe7\xdc_-N\xce\xee\xa9#\xb9\xd9\xdex\x03@E\xb3\x8eMt\xbb\x91\x84N5;-\xeeD&\"\xe8\xe6\x9d;k\x86\x00X\x9c\x9c]>r\xfa\xc4\a\x88\xe8\xa1\x10\xc24\x80C\xde{=\xc1\x0f\xf4\x80\xfd\xfb\x0e\x94Z\xa4\xc0{B\x91\x17\x83\x12\xe4\xd65e\u074c\"2H\xcb\r!\xa0Wt+\xf1\x94\xd2\xdd\xf1\x8cs\xeeS\vgf\x06\xa5\x12\x1a\xcd\xf5\xa6nHV\x11\xb1Y?\xfa\x1e\xba![aa\xb54\x15\x1e\xe5k\xaf\xeft\xae\xf8Z\xb1j\x95\x9a\xc09 \x82\x80jY\x16\xf1\x00\x02#\x80\xe1\x88\xc0(\x06cf\xe3\xea#\"\x14\x12\xe0\x89\xb6]z|\xbb,\x9c\x99\xb9\f\xe0\x93\x87N\x1e\xfb\x1a\x80/\x89\xc8/\x00\xa5r\xf4j\u007f?q\xe4@?偬\xfc\xbeT\x9b\xa6\xc5~ykeYKB\u05c8Zj\xf5z\xbd\xd2\x1b\x9c\x8c\xbb\v\x05\x80\xd7\x18\x05\x0fS\xf8\xf5~z\xef\x9f\x13\x91\xc7_\xfc\xfc\xe2\xcc^\u038d\xae7ݏ\xac[ֺ\xd4\xf4\xfa\xec\xf8\x15-\x15\x92e\x19Bs\xe8\xfaW\x16'g\xbfq\xe8\xe4\xb1e\xe7\xdc\x14\x11=(\"\xe0\xb5\x1c\xc5\xf9\xfe\xdf\x1c;\xb8\x0fr_\xbf}\x00K\x80s\xc3\xf5o\x15\xb7\x81\xd2B\x0e!\f\xebp\xf1\x9b\x8c\xe2\xf5n%\xe6T\n\x9b\x0e3O\x13\xd1\xd4\xe2\xe4\xec\xc6n\xcc\xd7\r\xf3\x1b\x97\xa7\xe7\xdb\x00\xfe\xfc\xf0\xa9\xe3_!\xa2_%\xa2\xc7D\xe4a\xe7\\\x1d@\xa9U6*\x1b\xaaw\x1e\xb5\xac^y\xe0\xbd\xf7 \xe7\xd0\xeb\xe5pnh\xeao\xca`\xe8\xe5hv;\x95߳\xc1$\"z+˲\xbf\x16\x91\xe9\xe5\xe9\xf9\x1du\x1e\xbbY\xac/_\xaf\x15\x18\x96\xb2\xb7\x9bWlBZW\x85\x8d\xe7\xdci7\x96\xb245'\x00\x9e9|\xea\xf8\xbf:\xe7~\v\xc0\xe7\x98\xf9\x1dz/U\x988\xe7\xc0ݲ\x05\xa6\xf3\xb8k\xdf\xfe\x8ae\xa0\x14E\x8e^\xd1۴\xc9\x18\x8d\xf3\r\xef\xfd\xa7E\xe4\xe9\x8533\x15\xdb=\xb6@\xab\xae\xaf\xeaIZk\xc2[\v\x00\xc0\xc0Z\xb2>㝢\u007fǺd\xf4z\xac\xe6\xad\u007f\xdf\n<+\xe0b\x8bĎ\xf9vs\xe1\xec\xc2\xf9ç\x8e\xbf\x97\x88\x1e\x11\x91\xdf\x06\xf0\xcbDD\x03w\xf4\xc5|\xa0\x00\t3\xd8\t0N\xc8\xee\xae6\xf3\xb2q\x0e\x0eܯ\x05'\xd5\xcdغ@\x9ds\x90\xcb\x02j\t\x8a\xa2[YG:\xcfjq\x88ȳι\xaf\x8b\xc8\xdf\\8\xbb\xb0\xe7\x93\x15\xefY\x9a\x95e\x9fW{$\xc1\xde\u007f+,u\x9d\xd8{\x1e\xcd\xfd\"\x80\x87\x8e\x9c>\xf1~\x11\x99\n!\xbc[_k_\xd9@\xb6\x9a\xa1@ѷ\xfa\xb3\x1a\xb2\xfdu\xc8]\x02\xdc\x05`\x1f -AX\v\xa0\rB\xde\xee\xf4לȦ}\x13\x18\xec_犢\xf8\xec\xf2\xf4\xfc\x0fws\xben:A\xbe\xb4H\x9e\x06\xf0\xf4\x91\xd3'\x0e\x02\xf8(\x80_\x17\x91\xf7\xe9\x84\xeaD\xf5\xf2\x1e\xf2\"\xaf<\xf8q\xf6\x89\x1d\x1c\xb0Y\x9b\xd5`t\xa9\x81p\b\xe1\x99\x10\xc2_\xd4j\xb5g\x16'gw\xbf\x9d\xdf\xff\x03\x11\xfd\x0f\x80\t\x00\x9b\x04\x81}H\xac[%\x96\xfev\xac%\xbb\xdf\bb\a,O\xcf\x17\x00\xbez\xe4\xf4\x89s\x00>\x04\xe0#\"\xf2\x90\x88\xec\x8f\xcd\xfa,˰\xd6X\xad<\x1c:\xfe\xd8\xefo\xfc\xb7\x8b\xcc\xfcM\xe7\xdc\x17\x97\xa7\xe7\u05f7\xba\x06\"\xea0\xf3\xb7\x01T,\xd48\xbef\xad\x13+\x90\xad\xb6h\xcb}3\xf3\xb6\xfbC(\"\xb2Q\x14ŷc_\xb4]\x0f\"R\xb1\x9e\x00T\xae\xc5Z\xa5\x806/ʾ\xbf\xd3k\xdb\t\xe5\xc9\xeds\x00\xce\x1d:y\xec'E\xe4c\xcc\xfc\b\x80\a\xac&>X\xcf\xcd\x02\xfcr5\xb5?\x18\x97\xads\x0e\xc2\fq\x0e\x85\xb1\x06E\x04\x01C\x8f\x84\x18\xc5j\xa0<\x0e{\xe9|/˲o\x10\xd17\x17\xce\xccl\xbb\x15\xf5v\xd0\xf1ڴl\x1bطV\xa8\xae\x05\xfb\xba\n\xcaxO\xbc\x9e¸45\xf7\xef\x87N\x1e{\x0f\x11}\xd4{\xff83\xffb\b\xc1Ya\xc4\xc2謵@\xeb\xe5<\x995e\x15\x15+\xc8\xcb\xe7\xf0\xbcs\xeei\"\xfa\xd6\xe2\xe4\xecK{1_;V\xcf\x0e\x9f:~\x9f\x88\xbcOD\x1eȲ\xec\x01f>\x01\xa0\x06Ts\xe7\xad\x14\xb7n\x1f\xdb\r\xcbNH\x96e/2\xf3\xf3\x00\xbe\a\xe0\uf5e6\xe6n\xebBJ\x00\x87N\x1e\x1b\x03\xf0\xfe,\xcb>\"\"\x1fb\xe6{\xe3\x87V\x96*(\x00\x00\x05\x9fIDAT\xc6\nE\xbbї\x9f\x9fg\xe6\xa7\x00|\xeb\xc2م;\xbaQ&n\x8dç\x8e\xff,\x80\x0f\x028FDGC\bG\xbc\xf7\xfb\xac\xb0\xb6V\x9fM\x12Qb\xcb[\x85\xa8U*\x99\xb9\xc5\xccK\xde\xfb\xc5\x10\xc2\x02\x80\u007f\xbapv\xe1\xb6ƅ,\x87\xbep\xe2Q\xef\xfd\x93\xba7Yk\x11@\xe5\xb0\xe4VY\x95:F;G\xe5x\x9f\x9a\xff\xbd\x17>v\xa3\xbf\xffs\u007fp\xf4\xa0s\xeeWD\xe4\xe1,\xcb\x1e\x12\x91\x83V\x10\x01Մ\x0e\x9d\xf7\xf2\xef\x05\"z\x0e\xc0\xd3\xcc\xfcw\xcb\xd3\xf3;j\xa4w3\xecz\x0e\xe1\xd1?\xbc\u007f\\D\x8e3\xf3\x03Y\x96\xddW\x14\xc5O\x88\xc8A\xef\xfdA\":\xc8\xcc\a\xbd\xf7\x8e\x99WDd\x15\xc0\x8asn\x85\x88V\x99\xf9\xb5\x10\xc2\xf3ι\x17\x96\xa7\xe7\xb7l\xa1\x98\xb8s\x1c:y\xec\x00\x11\xddCD\xf7\x88\xc8=ι{\x01\xdc\x03`\x8c\x99/\x89\xc8%\"z\x13\xc0%\"z\xa3\xacŕ\x18\x01\x0e\x9d<\xe6\x88\xe8g\x9csG\x99\xf9(\x80{\x9ds\aD\xe4\x003\x1f \xa2\x03Y\x96\x1d`\xe6\x03!\x84}ι\x1637\xb2,k0s\x03@\x83\x99\x1bD\xd4@\u007f},\x02X\x04\xf0\x83\xa5\xa9\xb9\xdbW\x96\xe1\x06\x1c\xfe\xe2\xfd\x8f\x02x2N\x92\x897q\xebފcn\x83X\x84\xc9V\v!<\xb5\xf8\xa9\xf37\x14 \x96#\xa7Ox\x00?\r\xe0n\x00w\x17Eq\xb7\xf7\xfen\xef\xfdAf\xbe\x06\xe0\r\"\xba䜻\xc4\xcco\x88\xc8奩\xb9\xdb\xea\x1b\xbf=I\xe8\x89D\"\xf1c\xc0\xd1/\xbf\xfbQ\"z\xd2\xc65ĸ\xe84&d\xd3فj\x8cL\x05\x8e\xba\xe0K\xe1s\xcb\x02\xe4ǁۗ\x84\x9eH$\x12?\xe2\xd8TظK\xaa\x8d]\xe9\xf7\xb6\xaa֠Yfz>\xc8\xc6&F\x8d$@\x12\x89D\xa2\xc4\n\x0e\xa0Zj\xdd6\xbbR\x97\x96Z#63Ϟ_\xd2\xf7ܭl\xc0\x1f5\x92\x00I$\x12\x89\x12\x1b\xe8\xb7.)}M3\xa3\xac@\xb0\xf5\xf9\xe2\xb31q\xe2\xc0\xa8\x91\x04H\"\x91H\x94hv\x95\xcd\x1e\xb5\x99V6\x95\x1d\xa8\x96\xd9\x016\x17\x93̲\f\xbd^\uf39e\xf7\xd9K\x92\x00I$\x12\x89\x92\xb1N\x1d\xb5n\x86Z\x91A\xba\x02)L\ttS\x85B\xbf\x06\xaa\xe7CT\xd8h\xc5\r\x15\"\xa3*@v\xdei'\x91H$F\x84Z\xab\x86:\xeap\x9d\xe8lGF\xc89G6VC\xaf\xe8!\xab{xr`b\x88\xeb\xd7F\v\b@Vm\x8b\xa0Av[\xf6d\x94H\x02$\x91H$JB\b\xf0\xceo*S$\x85\xa0F5\xa0\x03Ըo\x9d\xd4|\xbf8\xac\xba\xb5\x802\x80N\xfd\x1ai\xf0\x00\x9c\x80\x89\xe1j\xa3\x19\x03I\x02$\x91H$JlI\x16%._\xa2'\xcd5\x0eb[X\x88\xf4\xab\xe0:\xa6\xb2\xb21\rʼ\x8f\"I\x80$\x12\x89\x84\xc1\x16\xe3\xb41\x0f[<Q\xcf{h\x8cC\xd1fxJ\xfc\x1e\xa3\xc6h:\xe6\x12\x89Db\x1blU 5>\x8d\xee\xbdG\xbd^\xaf\xa4\xf7\xdaC\x83\xa6\x04}\xa57\xcc(\x92\x04H\"\x91H\x94\xa8P\xb0\xc5\"m\xdf\x19\x1b\x1c\xb7\x02fll\xacr\xf8\xd0\xf6\x0f\xb11\x92Q#\t\x90D\"\x91(\xb1}^l\xd3(\xdb\xf7C\u007fFk]eY6(_\xa2B$nc\x11\xf7O\x1f\x15\x92\x00I$\x12\t\x83\xed壂\x01\xd8\xdc\xee\xd6V\xdbՒ&q\x8bY[|q\x14I\x02$\x91H$Jt\xc3W!\xa0օ\r\xa0\x03\xd8t\x98ЖqW\x01\xa3n/\xb5fF\x91\x94\x85\x95H$\x12\x06ku\xd8&x\x8a\xado\x15\xf7N\x8f\xddU\xea\xd6\xd2\xd8ɨ\x91\x04H\"\x91H\x94ؔ]-\x90\xa8\xc4}\xd0\xf55ۦ8n[\xac?kS}G\x89\xe4\xc2J$\x12\x89\x12kQ\xd86\xbc\xdavۦ\xee\xda~!\xb6d\xbb\xad\xd6k\xad\x94Q$\t\x90D\"\x91(\xb1\xc2\xc0\x16@̲l 0\xecY\x11k\xb1\xe8\x87E\xab\xfa\x8e\xaa\v+\t\x90D\"\x910ĥKl\tw\xb5(\xf4\xc0\xa0\x8do8\xe7*\x95wm<dT\x8b)\x8e\xe6\xa8\x12\x89Db\x9b\xc4\x19W\x8a\x9e0W\xc1\xa2\x8d\xa4,Z'K3\xaf⬭Qc4#;\x89D\"\xb1\r\xbc\xf7\bE@Q\x14\x95\x96\xb4궲=A\xb4\x0f\x88\xbe\xa65\xb4\xac\xf0Qa4\xaaq\x90d\x81$\x12\x89D\x89MŵYWZq\u05f6\xaf\xd5v\xb7\xde\xfb\x8a\xb5\xa1ߋ\x85\xc8(\x92,\x90D\"\x910h}+\x1b\xf3\xd0\xefٲ\xed\xeaʊ˟\xd8`\xba\xfd\xf9Q$Y \x89D\"\xa1\b\x02\x04\xa8\xd7\xea(\xf2\x02\x10@X\xc0\x81\xe1\xc8m\xfa<\x14\x01\x04\x02\x04\xe0\xc0\xe0\xc0 \xf3OX\xfa\x1f\"\xf9\x9d\x1e\xda^\x90,\x90D\"\x91(iu\x9a\xdf\aL\x89\x926W\x0e\x14Z\xb7\x94Z&\xfay\xadV\xab\x94n\xd7\x18IY\x0e\xe5\xbf\xef\xc4x\xf6\x9a$@\x12\x89D\xa2DSs\xe3\x02\x88\x1a8\xb7'\xd05E\xd7\xc6;\x00l\x126\x1a?\x19E\x92\v+\x91H$J4\x80\x1eB@\xadV\x1bX\x1f\xb60\xa2\n\x19\x15\x1c*h4F\x12\xc7?\xf4c\x14I\x16H\"\x91H\x948疙\xf9\x9d\x9ay\x05\xa0\x92\xaa\v\fO\xabk\xb7A[<\xd1\n\x16\xfd\xba\x14:Wn\xffh\x12\x89D\"\x91H$\x12\x89D\"\x91H$\x12\x89D\"\x91H$\x12\xdb\xe1\xff\x00a`\x0e\xb8q\xfd\x8e\xd6\x00\x00\x00\x00IEND\xaeB`\x82"),
321
        }
322
        file18 := &embedded.EmbeddedFile{
323
                Filename:    "tray.html",
324
                FileModTime: time.Unix(1535012730, 0),
325
                Content:     string("<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-355, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0\">\n{{if USE_CDN}}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://assets.statup.io/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css\" integrity=\"sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://assets.statup.io/base.css\">\n{{ else }}\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"/css/base.css\">\n{{end}}\n\n    <title>{{.Name}} Status</title>\n\n    <style>\n        BODY::-webkit-scrollbar { width: 0 !important }\n    </style>\n\n</head>\n<body>\n\n\n<div class=\"container col-12 sm-container\" style=\"margin-top: 0 !important;\">\n\n    <div class=\"col-12 full-col-12\">\n        <div class=\"list-group online_list\">\n        {{ range .Services }}\n            <a href=\"#\" class=\"service_li list-group-item list-group-item-action text-truncate {{if not .Online}}bg-danger text-white{{ end }}\" data-id=\"{{.Id}}\">\n            {{ .Name }}\n            {{if .Online}}\n                <span class=\"badge bg-success float-right pulse-glow\">ONLINE</span>\n            {{ else }}\n                <span class=\"badge bg-white text-black-50 float-right pulse\">OFFLINE</span>\n            {{end}}\n            </a>\n        {{ end }}\n        </div>\n    </div>\n\n    <div class=\"col-12 full-col-12\">\n    {{ range .Services }}\n        <div class=\"mt-4\" id=\"service_id_{{.Id}}\">\n            <div class=\"card\">\n                <div class=\"card-body\">\n                    <div class=\"col-12\">\n                        <h4 class=\"mt-3\"><a href=\"/service/{{.Id}}\"{{if not .Online}} class=\"text-danger\"{{end}}>{{ .Name }}</a>\n                        {{if .Online}}\n                            <span class=\"badge bg-success float-right\">ONLINE</span>\n                        {{ else }}\n                            <span class=\"badge bg-danger float-right pulse\">OFFLINE</span>\n                        {{end}}</h4>\n\n                        <div class=\"row stats_area mt-5 mb-5\">\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.Online24}}%</span>\n                                Online last 24 Hours\n                            </div>\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.AvgTime}}ms</span>\n                                Average Response\n                            </div>\n                            <div class=\"col-4\">\n                                <span class=\"lg_number\">{{.AvgUptime}}%</span>\n                                Total Uptime\n                            </div>\n                        </div>\n\n                    </div>\n                </div>\n            {{ if .AvgTime }}\n                <div class=\"chart-container\">\n                    <canvas id=\"service_{{ .Id }}\"></canvas>\n                </div>\n            {{ end }}\n                <div class=\"row lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}\">\n                    <div class=\"col-10 text-truncate\">\n                        <span class=\"d-none d-md-inline\">{{.SmallText}}</span>\n                    </div>\n                    <div class=\"col-sm-12 col-md-2\">\n\n                    </div>\n                </div>\n            </div>\n        </div>\n    {{ end }}\n    </div>\n</div>\n\n<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js\" integrity=\"sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js\"></script>\n<script src=\"https://assets.statup.io/main.js\"></script>\n\n<script src=\"/charts.js\"></script>\n\n</body>\n</html>"),
326
        }
327
        file19 := &embedded.EmbeddedFile{
328
                Filename:    "user.html",
329
                FileModTime: time.Unix(1538459587, 0),
330
                Content:     string("{{define \"title\"}}Statup | {{.Username}}{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <h3>User {{.Username}}</h3>\n        {{template \"form_user\" .}}\n    </div>\n</div>\n{{end}}\n"),
331
        }
332
        file1a := &embedded.EmbeddedFile{
333
                Filename:    "users.html",
334
                FileModTime: time.Unix(1538459610, 0),
335
                Content:     string("{{define \"title\"}}Statup | Users{{end}}\n{{define \"content\"}}\n<div class=\"container col-md-7 col-sm-12 mt-md-5 bg-light\">\n{{template \"nav\"}}\n    <div class=\"col-12\">\n        <h3>Users</h3>\n        <table class=\"table table-striped\">\n            <thead>\n            <tr>\n                <th scope=\"col\">Username</th>\n                <th scope=\"col\"></th>\n            </tr>\n            </thead>\n            <tbody>\n            {{range .}}\n            <tr>\n                <td>{{.Username}}</td>\n                <td class=\"text-right\" id=\"user_{{.Id}}\">\n                    <div class=\"btn-group\">\n                        <a href=\"/user/{{.Id}}\" class=\"btn btn-primary\">Edit</a>\n                        <a href=\"/user/{{.Id}}/delete\" class=\"btn btn-danger confirm-btn\" data-id=\"user_{{.Id}}\">Delete</a>\n                    </div>\n                </td>\n            </tr>\n            {{end}}\n            </tbody>\n        </table>\n\n        <h3>Create User</h3>\n\n        {{template \"form_user\" NewUser}}\n\n    </div>\n</div>\n{{end}}\n"),
336
        }
337
338
        // define dirs
339
        dirk := &embedded.EmbeddedDir{
340
                Filename:   "",
341
                DirModTime: time.Unix(1538970873, 0),
342
                ChildFiles: []*embedded.EmbeddedFile{
343
                        filel,  // "base.html"
344
                        filem,  // "dashboard.html"
345
                        filen,  // "error_404.html"
346
                        fileo,  // "favicon.ico"
347
                        filep,  // "footer.html"
348
                        fileq,  // "form_checkin.html"
349
                        filer,  // "form_notifier.html"
350
                        files,  // "form_service.html"
351
                        filet,  // "form_user.html"
352
                        fileu,  // "head.html"
353
                        filev,  // "help.html"
354
                        filew,  // "help.md"
355
                        filex,  // "index.html"
356
                        filey,  // "login.html"
357
                        filez,  // "logs.html"
358
                        file10, // "nav.html"
359
                        file11, // "robots.txt"
360
                        file12, // "scripts.html"
361
                        file13, // "service.html"
362
                        file14, // "services.html"
363
                        file15, // "settings.html"
364
                        file16, // "setup.html"
365
                        file17, // "statup.png"
366
                        file18, // "tray.html"
367
                        file19, // "user.html"
368
                        file1a, // "users.html"
369
370
                },
371
        }
372
373
        // link ChildDirs
374
        dirk.ChildDirs = []*embedded.EmbeddedDir{}
375
376
        // register embeddedBox
377
        embedded.RegisterEmbeddedBox(`tmpl`, &embedded.EmbeddedBox{
378
                Name: `tmpl`,
379
                Time: time.Unix(1538970873, 0),
380
                Dirs: map[string]*embedded.EmbeddedDir{
381
                        "": dirk,
382
                },
383
                Files: map[string]*embedded.EmbeddedFile{
384
                        "base.html":          filel,
385
                        "dashboard.html":     filem,
386
                        "error_404.html":     filen,
387
                        "favicon.ico":        fileo,
388
                        "footer.html":        filep,
389
                        "form_checkin.html":  fileq,
390
                        "form_notifier.html": filer,
391
                        "form_service.html":  files,
392
                        "form_user.html":     filet,
393
                        "head.html":          fileu,
394
                        "help.html":          filev,
395
                        "help.md":            filew,
396
                        "index.html":         filex,
397
                        "login.html":         filey,
398
                        "logs.html":          filez,
399
                        "nav.html":           file10,
400
                        "robots.txt":         file11,
401
                        "scripts.html":       file12,
402
                        "service.html":       file13,
403
                        "services.html":      file14,
404
                        "settings.html":      file15,
405
                        "setup.html":         file16,
406
                        "statup.png":         file17,
407
                        "tray.html":          file18,
408
                        "user.html":          file19,
409
                        "users.html":         file1a,
410
                },
411
        })
412
}
func CreateAllAssets
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/source/source.go:

152
func CreateAllAssets(folder string) error {
153
        utils.Log(1, fmt.Sprintf("Dump Statup assets into %v/assets", folder))
154
        MakePublicFolder(folder + "/assets")
155
        MakePublicFolder(folder + "/assets/js")
156
        MakePublicFolder(folder + "/assets/css")
157
        MakePublicFolder(folder + "/assets/scss")
158
        utils.Log(1, "Inserting scss, css, and javascript files into assets folder")
159
        CopyToPublic(ScssBox, folder+"/assets/scss", "base.scss")
160
        CopyToPublic(ScssBox, folder+"/assets/scss", "variables.scss")
161
        CopyToPublic(ScssBox, folder+"/assets/scss", "mobile.scss")
162
        CopyToPublic(ScssBox, folder+"/assets/scss", "pikaday.scss")
163
        CopyToPublic(CssBox, folder+"/assets/css", "bootstrap.min.css")
164
        CopyToPublic(CssBox, folder+"/assets/css", "base.css")
165
        //CopyToPublic(JsBox, folder+"/assets/js", "bootstrap.min.js")
166
        //CopyToPublic(JsBox, folder+"/assets/js", "Chart.bundle.min.js")
167
        //CopyToPublic(JsBox, folder+"/assets/js", "jquery-3.3.1.min.js")
168
        //CopyToPublic(JsBox, folder+"/assets/js", "sortable.min.js")
169
        //CopyToPublic(JsBox, folder+"/assets/js", "main.js")
170
        //CopyToPublic(JsBox, folder+"/assets/js", "setup.js")
171
        CopyToPublic(TmplBox, folder+"/assets", "robots.txt")
172
        CopyToPublic(TmplBox, folder+"/assets", "statup.png")
173
        utils.Log(1, "Compiling CSS from SCSS style...")
174
        err := utils.Log(1, "Statup assets have been inserted")
175
        return err
176
}
@@ -1652,7 +1692,7 @@ PACKAGE:github.com/hunterlong/statup/plugin DONE:33.33 57
func init() {
58
59
        // define files
60
        file6 := &embedded.EmbeddedFile{
61
                Filename:    "base.scss",
62
                FileModTime: time.Unix(1538106377, 0),
63
                Content:     string("/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n@import 'variables';\n\n\nHTML,BODY {\n    background-color: $background-color;\n}\n\n.container {\n    padding-top: 20px;\n    padding-bottom: 20px;\n    max-width: $max-width;\n}\n\n.header-title {\n    color: $title-color;\n}\n\n.header-desc {\n    color: $description-color;\n}\n\n.btn {\n    border-radius: $global-border-radius;\n}\n\n.online_list .badge {\n    margin-top: 0.2rem;\n}\n\n.navbar {\n    margin-bottom: 30px;\n}\n\n.btn-sm {\n    line-height: 1.3;\n    font-size: 0.75rem;\n}\n\n.view_service_btn {\n    position: absolute;\n    bottom: -40px;\n    right: 40px;\n}\n\n.service_lower_info {\n    position: absolute;\n    bottom: -40px;\n    left: 40px;\n    color: #d1ffca;\n    font-size: 0.85rem;\n}\n\n.lg_number {\n    font-size: $service-stats-size;\n    font-weight: bold;\n    display: block;\n    color: $service-stats-color;\n}\n\n.stats_area {\n    text-align: center;\n    color: #a5a5a5;\n}\n\n.lower_canvas {\n    height: 3.4rem;\n    width: 100%;\n    background-color: #48d338;\n    padding: 15px 10px;\n    margin-left: 0px !important;\n    margin-right: 0px !important;\n}\n\n.lower_canvas SPAN {\n    font-size: 1rem;\n    color: $service-description-color\n}\n\n.footer {\n    text-decoration: none;\n    margin-top: 20px;\n}\n\n.footer A {\n    color: $footer-text-color;\n    text-decoration: none;\n}\n\n.footer A:HOVER {\n    color: #6d6d6d;\n}\n\n.badge {\n    color: white;\n    border-radius: $global-border-radius;\n}\n\n.btn-group {\n    height: 25px;\n\n    & A {\n        padding: 0.1rem .75rem;\n        font-size: 0.8rem;\n    }\n}\n\n.card-body .badge {\n    color: #fff;\n}\n\n.nav-pills .nav-link {\n    border-radius: $global-border-radius;\n}\n\n.form-control {\n    border-radius: $global-border-radius;\n}\n\n.card {\n    background-color: $service-background;\n    border: $service-border;\n}\n\n.card-body {\n    overflow: hidden;\n}\n\n.card-body H4 A {\n    color: $service-title;\n    text-decoration: none;\n}\n\n.chart-container {\n  position: relative;\n  height: 170px;\n  width: 100%;\n}\n\n.service-chart-container {\n  position: relative;\n  height: 400px;\n  width: 100%;\n}\n\n@mixin dynamic-color-hov($color) {\n    &.dyn-dark {\n        background-color: darken($color, 12%) !important;\n        border-color: darken($color, 17%) !important;\n    }\n    &.dyn-dark:HOVER {\n        background-color: darken($color, 17%) !important;\n        border-color: darken($color, 20%) !important;\n    }\n    &.dyn-light {\n        background-color: lighten($color, 12%) !important;\n        border-color: lighten($color, 17%) !important;\n    }\n    &.dyn-light:HOVER {\n        background-color: lighten($color, 17%) !important;\n        border-color: lighten($color, 20%) !important;\n    }\n}\n\n@mixin dynamic-color($color) {\n    &.dyn-dark {\n        background-color: darken($color, 12%) !important;\n        border-color: darken($color, 17%) !important;\n    }\n    &.dyn-light {\n        background-color: lighten($color, 12%) !important;\n        border-color: lighten($color, 17%) !important;\n    }\n}\n\n\n.btn-primary {\n    background-color: $primary-color;\n    border-color: darken($primary-color, 17%);\n    color: white;\n    @include dynamic-color($success-color);\n}\n\n.btn-success {\n    background-color: $success-color;\n    @include dynamic-color($success-color);\n}\n\n.btn-danger {\n    background-color: $danger-color;\n    @include dynamic-color($danger-color);\n}\n\n.bg-success {\n    background-color: $success-color !important;\n}\n\n.bg-danger {\n    background-color: $danger-color !important;\n}\n\n.bg-success .dyn-dark {\n    background-color: darken($success-color, 10%) !important;\n}\n\n.bg-danger .dyn-dark {\n    background-color: darken($danger-color, 10%) !important;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show>.nav-link {\n    background-color: $nav-tab-color;\n}\n\n.nav-pills A {\n    color: #424242;\n}\n\n\n.CodeMirror {\n  /* Bootstrap Settings */\n  box-sizing: border-box;\n  margin: 0;\n  font: inherit;\n  overflow: auto;\n  font-family: inherit;\n  display: block;\n  width: 100%;\n  padding: 0px;\n  font-size: 14px;\n  line-height: 1.5;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  /* Code Mirror Settings */\n  font-family: monospace;\n  position: relative;\n  overflow: hidden;\n  height:80vh;\n}\n\n.CodeMirror-focused {\n  /* Bootstrap Settings */\n  border-color: #66afe9;\n  outline: 0;\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n\n.switch {\n  font-size: 1rem;\n  position: relative;\n}\n.switch input {\n  position: absolute;\n  height: 1px;\n  width: 1px;\n  background: none;\n  border: 0;\n  clip: rect(0 0 0 0);\n  clip-path: inset(50%);\n  overflow: hidden;\n  padding: 0;\n}\n.switch input + label {\n  position: relative;\n  min-width: calc(calc(2.375rem * .8) * 2);\n  border-radius: calc(2.375rem * .8);\n  height: calc(2.375rem * .8);\n  line-height: calc(2.375rem * .8);\n  display: inline-block;\n  cursor: pointer;\n  outline: none;\n  user-select: none;\n  vertical-align: middle;\n  text-indent: calc(calc(calc(2.375rem * .8) * 2) + .5rem);\n}\n.switch input + label::before,\n.switch input + label::after {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: calc(calc(2.375rem * .8) * 2);\n  bottom: 0;\n  display: block;\n}\n.switch input + label::before {\n  right: 0;\n  background-color: #dee2e6;\n  border-radius: calc(2.375rem * .8);\n  transition: 0.2s all;\n}\n.switch input + label::after {\n  top: 2px;\n  left: 2px;\n  width: calc(calc(2.375rem * .8) - calc(2px * 2));\n  height: calc(calc(2.375rem * .8) - calc(2px * 2));\n  border-radius: 50%;\n  background-color: white;\n  transition: 0.2s all;\n}\n.switch input:checked + label::before {\n  background-color: #08d;\n}\n.switch input:checked + label::after {\n  margin-left: calc(2.375rem * .8);\n}\n.switch input:focus + label::before {\n  outline: none;\n  box-shadow: 0 0 0 0.2rem rgba(0, 136, 221, 0.25);\n}\n.switch input:disabled + label {\n  color: #868e96;\n  cursor: not-allowed;\n}\n.switch input:disabled + label::before {\n  background-color: #e9ecef;\n}\n.switch.switch-sm {\n  font-size: 0.875rem;\n}\n.switch.switch-sm input + label {\n  min-width: calc(calc(1.9375rem * .8) * 2);\n  height: calc(1.9375rem * .8);\n  line-height: calc(1.9375rem * .8);\n  text-indent: calc(calc(calc(1.9375rem * .8) * 2) + .5rem);\n}\n.switch.switch-sm input + label::before {\n  width: calc(calc(1.9375rem * .8) * 2);\n}\n.switch.switch-sm input + label::after {\n  width: calc(calc(1.9375rem * .8) - calc(2px * 2));\n  height: calc(calc(1.9375rem * .8) - calc(2px * 2));\n}\n.switch.switch-sm input:checked + label::after {\n  margin-left: calc(1.9375rem * .8);\n}\n.switch.switch-lg {\n  font-size: 1.25rem;\n}\n.switch.switch-lg input + label {\n  min-width: calc(calc(3rem * .8) * 2);\n  height: calc(3rem * .8);\n  line-height: calc(3rem * .8);\n  text-indent: calc(calc(calc(3rem * .8) * 2) + .5rem);\n}\n.switch.switch-lg input + label::before {\n  width: calc(calc(3rem * .8) * 2);\n}\n.switch.switch-lg input + label::after {\n  width: calc(calc(3rem * .8) - calc(2px * 2));\n  height: calc(calc(3rem * .8) - calc(2px * 2));\n}\n.switch.switch-lg input:checked + label::after {\n  margin-left: calc(3rem * .8);\n}\n.switch + .switch {\n  margin-left: 1rem;\n}\n\n\n@keyframes pulse_animation {\n    0% { transform: scale(1); }\n    30% { transform: scale(1); }\n    40% { transform: scale(1.02); }\n    50% { transform: scale(1); }\n    60% { transform: scale(1); }\n    70% { transform: scale(1.05); }\n    80% { transform: scale(1); }\n    100% { transform: scale(1); }\n}\n\n.pulse {\n    animation-name: pulse_animation;\n    animation-duration: 1500ms;\n    transform-origin:70% 70%;\n    animation-iteration-count: infinite;\n    animation-timing-function: linear;\n}\n\n\n@keyframes glow-grow {\n  0% {\n    opacity: 0;\n    transform: scale(1);\n  }\n  80% {\n    opacity: 1;\n  }\n  100% {\n    transform: scale(2);\n    opacity: 0;\n  }\n}\n.pulse-glow {\n    animation-name: glow-grown;\n    animation-duration: 100ms;\n    transform-origin: 70% 30%;\n    animation-iteration-count: infinite;\n    animation-timing-function: linear;\n}\n\n.pulse-glow:before,\n.pulse-glow:after {\n    position: absolute;\n    content: '';\n    height: 0.5rem;\n    width: 1.75rem;\n    top: 1.2rem;\n    right: 2.15rem;\n    border-radius: 0;\n    box-shadow: 0 0 7px #47d337;\n    animation: glow-grow 2s ease-out infinite;\n}\n\n.sortable_drag {\n  background-color: #0000000f;\n}\n\n.drag_icon {\n  cursor: move; /* fallback if grab cursor is unsupported */\n  cursor: grab;\n  cursor: -moz-grab;\n  cursor: -webkit-grab;\n  width: 25px;\n  height: 25px;\n  display: inline-block;\n  margin-right: 5px;\n  margin-left: -10px;\n  text-align: center;\n  color: #b1b1b1;\n}\n\n/* (Optional) Apply a \"closed-hand\" cursor during drag operation. */\n.drag_icon:active {\n  cursor: grabbing;\n  cursor: -moz-grabbing;\n  cursor: -webkit-grabbing;\n}\n\n.switch_btn {\n  float: right;\n  margin: -1px 0px 0px 0px;\n  display: block;\n}\n\n#start_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px;\n}\n\n#end_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px;\n  right: 0;\n}\n\n.pointer {\n  cursor: pointer;\n}\n\n@import './pikaday';\n\n@import './mobile';\n"),
64
        }
65
        file7 := &embedded.EmbeddedFile{
66
                Filename:    "mobile.scss",
67
                FileModTime: time.Unix(1538106377, 0),
68
                Content:     string("/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n@media (max-width: 767px) {\n\n    HTML,BODY {\n        background-color: $sm-background-color;\n    }\n\n    .sm-container {\n        margin-top: 40px !important;\n        padding: 0 !important;\n    }\n\n    .list-group-item H5 {\n        font-size: 0.9rem;\n    }\n\n    .container {\n        padding: 0 !important;\n    }\n\n    .navbar {\n        margin-left: 0px;\n        margin-top: 0px;\n        width: 100%;\n        margin-bottom: 0;\n    }\n\n    .btn-sm {\n        line-height: 0.9rem;\n        font-size: 0.65rem;\n    }\n\n    .full-col-12 {\n        padding-left: 0px;\n        padding-right: 0px;\n    }\n\n    .card {\n        border: 0;\n        border-radius: $sm-border-radius;\n        padding: $sm-padding;\n        background-color: $sm-service-background;\n    }\n\n    .card-body {\n        font-size: 6pt;\n        padding: 5px 5px;\n    }\n\n    .lg_number {\n        font-size: 7.8vw;\n    }\n\n    .stats_area {\n        margin-top: 1.5rem !important;\n        margin-bottom: 1.5rem !important;\n    }\n\n    .stats_area .col-4 {\n        padding-left: 0;\n        padding-right: 0;\n        font-size: 0.6rem;\n    }\n\n    .list-group-item {\n        border-top: 1px solid #e4e4e4;\n        border: 0px;\n    }\n\n    .list-group-item:first-child {\n        border-top-left-radius: 0;\n        border-top-right-radius: 0;\n    }\n\n    .list-group-item:last-child {\n        border-bottom-right-radius: 0;\n        border-bottom-left-radius: 0;\n    }\n\n    .list-group-item P {\n        font-size: 0.7rem;\n    }\n\n    .service-chart-container {\n        height: 200px;\n    }\n}\n"),
69
        }
70
        file8 := &embedded.EmbeddedFile{
71
                Filename:    "pikaday.scss",
72
                FileModTime: time.Unix(1537243356, 0),
73
                Content:     string("/*!\n * Pikaday\n * Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/\n */\n\n// Variables\n// Declare any of these variables before importing this SCSS file to easily override defaults\n// Variables are namespaced with the pd (pikaday) prefix\n\n// Colours\n$pd-text-color: #333 !default;\n$pd-title-color: #333 !default;\n$pd-title-bg: #fff !default;\n$pd-picker-bg: #fff !default;\n$pd-picker-border: #ccc !default;\n$pd-picker-border-bottom: #bbb !default;\n$pd-picker-shadow: rgba(0,0,0,.5) !default;\n$pd-th-color: #999 !default;\n$pd-day-color: #666 !default;\n$pd-day-bg: #f5f5f5 !default;\n$pd-day-hover-color: #fff !default;\n$pd-day-hover-bg: #ff8000 !default;\n$pd-day-today-color: #33aaff !default;\n$pd-day-selected-color: #fff !default;\n$pd-day-selected-bg: #33aaff !default;\n$pd-day-selected-shadow: #178fe5 !default;\n$pd-day-disabled-color: #999 !default;\n$pd-week-color: #999 !default;\n\n// Font\n$pd-font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif !default;\n\n\n.pika-single {\n    z-index: 9999;\n    display: block;\n    position: relative;\n    color: $pd-text-color;\n    background: $pd-picker-bg;\n    border: 1px solid $pd-picker-border;\n    border-bottom-color: $pd-picker-border-bottom;\n    font-family: $pd-font-family;\n\n    &.is-hidden {\n        display: none;\n    }\n\n    &.is-bound {\n        position: absolute;\n        box-shadow: 0 5px 15px -5px $pd-picker-shadow;\n    }\n}\n\n// clear child float (pika-lendar), using the famous micro clearfix hack\n// http://nicolasgallagher.com/micro-clearfix-hack/\n.pika-single {\n    *zoom: 1;\n\n    &:before,\n    &:after {\n        content: \" \";\n        display: table;\n    }\n\n    &:after { clear: both }\n}\n\n.pika-lendar {\n    float: left;\n    width: 240px;\n    margin: 8px;\n}\n\n.pika-title {\n    position: relative;\n    text-align: center;\n\n    select {\n        cursor: pointer;\n        position: absolute;\n        z-index: 9998;\n        margin: 0;\n        left: 0;\n        top: 5px;\n        filter: alpha(opacity=0);\n        opacity: 0;\n    }\n}\n\n.pika-label {\n    display: inline-block;\n    *display: inline;\n    position: relative;\n    z-index: 9999;\n    overflow: hidden;\n    margin: 0;\n    padding: 5px 3px;\n    font-size: 14px;\n    line-height: 20px;\n    font-weight: bold;\n    color: $pd-title-color;\n    background-color: $pd-title-bg;\n}\n\n.pika-prev,\n.pika-next {\n    display: block;\n    cursor: pointer;\n    position: relative;\n    outline: none;\n    border: 0;\n    padding: 0;\n    width: 20px;\n    height: 30px;\n    text-indent: 20px; // hide text using text-indent trick, using width value (it's enough)\n    white-space: nowrap;\n    overflow: hidden;\n    background-color: transparent;\n    background-position: center center;\n    background-repeat: no-repeat;\n    background-size: 75% 75%;\n    opacity: .5;\n    *position: absolute;\n    *top: 0;\n\n    &:hover {\n        opacity: 1;\n    }\n\n    &.is-disabled {\n        cursor: default;\n        opacity: .2;\n    }\n}\n\n.pika-prev,\n.is-rtl .pika-next {\n    float: left;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');\n    *left: 0;\n}\n\n.pika-next,\n.is-rtl .pika-prev {\n    float: right;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');\n    *right: 0;\n}\n\n.pika-select {\n    display: inline-block;\n    *display: inline;\n}\n\n.pika-table {\n    width: 100%;\n    border-collapse: collapse;\n    border-spacing: 0;\n    border: 0;\n\n    th,\n    td {\n        width: 14.285714285714286%;\n        padding: 0;\n    }\n\n    th {\n        color: $pd-th-color;\n        font-size: 12px;\n        line-height: 25px;\n        font-weight: bold;\n        text-align: center;\n    }\n\n    abbr {\n        border-bottom: none;\n        cursor: help;\n    }\n}\n\n.pika-button {\n    cursor: pointer;\n    display: block;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    outline: none;\n    border: 0;\n    margin: 0;\n    width: 100%;\n    padding: 5px;\n    color: $pd-day-color;\n    font-size: 12px;\n    line-height: 15px;\n    text-align: right;\n    background: $pd-day-bg;\n\n    .is-today & {\n        color: $pd-day-today-color;\n        font-weight: bold;\n    }\n\n    .is-selected & {\n        color: $pd-day-selected-color;\n        font-weight: bold;\n        background: $pd-day-selected-bg;\n        box-shadow: inset 0 1px 3px $pd-day-selected-shadow;\n        border-radius: 3px;\n    }\n\n    .is-disabled &,\n    .is-outside-current-month & {        \n        color: $pd-day-disabled-color;\n        opacity: .3;\n    }\n\n    .is-disabled & {\n        pointer-events: none;\n        cursor: default;\n    }\n\n    &:hover {\n        color: $pd-day-hover-color;\n        background: $pd-day-hover-bg;\n        box-shadow: none;\n        border-radius: 3px;\n    }\n\n    .is-selection-disabled {\n        pointer-events: none;\n        cursor: default;\n    }\n}\n\n.pika-week {\n    font-size: 11px;\n    color: $pd-week-color;\n}\n\n.is-inrange .pika-button {\n    background: #D5E9F7;\n}\n\n.is-startrange .pika-button {\n    color: #fff;\n    background: #6CB31D;\n    box-shadow: none;\n    border-radius: 3px;\n}\n\n.is-endrange .pika-button {\n    color: #fff;\n    background: #33aaff;\n    box-shadow: none;\n    border-radius: 3px;\n}"),
74
        }
75
        file9 := &embedded.EmbeddedFile{
76
                Filename:    "variables.scss",
77
                FileModTime: time.Unix(1537299527, 0),
78
                Content:     string("/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/*    Index Page      */\n$background-color: #fcfcfc;\n$max-width: 860px;\n$title-color: #464646;\n$description-color: #939393;\n\n/*    Status Container   */\n$service-background: #ffffff;\n$service-border: 1px solid rgba(0,0,0,.125);\n$service-title: #444444;\n$service-stats-color: #4f4f4f;\n$service-description-color: #fff;\n$service-stats-size: 2.3rem;\n\n/*    Button Colors      */\n$success-color: #47d337;\n$danger-color: #dd3545;\n$primary-color: #3e9bff;\n\n/*   Footer Settings   */\n$footer-text-color: #8d8d8d;\n$nav-tab-color: #13a00d;\n$footer-display: block;\n\n/*   Global Settings */\n$global-border-radius: 0.2rem;\n\n\n/*   Mobile Settings   */\n$sm-background-color: #fcfcfc;\n$sm-border-radius: 0rem;\n\n/*   Mobile Service Container   */\n$sm-service-background: #ffffff;\n$sm-padding: 0;\n$sm-service-stats-size: 1.5rem;\n"),
79
        }
80
81
        // define dirs
82
        dir5 := &embedded.EmbeddedDir{
83
                Filename:   "",
84
                DirModTime: time.Unix(1538106377, 0),
85
                ChildFiles: []*embedded.EmbeddedFile{
86
                        file6, // "base.scss"
87
                        file7, // "mobile.scss"
88
                        file8, // "pikaday.scss"
89
                        file9, // "variables.scss"
90
91
                },
92
        }
93
94
        // link ChildDirs
95
        dir5.ChildDirs = []*embedded.EmbeddedDir{}
96
97
        // register embeddedBox
98
        embedded.RegisterEmbeddedBox(`scss`, &embedded.EmbeddedBox{
99
                Name: `scss`,
100
                Time: time.Unix(1538106377, 0),
101
                Dirs: map[string]*embedded.EmbeddedDir{
102
                        "": dir5,
103
                },
104
                Files: map[string]*embedded.EmbeddedFile{
105
                        "base.scss":      file6,
106
                        "mobile.scss":    file7,
107
                        "pikaday.scss":   file8,
108
                        "variables.scss": file9,
109
                },
110
        })
111
}
func init
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/source/rice-box.go:

-
8
func init() {
9
10
        // define files
11
        file2 := &embedded.EmbeddedFile{
12
                Filename:    "base.css",
13
                FileModTime: time.Unix(1538899462, 0),
14
                Content:     string("@charset \"UTF-8\";\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n/*    Index Page      */\n/*    Status Container   */\n/*    Button Colors      */\n/*   Footer Settings   */\n/*   Global Settings */\n/*   Mobile Settings   */\n/*   Mobile Service Container   */\nHTML, BODY {\n  background-color: #fcfcfc; }\n\n.container {\n  padding-top: 20px;\n  padding-bottom: 20px;\n  max-width: 860px; }\n\n.header-title {\n  color: #464646; }\n\n.header-desc {\n  color: #939393; }\n\n.btn {\n  border-radius: 0.2rem; }\n\n.online_list .badge {\n  margin-top: 0.2rem; }\n\n.navbar {\n  margin-bottom: 30px; }\n\n.btn-sm {\n  line-height: 1.3;\n  font-size: 0.75rem; }\n\n.view_service_btn {\n  position: absolute;\n  bottom: -40px;\n  right: 40px; }\n\n.service_lower_info {\n  position: absolute;\n  bottom: -40px;\n  left: 40px;\n  color: #d1ffca;\n  font-size: 0.85rem; }\n\n.lg_number {\n  font-size: 2.3rem;\n  font-weight: bold;\n  display: block;\n  color: #4f4f4f; }\n\n.stats_area {\n  text-align: center;\n  color: #a5a5a5; }\n\n.lower_canvas {\n  height: 3.4rem;\n  width: 100%;\n  background-color: #48d338;\n  padding: 15px 10px;\n  margin-left: 0px !important;\n  margin-right: 0px !important; }\n\n.lower_canvas SPAN {\n  font-size: 1rem;\n  color: #fff; }\n\n.footer {\n  text-decoration: none;\n  margin-top: 20px; }\n\n.footer A {\n  color: #8d8d8d;\n  text-decoration: none; }\n\n.footer A:HOVER {\n  color: #6d6d6d; }\n\n.badge {\n  color: white;\n  border-radius: 0.2rem; }\n\n.btn-group {\n  height: 25px; }\n  .btn-group A {\n    padding: 0.1rem .75rem;\n    font-size: 0.8rem; }\n\n.card-body .badge {\n  color: #fff; }\n\n.nav-pills .nav-link {\n  border-radius: 0.2rem; }\n\n.form-control {\n  border-radius: 0.2rem; }\n\n.card {\n  background-color: #ffffff;\n  border: 1px solid rgba(0, 0, 0, 0.125); }\n\n.card-body {\n  overflow: hidden; }\n\n.card-body H4 A {\n  color: #444444;\n  text-decoration: none; }\n\n.chart-container {\n  position: relative;\n  height: 170px;\n  width: 100%; }\n\n.service-chart-container {\n  position: relative;\n  height: 400px;\n  width: 100%; }\n\n.btn-primary {\n  background-color: #3e9bff;\n  border-color: #006fe6;\n  color: white; }\n  .btn-primary.dyn-dark {\n    background-color: #32a825 !important;\n    border-color: #2c9320 !important; }\n  .btn-primary.dyn-light {\n    background-color: #75de69 !important;\n    border-color: #88e37e !important; }\n\n.btn-success {\n  background-color: #47d337; }\n  .btn-success.dyn-dark {\n    background-color: #32a825 !important;\n    border-color: #2c9320 !important; }\n  .btn-success.dyn-light {\n    background-color: #75de69 !important;\n    border-color: #88e37e !important; }\n\n.btn-danger {\n  background-color: #dd3545; }\n  .btn-danger.dyn-dark {\n    background-color: #b61f2d !important;\n    border-color: #a01b28 !important; }\n  .btn-danger.dyn-light {\n    background-color: #e66975 !important;\n    border-color: #e97f89 !important; }\n\n.bg-success {\n  background-color: #47d337 !important; }\n\n.bg-danger {\n  background-color: #dd3545 !important; }\n\n.bg-success .dyn-dark {\n  background-color: #35b027 !important; }\n\n.bg-danger .dyn-dark {\n  background-color: #bf202f !important; }\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  background-color: #13a00d; }\n\n.nav-pills A {\n  color: #424242; }\n\n.CodeMirror {\n  /* Bootstrap Settings */\n  box-sizing: border-box;\n  margin: 0;\n  font: inherit;\n  overflow: auto;\n  font-family: inherit;\n  display: block;\n  width: 100%;\n  padding: 0px;\n  font-size: 14px;\n  line-height: 1.5;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  /* Code Mirror Settings */\n  font-family: monospace;\n  position: relative;\n  overflow: hidden;\n  height: 80vh; }\n\n.CodeMirror-focused {\n  /* Bootstrap Settings */\n  border-color: #66afe9;\n  outline: 0;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; }\n\n.switch {\n  font-size: 1rem;\n  position: relative; }\n\n.switch input {\n  position: absolute;\n  height: 1px;\n  width: 1px;\n  background: none;\n  border: 0;\n  clip: rect(0 0 0 0);\n  clip-path: inset(50%);\n  overflow: hidden;\n  padding: 0; }\n\n.switch input + label {\n  position: relative;\n  min-width: calc(calc(2.375rem * .8) * 2);\n  border-radius: calc(2.375rem * .8);\n  height: calc(2.375rem * .8);\n  line-height: calc(2.375rem * .8);\n  display: inline-block;\n  cursor: pointer;\n  outline: none;\n  user-select: none;\n  vertical-align: middle;\n  text-indent: calc(calc(calc(2.375rem * .8) * 2) + .5rem); }\n\n.switch input + label::before,\n.switch input + label::after {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: calc(calc(2.375rem * .8) * 2);\n  bottom: 0;\n  display: block; }\n\n.switch input + label::before {\n  right: 0;\n  background-color: #dee2e6;\n  border-radius: calc(2.375rem * .8);\n  transition: 0.2s all; }\n\n.switch input + label::after {\n  top: 2px;\n  left: 2px;\n  width: calc(calc(2.375rem * .8) - calc(2px * 2));\n  height: calc(calc(2.375rem * .8) - calc(2px * 2));\n  border-radius: 50%;\n  background-color: white;\n  transition: 0.2s all; }\n\n.switch input:checked + label::before {\n  background-color: #08d; }\n\n.switch input:checked + label::after {\n  margin-left: calc(2.375rem * .8); }\n\n.switch input:focus + label::before {\n  outline: none;\n  box-shadow: 0 0 0 0.2rem rgba(0, 136, 221, 0.25); }\n\n.switch input:disabled + label {\n  color: #868e96;\n  cursor: not-allowed; }\n\n.switch input:disabled + label::before {\n  background-color: #e9ecef; }\n\n.switch.switch-sm {\n  font-size: 0.875rem; }\n\n.switch.switch-sm input + label {\n  min-width: calc(calc(1.9375rem * .8) * 2);\n  height: calc(1.9375rem * .8);\n  line-height: calc(1.9375rem * .8);\n  text-indent: calc(calc(calc(1.9375rem * .8) * 2) + .5rem); }\n\n.switch.switch-sm input + label::before {\n  width: calc(calc(1.9375rem * .8) * 2); }\n\n.switch.switch-sm input + label::after {\n  width: calc(calc(1.9375rem * .8) - calc(2px * 2));\n  height: calc(calc(1.9375rem * .8) - calc(2px * 2)); }\n\n.switch.switch-sm input:checked + label::after {\n  margin-left: calc(1.9375rem * .8); }\n\n.switch.switch-lg {\n  font-size: 1.25rem; }\n\n.switch.switch-lg input + label {\n  min-width: calc(calc(3rem * .8) * 2);\n  height: calc(3rem * .8);\n  line-height: calc(3rem * .8);\n  text-indent: calc(calc(calc(3rem * .8) * 2) + .5rem); }\n\n.switch.switch-lg input + label::before {\n  width: calc(calc(3rem * .8) * 2); }\n\n.switch.switch-lg input + label::after {\n  width: calc(calc(3rem * .8) - calc(2px * 2));\n  height: calc(calc(3rem * .8) - calc(2px * 2)); }\n\n.switch.switch-lg input:checked + label::after {\n  margin-left: calc(3rem * .8); }\n\n.switch + .switch {\n  margin-left: 1rem; }\n\n@keyframes pulse_animation {\n  0% {\n    transform: scale(1); }\n  30% {\n    transform: scale(1); }\n  40% {\n    transform: scale(1.02); }\n  50% {\n    transform: scale(1); }\n  60% {\n    transform: scale(1); }\n  70% {\n    transform: scale(1.05); }\n  80% {\n    transform: scale(1); }\n  100% {\n    transform: scale(1); } }\n.pulse {\n  animation-name: pulse_animation;\n  animation-duration: 1500ms;\n  transform-origin: 70% 70%;\n  animation-iteration-count: infinite;\n  animation-timing-function: linear; }\n\n@keyframes glow-grow {\n  0% {\n    opacity: 0;\n    transform: scale(1); }\n  80% {\n    opacity: 1; }\n  100% {\n    transform: scale(2);\n    opacity: 0; } }\n.pulse-glow {\n  animation-name: glow-grown;\n  animation-duration: 100ms;\n  transform-origin: 70% 30%;\n  animation-iteration-count: infinite;\n  animation-timing-function: linear; }\n\n.pulse-glow:before,\n.pulse-glow:after {\n  position: absolute;\n  content: '';\n  height: 0.5rem;\n  width: 1.75rem;\n  top: 1.2rem;\n  right: 2.15rem;\n  border-radius: 0;\n  box-shadow: 0 0 7px #47d337;\n  animation: glow-grow 2s ease-out infinite; }\n\n.sortable_drag {\n  background-color: #0000000f; }\n\n.drag_icon {\n  cursor: move;\n  /* fallback if grab cursor is unsupported */\n  cursor: grab;\n  cursor: -moz-grab;\n  cursor: -webkit-grab;\n  width: 25px;\n  height: 25px;\n  display: inline-block;\n  margin-right: 5px;\n  margin-left: -10px;\n  text-align: center;\n  color: #b1b1b1; }\n\n/* (Optional) Apply a \"closed-hand\" cursor during drag operation. */\n.drag_icon:active {\n  cursor: grabbing;\n  cursor: -moz-grabbing;\n  cursor: -webkit-grabbing; }\n\n.switch_btn {\n  float: right;\n  margin: -1px 0px 0px 0px;\n  display: block; }\n\n#start_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px; }\n\n#end_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px;\n  right: 0; }\n\n.pointer {\n  cursor: pointer; }\n\n/*!\n * Pikaday\n * Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/\n */\n.pika-single {\n  z-index: 9999;\n  display: block;\n  position: relative;\n  color: #333;\n  background: #fff;\n  border: 1px solid #ccc;\n  border-bottom-color: #bbb;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif; }\n  .pika-single.is-hidden {\n    display: none; }\n  .pika-single.is-bound {\n    position: absolute;\n    box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.5); }\n\n.pika-single {\n  *zoom: 1; }\n  .pika-single:before, .pika-single:after {\n    content: \" \";\n    display: table; }\n  .pika-single:after {\n    clear: both; }\n\n.pika-lendar {\n  float: left;\n  width: 240px;\n  margin: 8px; }\n\n.pika-title {\n  position: relative;\n  text-align: center; }\n  .pika-title select {\n    cursor: pointer;\n    position: absolute;\n    z-index: 9998;\n    margin: 0;\n    left: 0;\n    top: 5px;\n    filter: alpha(opacity=0);\n    opacity: 0; }\n\n.pika-label {\n  display: inline-block;\n  *display: inline;\n  position: relative;\n  z-index: 9999;\n  overflow: hidden;\n  margin: 0;\n  padding: 5px 3px;\n  font-size: 14px;\n  line-height: 20px;\n  font-weight: bold;\n  color: #333;\n  background-color: #fff; }\n\n.pika-prev,\n.pika-next {\n  display: block;\n  cursor: pointer;\n  position: relative;\n  outline: none;\n  border: 0;\n  padding: 0;\n  width: 20px;\n  height: 30px;\n  text-indent: 20px;\n  white-space: nowrap;\n  overflow: hidden;\n  background-color: transparent;\n  background-position: center center;\n  background-repeat: no-repeat;\n  background-size: 75% 75%;\n  opacity: .5;\n  *position: absolute;\n  *top: 0; }\n  .pika-prev:hover,\n  .pika-next:hover {\n    opacity: 1; }\n  .pika-prev.is-disabled,\n  .pika-next.is-disabled {\n    cursor: default;\n    opacity: .2; }\n\n.pika-prev,\n.is-rtl .pika-next {\n  float: left;\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==\");\n  *left: 0; }\n\n.pika-next,\n.is-rtl .pika-prev {\n  float: right;\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=\");\n  *right: 0; }\n\n.pika-select {\n  display: inline-block;\n  *display: inline; }\n\n.pika-table {\n  width: 100%;\n  border-collapse: collapse;\n  border-spacing: 0;\n  border: 0; }\n  .pika-table th,\n  .pika-table td {\n    width: 14.285714285714286%;\n    padding: 0; }\n  .pika-table th {\n    color: #999;\n    font-size: 12px;\n    line-height: 25px;\n    font-weight: bold;\n    text-align: center; }\n  .pika-table abbr {\n    border-bottom: none;\n    cursor: help; }\n\n.pika-button {\n  cursor: pointer;\n  display: block;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  outline: none;\n  border: 0;\n  margin: 0;\n  width: 100%;\n  padding: 5px;\n  color: #666;\n  font-size: 12px;\n  line-height: 15px;\n  text-align: right;\n  background: #f5f5f5; }\n  .is-today .pika-button {\n    color: #33aaff;\n    font-weight: bold; }\n  .is-selected .pika-button {\n    color: #fff;\n    font-weight: bold;\n    background: #33aaff;\n    box-shadow: inset 0 1px 3px #178fe5;\n    border-radius: 3px; }\n  .is-disabled .pika-button, .is-outside-current-month .pika-button {\n    color: #999;\n    opacity: .3; }\n  .is-disabled .pika-button {\n    pointer-events: none;\n    cursor: default; }\n  .pika-button:hover {\n    color: #fff;\n    background: #ff8000;\n    box-shadow: none;\n    border-radius: 3px; }\n  .pika-button .is-selection-disabled {\n    pointer-events: none;\n    cursor: default; }\n\n.pika-week {\n  font-size: 11px;\n  color: #999; }\n\n.is-inrange .pika-button {\n  background: #D5E9F7; }\n\n.is-startrange .pika-button {\n  color: #fff;\n  background: #6CB31D;\n  box-shadow: none;\n  border-radius: 3px; }\n\n.is-endrange .pika-button {\n  color: #fff;\n  background: #33aaff;\n  box-shadow: none;\n  border-radius: 3px; }\n\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n@media (max-width: 767px) {\n  HTML, BODY {\n    background-color: #fcfcfc; }\n\n  .sm-container {\n    margin-top: 40px !important;\n    padding: 0 !important; }\n\n  .list-group-item H5 {\n    font-size: 0.9rem; }\n\n  .container {\n    padding: 0 !important; }\n\n  .navbar {\n    margin-left: 0px;\n    margin-top: 0px;\n    width: 100%;\n    margin-bottom: 0; }\n\n  .btn-sm {\n    line-height: 0.9rem;\n    font-size: 0.65rem; }\n\n  .full-col-12 {\n    padding-left: 0px;\n    padding-right: 0px; }\n\n  .card {\n    border: 0;\n    border-radius: 0rem;\n    padding: 0;\n    background-color: #ffffff; }\n\n  .card-body {\n    font-size: 6pt;\n    padding: 5px 5px; }\n\n  .lg_number {\n    font-size: 7.8vw; }\n\n  .stats_area {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important; }\n\n  .stats_area .col-4 {\n    padding-left: 0;\n    padding-right: 0;\n    font-size: 0.6rem; }\n\n  .list-group-item {\n    border-top: 1px solid #e4e4e4;\n    border: 0px; }\n\n  .list-group-item:first-child {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0; }\n\n  .list-group-item:last-child {\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0; }\n\n  .list-group-item P {\n    font-size: 0.7rem; }\n\n  .service-chart-container {\n    height: 200px; } }\n\n/*# sourceMappingURL=base.css.map */\n"),
15
        }
16
        file3 := &embedded.EmbeddedFile{
17
                Filename:    "base.css.map",
18
                FileModTime: time.Unix(1538899462, 0),
19
                Content:     string("{\n\"version\": 3,\n\"mappings\": \";AAAA;;;;;;;;;;;;;;;GAeG;ACfH;;;;;;;;;;;;;;;GAeG;AAEH,wBAAwB;AAMxB,2BAA2B;AAQ3B,2BAA2B;AAK3B,yBAAyB;AAKzB,uBAAuB;AAIvB,yBAAyB;AAIzB,kCAAkC;AD7BlC,UAAU;EACN,gBAAgB,ECHD,OAAO;;ADM1B,UAAW;EACP,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;EACpB,SAAS,ECRD,KAAK;;ADWjB,aAAc;EACV,KAAK,ECXK,OAAO;;ADcrB,YAAa;EACT,KAAK,ECdW,OAAO;;ADiB3B,IAAK;EACD,aAAa,ECGM,MAAM;;ADA7B,mBAAoB;EAChB,UAAU,EAAE,MAAM;;AAGtB,OAAQ;EACJ,aAAa,EAAE,IAAI;;AAGvB,OAAQ;EACJ,WAAW,EAAE,GAAG;EAChB,SAAS,EAAE,OAAO;;AAGtB,iBAAkB;EACd,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAGf,mBAAoB;EAChB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,IAAI,EAAE,IAAI;EACV,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,OAAO;;AAGtB,UAAW;EACP,SAAS,ECzCQ,MAAM;ED0CvB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,KAAK;EACd,KAAK,EC9Ca,OAAO;;ADiD7B,WAAY;EACR,UAAU,EAAE,MAAM;EAClB,KAAK,EAAE,OAAO;;AAGlB,aAAc;EACV,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,OAAO;EACzB,OAAO,EAAE,SAAS;EAClB,WAAW,EAAE,cAAc;EAC3B,YAAY,EAAE,cAAc;;AAGhC,kBAAmB;EACf,SAAS,EAAE,IAAI;EACf,KAAK,EChEmB,IAAI;;ADmEhC,OAAQ;EACJ,eAAe,EAAE,IAAI;EACrB,UAAU,EAAE,IAAI;;AAGpB,SAAU;EACN,KAAK,EChEW,OAAO;EDiEvB,eAAe,EAAE,IAAI;;AAGzB,eAAgB;EACZ,KAAK,EAAE,OAAO;;AAGlB,MAAO;EACH,KAAK,EAAE,KAAK;EACZ,aAAa,ECrEM,MAAM;;ADwE7B,UAAW;EACP,MAAM,EAAE,IAAI;EAEZ,YAAI;IACA,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,MAAM;;AAIzB,iBAAkB;EACd,KAAK,EAAE,IAAI;;AAGf,oBAAqB;EACjB,aAAa,ECtFM,MAAM;;ADyF7B,aAAc;EACV,aAAa,EC1FM,MAAM;;AD6F7B,KAAM;EACF,gBAAgB,EChHC,OAAO;EDiHxB,MAAM,EChHO,8BAA0B;;ADmH3C,UAAW;EACP,QAAQ,EAAE,MAAM;;AAGpB,eAAgB;EACZ,KAAK,ECvHO,OAAO;EDwHnB,eAAe,EAAE,IAAI;;AAGzB,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAGb,wBAAyB;EACvB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAkCb,YAAa;EACT,gBAAgB,EC/JJ,OAAO;EDgKnB,YAAY,EAAE,OAA2B;EACzC,KAAK,EAAE,KAAK;EAdZ,qBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,sBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAYrD,YAAa;EACT,gBAAgB,ECxKJ,OAAO;EDqJnB,qBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,sBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAiBrD,WAAY;EACR,gBAAgB,EC5KL,OAAO;EDoJlB,oBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,qBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAsBrD,WAAY;EACR,gBAAgB,EAAE,kBAAyB;;AAG/C,UAAW;EACP,gBAAgB,EAAE,kBAAwB;;AAG9C,qBAAsB;EAClB,gBAAgB,EAAE,kBAAsC;;AAG5D,oBAAqB;EACjB,gBAAgB,EAAE,kBAAqC;;AAG3D,yDAAwD;EACpD,gBAAgB,EC5LJ,OAAO;;AD+LvB,YAAa;EACT,KAAK,EAAE,OAAO;;AAIlB,WAAY;EACV,wBAAwB;EACxB,UAAU,EAAE,UAAU;EACtB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,OAAO;EACb,QAAQ,EAAE,IAAI;EACd,WAAW,EAAE,OAAO;EACpB,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,IAAI;EACtB,gBAAgB,EAAE,IAAI;EACtB,MAAM,EAAE,cAAc;EACtB,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,oCAAmC;EAC/C,UAAU,EAAE,0DAA0D;EACtE,0BAA0B;EAC1B,WAAW,EAAE,SAAS;EACtB,QAAQ,EAAE,QAAQ;EAClB,QAAQ,EAAE,MAAM;EAChB,MAAM,EAAC,IAAI;;AAGb,mBAAoB;EAClB,wBAAwB;EACxB,YAAY,EAAE,OAAO;EACrB,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,sEAAiE;EAC7E,UAAU,EAAE,0DAA0D;;AAGxE,OAAQ;EACN,SAAS,EAAE,IAAI;EACf,QAAQ,EAAE,QAAQ;;AAEpB,aAAc;EACZ,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,aAAa;EACnB,SAAS,EAAE,UAAU;EACrB,QAAQ,EAAE,MAAM;EAChB,OAAO,EAAE,CAAC;;AAEZ,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAClB,SAAS,EAAE,6BAA6B;EACxC,aAAa,EAAE,mBAAmB;EAClC,MAAM,EAAE,mBAAmB;EAC3B,WAAW,EAAE,mBAAmB;EAChC,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,MAAM;EACtB,WAAW,EAAE,2CAA2C;;AAE1D;4BAC6B;EAC3B,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,6BAA6B;EACpC,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,KAAK;;AAEhB,6BAA8B;EAC5B,KAAK,EAAE,CAAC;EACR,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,mBAAmB;EAClC,UAAU,EAAE,QAAQ;;AAEtB,4BAA6B;EAC3B,GAAG,EAAE,GAAG;EACR,IAAI,EAAE,GAAG;EACT,KAAK,EAAE,yCAAyC;EAChD,MAAM,EAAE,yCAAyC;EACjD,aAAa,EAAE,GAAG;EAClB,gBAAgB,EAAE,KAAK;EACvB,UAAU,EAAE,QAAQ;;AAEtB,qCAAsC;EACpC,gBAAgB,EAAE,IAAI;;AAExB,oCAAqC;EACnC,WAAW,EAAE,mBAAmB;;AAElC,mCAAoC;EAClC,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,oCAAoC;;AAElD,8BAA+B;EAC7B,KAAK,EAAE,OAAO;EACd,MAAM,EAAE,WAAW;;AAErB,sCAAuC;EACrC,gBAAgB,EAAE,OAAO;;AAE3B,iBAAkB;EAChB,SAAS,EAAE,QAAQ;;AAErB,+BAAgC;EAC9B,SAAS,EAAE,8BAA8B;EACzC,MAAM,EAAE,oBAAoB;EAC5B,WAAW,EAAE,oBAAoB;EACjC,WAAW,EAAE,4CAA4C;;AAE3D,uCAAwC;EACtC,KAAK,EAAE,8BAA8B;;AAEvC,sCAAuC;EACrC,KAAK,EAAE,0CAA0C;EACjD,MAAM,EAAE,0CAA0C;;AAEpD,8CAA+C;EAC7C,WAAW,EAAE,oBAAoB;;AAEnC,iBAAkB;EAChB,SAAS,EAAE,OAAO;;AAEpB,+BAAgC;EAC9B,SAAS,EAAE,yBAAyB;EACpC,MAAM,EAAE,eAAe;EACvB,WAAW,EAAE,eAAe;EAC5B,WAAW,EAAE,uCAAuC;;AAEtD,uCAAwC;EACtC,KAAK,EAAE,yBAAyB;;AAElC,sCAAuC;EACrC,KAAK,EAAE,qCAAqC;EAC5C,MAAM,EAAE,qCAAqC;;AAE/C,8CAA+C;EAC7C,WAAW,EAAE,eAAe;;AAE9B,iBAAkB;EAChB,WAAW,EAAE,IAAI;;AAInB,0BASC;EARG,EAAG;IAAE,SAAS,EAAE,QAAQ;EACxB,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,WAAW;EAC5B,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,WAAW;EAC5B,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,IAAK;IAAE,SAAS,EAAE,QAAQ;AAG9B,MAAO;EACH,cAAc,EAAE,eAAe;EAC/B,kBAAkB,EAAE,MAAM;EAC1B,gBAAgB,EAAC,OAAO;EACxB,yBAAyB,EAAE,QAAQ;EACnC,yBAAyB,EAAE,MAAM;;AAIrC,oBAYC;EAXC,EAAG;IACD,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,QAAQ;EAErB,GAAI;IACF,OAAO,EAAE,CAAC;EAEZ,IAAK;IACH,SAAS,EAAE,QAAQ;IACnB,OAAO,EAAE,CAAC;AAGd,WAAY;EACR,cAAc,EAAE,UAAU;EAC1B,kBAAkB,EAAE,KAAK;EACzB,gBAAgB,EAAE,OAAO;EACzB,yBAAyB,EAAE,QAAQ;EACnC,yBAAyB,EAAE,MAAM;;AAGrC;iBACkB;EACd,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,EAAE;EACX,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,OAAO;EACd,GAAG,EAAE,MAAM;EACX,KAAK,EAAE,OAAO;EACd,aAAa,EAAE,CAAC;EAChB,UAAU,EAAE,eAAe;EAC3B,SAAS,EAAE,8BAA8B;;AAG7C,cAAe;EACb,gBAAgB,EAAE,SAAS;;AAG7B,UAAW;EACT,MAAM,EAAE,IAAI;EAAE,4CAA4C;EAC1D,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,SAAS;EACjB,MAAM,EAAE,YAAY;EACpB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,GAAG;EACjB,WAAW,EAAE,KAAK;EAClB,UAAU,EAAE,MAAM;EAClB,KAAK,EAAE,OAAO;;AAGhB,oEAAoE;AACpE,iBAAkB;EAChB,MAAM,EAAE,QAAQ;EAChB,MAAM,EAAE,aAAa;EACrB,MAAM,EAAE,gBAAgB;;AAG1B,WAAY;EACV,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,gBAAgB;EACxB,OAAO,EAAE,KAAK;;AAGhB,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,KAAK;EACd,UAAU,EAAE,IAAI;;AAGlB,cAAe;EACb,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,KAAK;EACd,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,CAAC;;AAGV,QAAS;EACP,MAAM,EAAE,OAAO;;AEhejB;;;GAGG;AA8BH,YAAa;EACT,OAAO,EAAE,IAAI;EACb,OAAO,EAAE,KAAK;EACd,QAAQ,EAAE,QAAQ;EAClB,KAAK,EA3BO,IAAI;EA4BhB,UAAU,EAzBC,IAAI;EA0Bf,MAAM,EAAE,cAA2B;EACnC,mBAAmB,EAzBG,IAAI;EA0B1B,WAAW,EAXE,8CAA8C;EAa3D,sBAAY;IACR,OAAO,EAAE,IAAI;EAGjB,qBAAW;IACP,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,kCAAiC;;AAMrD,YAAa;EACT,KAAK,EAAE,CAAC;EAER,uCACQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;EAGlB,kBAAQ;IAAE,KAAK,EAAE,IAAI;;AAGzB,YAAa;EACT,KAAK,EAAE,IAAI;EACX,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,GAAG;;AAGf,WAAY;EACR,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,MAAM;EAElB,kBAAO;IACH,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,GAAG;IACR,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,CAAC;;AAIlB,WAAY;EACR,OAAO,EAAE,YAAY;EACrB,QAAQ,EAAE,MAAM;EAChB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,MAAM;EAChB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,OAAO;EAChB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,IAAI;EACjB,KAAK,EAzFQ,IAAI;EA0FjB,gBAAgB,EAzFN,IAAI;;AA4FlB;UACW;EACP,OAAO,EAAE,KAAK;EACd,MAAM,EAAE,OAAO;EACf,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,MAAM;EACnB,QAAQ,EAAE,MAAM;EAChB,gBAAgB,EAAE,WAAW;EAC7B,mBAAmB,EAAE,aAAa;EAClC,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,OAAO,EAAE,EAAE;EACX,SAAS,EAAE,QAAQ;EACnB,IAAI,EAAE,CAAC;EAEP;kBAAQ;IACJ,OAAO,EAAE,CAAC;EAGd;wBAAc;IACV,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,EAAE;;AAInB;kBACmB;EACf,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,yNAAyN;EAC3O,KAAK,EAAE,CAAC;;AAGZ;kBACmB;EACf,KAAK,EAAE,KAAK;EACZ,gBAAgB,EAAE,yNAAyN;EAC3O,MAAM,EAAE,CAAC;;AAGb,YAAa;EACT,OAAO,EAAE,YAAY;EACrB,QAAQ,EAAE,MAAM;;AAGpB,WAAY;EACR,KAAK,EAAE,IAAI;EACX,eAAe,EAAE,QAAQ;EACzB,cAAc,EAAE,CAAC;EACjB,MAAM,EAAE,CAAC;EAET;gBACG;IACC,KAAK,EAAE,mBAAmB;IAC1B,OAAO,EAAE,CAAC;EAGd,cAAG;IACC,KAAK,EAtJC,IAAI;IAuJV,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,MAAM;EAGtB,gBAAK;IACD,aAAa,EAAE,IAAI;IACnB,MAAM,EAAE,IAAI;;AAIpB,YAAa;EACT,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,KAAK;EACd,eAAe,EAAE,UAAU;EAC3B,UAAU,EAAE,UAAU;EACtB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,CAAC;EACT,MAAM,EAAE,CAAC;EACT,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,GAAG;EACZ,KAAK,EA5KM,IAAI;EA6Kf,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,KAAK;EACjB,UAAU,EA/KF,OAAO;EAiLf,sBAAY;IACR,KAAK,EA/KQ,OAAO;IAgLpB,WAAW,EAAE,IAAI;EAGrB,yBAAe;IACX,KAAK,EAnLW,IAAI;IAoLpB,WAAW,EAAE,IAAI;IACjB,UAAU,EApLG,OAAO;IAqLpB,UAAU,EAAE,uBAAuC;IACnD,aAAa,EAAE,GAAG;EAGtB,iEAC4B;IACxB,KAAK,EAzLW,IAAI;IA0LpB,OAAO,EAAE,EAAE;EAGf,yBAAe;IACX,cAAc,EAAE,IAAI;IACpB,MAAM,EAAE,OAAO;EAGnB,kBAAQ;IACJ,KAAK,EAzMQ,IAAI;IA0MjB,UAAU,EAzMA,OAAO;IA0MjB,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,GAAG;EAGtB,mCAAuB;IACnB,cAAc,EAAE,IAAI;IACpB,MAAM,EAAE,OAAO;;AAIvB,UAAW;EACP,SAAS,EAAE,IAAI;EACf,KAAK,EAhNO,IAAI;;AAmNpB,wBAAyB;EACrB,UAAU,EAAE,OAAO;;AAGvB,2BAA4B;EACxB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,GAAG;;AAGtB,yBAA0B;EACtB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,GAAG;;AC7PtB;;;;;;;;;;;;;;;GAeG;AAEH,yBAA0B;EAEtB,UAAU;IACN,gBAAgB,EF0BF,OAAO;;EEvBzB,aAAc;IACV,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,YAAY;;EAGzB,mBAAoB;IAChB,SAAS,EAAE,MAAM;;EAGrB,UAAW;IACP,OAAO,EAAE,YAAY;;EAGzB,OAAQ;IACJ,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,CAAC;;EAGpB,OAAQ;IACJ,WAAW,EAAE,MAAM;IACnB,SAAS,EAAE,OAAO;;EAGtB,YAAa;IACT,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;;EAGtB,KAAM;IACF,MAAM,EAAE,CAAC;IACT,aAAa,EFRF,IAAI;IESf,OAAO,EFLF,CAAC;IEMN,gBAAgB,EFPA,OAAO;;EEU3B,UAAW;IACP,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,OAAO;;EAGpB,UAAW;IACP,SAAS,EAAE,KAAK;;EAGpB,WAAY;IACR,UAAU,EAAE,iBAAiB;IAC7B,aAAa,EAAE,iBAAiB;;EAGpC,kBAAmB;IACf,YAAY,EAAE,CAAC;IACf,aAAa,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM;;EAGrB,gBAAiB;IACb,UAAU,EAAE,iBAAiB;IAC7B,MAAM,EAAE,GAAG;;EAGf,4BAA6B;IACzB,sBAAsB,EAAE,CAAC;IACzB,uBAAuB,EAAE,CAAC;;EAG9B,2BAA4B;IACxB,0BAA0B,EAAE,CAAC;IAC7B,yBAAyB,EAAE,CAAC;;EAGhC,kBAAmB;IACf,SAAS,EAAE,MAAM;;EAGrB,wBAAyB;IACrB,MAAM,EAAE,KAAK\",\n\"sources\": [\"../scss/base.scss\",\"../scss/variables.scss\",\"../scss/pikaday.scss\",\"../scss/mobile.scss\"],\n\"names\": [],\n\"file\": \"base.css\"\n}\n"),
20
        }
21
        file4 := &embedded.EmbeddedFile{
22
                Filename:    "bootstrap.min.css",
23
                FileModTime: time.Unix(1530208361, 0),
24
                Content:     string("/*!\n * Bootstrap v4.1.1 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex=\"-1\"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:\"\\2014 \\00A0\"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\"}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:\"\";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:\"\";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size=\"1\"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:\"Browse\"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:\"Browse\";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:\"\";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:\"/\"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{color:#000;text-decoration:none;opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:\"\";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:\"\";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:\"\";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-item-next,.carousel-item-prev,.carousel-item.active{transition:none}}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\")}.carousel-control-next-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:\"\"}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:\"\"}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:\"\"}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:\"\"}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:\" (\" attr(title) \")\"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}\n/*# sourceMappingURL=bootstrap.min.css.map */"),
25
        }
26
27
        // define dirs
28
        dir1 := &embedded.EmbeddedDir{
29
                Filename:   "",
30
                DirModTime: time.Unix(1538106376, 0),
31
                ChildFiles: []*embedded.EmbeddedFile{
32
                        file2, // "base.css"
33
                        file3, // "base.css.map"
34
                        file4, // "bootstrap.min.css"
35
36
                },
37
        }
38
39
        // link ChildDirs
40
        dir1.ChildDirs = []*embedded.EmbeddedDir{}
41
42
        // register embeddedBox
43
        embedded.RegisterEmbeddedBox(`css`, &embedded.EmbeddedBox{
44
                Name: `css`,
45
                Time: time.Unix(1538106376, 0),
46
                Dirs: map[string]*embedded.EmbeddedDir{
47
                        "": dir1,
48
                },
49
                Files: map[string]*embedded.EmbeddedFile{
50
                        "base.css":          file2,
51
                        "base.css.map":      file3,
52
                        "bootstrap.min.css": file4,
53
                },
54
        })
55
}
+8
func init() {
9
10
        // define files
11
        file2 := &embedded.EmbeddedFile{
12
                Filename:    "base.css",
13
                FileModTime: time.Unix(1539032000, 0),
14
                Content:     string("@charset \"UTF-8\";\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n/*    Index Page      */\n/*    Status Container   */\n/*    Button Colors      */\n/*   Footer Settings   */\n/*   Global Settings */\n/*   Mobile Settings   */\n/*   Mobile Service Container   */\nHTML, BODY {\n  background-color: #fcfcfc; }\n\n.container {\n  padding-top: 20px;\n  padding-bottom: 20px;\n  max-width: 860px; }\n\n.header-title {\n  color: #464646; }\n\n.header-desc {\n  color: #939393; }\n\n.btn {\n  border-radius: 0.2rem; }\n\n.online_list .badge {\n  margin-top: 0.2rem; }\n\n.navbar {\n  margin-bottom: 30px; }\n\n.btn-sm {\n  line-height: 1.3;\n  font-size: 0.75rem; }\n\n.view_service_btn {\n  position: absolute;\n  bottom: -40px;\n  right: 40px; }\n\n.service_lower_info {\n  position: absolute;\n  bottom: -40px;\n  left: 40px;\n  color: #d1ffca;\n  font-size: 0.85rem; }\n\n.lg_number {\n  font-size: 2.3rem;\n  font-weight: bold;\n  display: block;\n  color: #4f4f4f; }\n\n.stats_area {\n  text-align: center;\n  color: #a5a5a5; }\n\n.lower_canvas {\n  height: 3.4rem;\n  width: 100%;\n  background-color: #48d338;\n  padding: 15px 10px;\n  margin-left: 0px !important;\n  margin-right: 0px !important; }\n\n.lower_canvas SPAN {\n  font-size: 1rem;\n  color: #fff; }\n\n.footer {\n  text-decoration: none;\n  margin-top: 20px; }\n\n.footer A {\n  color: #8d8d8d;\n  text-decoration: none; }\n\n.footer A:HOVER {\n  color: #6d6d6d; }\n\n.badge {\n  color: white;\n  border-radius: 0.2rem; }\n\n.btn-group {\n  height: 25px; }\n  .btn-group A {\n    padding: 0.1rem .75rem;\n    font-size: 0.8rem; }\n\n.card-body .badge {\n  color: #fff; }\n\n.nav-pills .nav-link {\n  border-radius: 0.2rem; }\n\n.form-control {\n  border-radius: 0.2rem; }\n\n.card {\n  background-color: #ffffff;\n  border: 1px solid rgba(0, 0, 0, 0.125); }\n\n.card-body {\n  overflow: hidden; }\n\n.card-body H4 A {\n  color: #444444;\n  text-decoration: none; }\n\n.chart-container {\n  position: relative;\n  height: 170px;\n  width: 100%; }\n\n.service-chart-container {\n  position: relative;\n  height: 400px;\n  width: 100%; }\n\n.btn-primary {\n  background-color: #3e9bff;\n  border-color: #006fe6;\n  color: white; }\n  .btn-primary.dyn-dark {\n    background-color: #32a825 !important;\n    border-color: #2c9320 !important; }\n  .btn-primary.dyn-light {\n    background-color: #75de69 !important;\n    border-color: #88e37e !important; }\n\n.btn-success {\n  background-color: #47d337; }\n  .btn-success.dyn-dark {\n    background-color: #32a825 !important;\n    border-color: #2c9320 !important; }\n  .btn-success.dyn-light {\n    background-color: #75de69 !important;\n    border-color: #88e37e !important; }\n\n.btn-danger {\n  background-color: #dd3545; }\n  .btn-danger.dyn-dark {\n    background-color: #b61f2d !important;\n    border-color: #a01b28 !important; }\n  .btn-danger.dyn-light {\n    background-color: #e66975 !important;\n    border-color: #e97f89 !important; }\n\n.bg-success {\n  background-color: #47d337 !important; }\n\n.bg-danger {\n  background-color: #dd3545 !important; }\n\n.bg-success .dyn-dark {\n  background-color: #35b027 !important; }\n\n.bg-danger .dyn-dark {\n  background-color: #bf202f !important; }\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  background-color: #13a00d; }\n\n.nav-pills A {\n  color: #424242; }\n\n.CodeMirror {\n  /* Bootstrap Settings */\n  box-sizing: border-box;\n  margin: 0;\n  font: inherit;\n  overflow: auto;\n  font-family: inherit;\n  display: block;\n  width: 100%;\n  padding: 0px;\n  font-size: 14px;\n  line-height: 1.5;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  /* Code Mirror Settings */\n  font-family: monospace;\n  position: relative;\n  overflow: hidden;\n  height: 80vh; }\n\n.CodeMirror-focused {\n  /* Bootstrap Settings */\n  border-color: #66afe9;\n  outline: 0;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; }\n\n.switch {\n  font-size: 1rem;\n  position: relative; }\n\n.switch input {\n  position: absolute;\n  height: 1px;\n  width: 1px;\n  background: none;\n  border: 0;\n  clip: rect(0 0 0 0);\n  clip-path: inset(50%);\n  overflow: hidden;\n  padding: 0; }\n\n.switch input + label {\n  position: relative;\n  min-width: calc(calc(2.375rem * .8) * 2);\n  border-radius: calc(2.375rem * .8);\n  height: calc(2.375rem * .8);\n  line-height: calc(2.375rem * .8);\n  display: inline-block;\n  cursor: pointer;\n  outline: none;\n  user-select: none;\n  vertical-align: middle;\n  text-indent: calc(calc(calc(2.375rem * .8) * 2) + .5rem); }\n\n.switch input + label::before,\n.switch input + label::after {\n  content: '';\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: calc(calc(2.375rem * .8) * 2);\n  bottom: 0;\n  display: block; }\n\n.switch input + label::before {\n  right: 0;\n  background-color: #dee2e6;\n  border-radius: calc(2.375rem * .8);\n  transition: 0.2s all; }\n\n.switch input + label::after {\n  top: 2px;\n  left: 2px;\n  width: calc(calc(2.375rem * .8) - calc(2px * 2));\n  height: calc(calc(2.375rem * .8) - calc(2px * 2));\n  border-radius: 50%;\n  background-color: white;\n  transition: 0.2s all; }\n\n.switch input:checked + label::before {\n  background-color: #08d; }\n\n.switch input:checked + label::after {\n  margin-left: calc(2.375rem * .8); }\n\n.switch input:focus + label::before {\n  outline: none;\n  box-shadow: 0 0 0 0.2rem rgba(0, 136, 221, 0.25); }\n\n.switch input:disabled + label {\n  color: #868e96;\n  cursor: not-allowed; }\n\n.switch input:disabled + label::before {\n  background-color: #e9ecef; }\n\n.switch.switch-sm {\n  font-size: 0.875rem; }\n\n.switch.switch-sm input + label {\n  min-width: calc(calc(1.9375rem * .8) * 2);\n  height: calc(1.9375rem * .8);\n  line-height: calc(1.9375rem * .8);\n  text-indent: calc(calc(calc(1.9375rem * .8) * 2) + .5rem); }\n\n.switch.switch-sm input + label::before {\n  width: calc(calc(1.9375rem * .8) * 2); }\n\n.switch.switch-sm input + label::after {\n  width: calc(calc(1.9375rem * .8) - calc(2px * 2));\n  height: calc(calc(1.9375rem * .8) - calc(2px * 2)); }\n\n.switch.switch-sm input:checked + label::after {\n  margin-left: calc(1.9375rem * .8); }\n\n.switch.switch-lg {\n  font-size: 1.25rem; }\n\n.switch.switch-lg input + label {\n  min-width: calc(calc(3rem * .8) * 2);\n  height: calc(3rem * .8);\n  line-height: calc(3rem * .8);\n  text-indent: calc(calc(calc(3rem * .8) * 2) + .5rem); }\n\n.switch.switch-lg input + label::before {\n  width: calc(calc(3rem * .8) * 2); }\n\n.switch.switch-lg input + label::after {\n  width: calc(calc(3rem * .8) - calc(2px * 2));\n  height: calc(calc(3rem * .8) - calc(2px * 2)); }\n\n.switch.switch-lg input:checked + label::after {\n  margin-left: calc(3rem * .8); }\n\n.switch + .switch {\n  margin-left: 1rem; }\n\n@keyframes pulse_animation {\n  0% {\n    transform: scale(1); }\n  30% {\n    transform: scale(1); }\n  40% {\n    transform: scale(1.02); }\n  50% {\n    transform: scale(1); }\n  60% {\n    transform: scale(1); }\n  70% {\n    transform: scale(1.05); }\n  80% {\n    transform: scale(1); }\n  100% {\n    transform: scale(1); } }\n.pulse {\n  animation-name: pulse_animation;\n  animation-duration: 1500ms;\n  transform-origin: 70% 70%;\n  animation-iteration-count: infinite;\n  animation-timing-function: linear; }\n\n@keyframes glow-grow {\n  0% {\n    opacity: 0;\n    transform: scale(1); }\n  80% {\n    opacity: 1; }\n  100% {\n    transform: scale(2);\n    opacity: 0; } }\n.pulse-glow {\n  animation-name: glow-grown;\n  animation-duration: 100ms;\n  transform-origin: 70% 30%;\n  animation-iteration-count: infinite;\n  animation-timing-function: linear; }\n\n.pulse-glow:before,\n.pulse-glow:after {\n  position: absolute;\n  content: '';\n  height: 0.5rem;\n  width: 1.75rem;\n  top: 1.2rem;\n  right: 2.15rem;\n  border-radius: 0;\n  box-shadow: 0 0 7px #47d337;\n  animation: glow-grow 2s ease-out infinite; }\n\n.sortable_drag {\n  background-color: #0000000f; }\n\n.drag_icon {\n  cursor: move;\n  /* fallback if grab cursor is unsupported */\n  cursor: grab;\n  cursor: -moz-grab;\n  cursor: -webkit-grab;\n  width: 25px;\n  height: 25px;\n  display: inline-block;\n  margin-right: 5px;\n  margin-left: -10px;\n  text-align: center;\n  color: #b1b1b1; }\n\n/* (Optional) Apply a \"closed-hand\" cursor during drag operation. */\n.drag_icon:active {\n  cursor: grabbing;\n  cursor: -moz-grabbing;\n  cursor: -webkit-grabbing; }\n\n.switch_btn {\n  float: right;\n  margin: -1px 0px 0px 0px;\n  display: block; }\n\n#start_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px; }\n\n#end_container {\n  position: absolute;\n  z-index: 99999;\n  margin-top: 20px;\n  right: 0; }\n\n.pointer {\n  cursor: pointer; }\n\n/*!\n * Pikaday\n * Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/\n */\n.pika-single {\n  z-index: 9999;\n  display: block;\n  position: relative;\n  color: #333;\n  background: #fff;\n  border: 1px solid #ccc;\n  border-bottom-color: #bbb;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif; }\n  .pika-single.is-hidden {\n    display: none; }\n  .pika-single.is-bound {\n    position: absolute;\n    box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.5); }\n\n.pika-single {\n  *zoom: 1; }\n  .pika-single:before, .pika-single:after {\n    content: \" \";\n    display: table; }\n  .pika-single:after {\n    clear: both; }\n\n.pika-lendar {\n  float: left;\n  width: 240px;\n  margin: 8px; }\n\n.pika-title {\n  position: relative;\n  text-align: center; }\n  .pika-title select {\n    cursor: pointer;\n    position: absolute;\n    z-index: 9998;\n    margin: 0;\n    left: 0;\n    top: 5px;\n    filter: alpha(opacity=0);\n    opacity: 0; }\n\n.pika-label {\n  display: inline-block;\n  *display: inline;\n  position: relative;\n  z-index: 9999;\n  overflow: hidden;\n  margin: 0;\n  padding: 5px 3px;\n  font-size: 14px;\n  line-height: 20px;\n  font-weight: bold;\n  color: #333;\n  background-color: #fff; }\n\n.pika-prev,\n.pika-next {\n  display: block;\n  cursor: pointer;\n  position: relative;\n  outline: none;\n  border: 0;\n  padding: 0;\n  width: 20px;\n  height: 30px;\n  text-indent: 20px;\n  white-space: nowrap;\n  overflow: hidden;\n  background-color: transparent;\n  background-position: center center;\n  background-repeat: no-repeat;\n  background-size: 75% 75%;\n  opacity: .5;\n  *position: absolute;\n  *top: 0; }\n  .pika-prev:hover,\n  .pika-next:hover {\n    opacity: 1; }\n  .pika-prev.is-disabled,\n  .pika-next.is-disabled {\n    cursor: default;\n    opacity: .2; }\n\n.pika-prev,\n.is-rtl .pika-next {\n  float: left;\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==\");\n  *left: 0; }\n\n.pika-next,\n.is-rtl .pika-prev {\n  float: right;\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=\");\n  *right: 0; }\n\n.pika-select {\n  display: inline-block;\n  *display: inline; }\n\n.pika-table {\n  width: 100%;\n  border-collapse: collapse;\n  border-spacing: 0;\n  border: 0; }\n  .pika-table th,\n  .pika-table td {\n    width: 14.285714285714286%;\n    padding: 0; }\n  .pika-table th {\n    color: #999;\n    font-size: 12px;\n    line-height: 25px;\n    font-weight: bold;\n    text-align: center; }\n  .pika-table abbr {\n    border-bottom: none;\n    cursor: help; }\n\n.pika-button {\n  cursor: pointer;\n  display: block;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  outline: none;\n  border: 0;\n  margin: 0;\n  width: 100%;\n  padding: 5px;\n  color: #666;\n  font-size: 12px;\n  line-height: 15px;\n  text-align: right;\n  background: #f5f5f5; }\n  .is-today .pika-button {\n    color: #33aaff;\n    font-weight: bold; }\n  .is-selected .pika-button {\n    color: #fff;\n    font-weight: bold;\n    background: #33aaff;\n    box-shadow: inset 0 1px 3px #178fe5;\n    border-radius: 3px; }\n  .is-disabled .pika-button, .is-outside-current-month .pika-button {\n    color: #999;\n    opacity: .3; }\n  .is-disabled .pika-button {\n    pointer-events: none;\n    cursor: default; }\n  .pika-button:hover {\n    color: #fff;\n    background: #ff8000;\n    box-shadow: none;\n    border-radius: 3px; }\n  .pika-button .is-selection-disabled {\n    pointer-events: none;\n    cursor: default; }\n\n.pika-week {\n  font-size: 11px;\n  color: #999; }\n\n.is-inrange .pika-button {\n  background: #D5E9F7; }\n\n.is-startrange .pika-button {\n  color: #fff;\n  background: #6CB31D;\n  box-shadow: none;\n  border-radius: 3px; }\n\n.is-endrange .pika-button {\n  color: #fff;\n  background: #33aaff;\n  box-shadow: none;\n  border-radius: 3px; }\n\n/*!\n * Statup\n * Copyright (C) 2018.  Hunter Long and the project contributors\n * Written by Hunter Long <info@socialeck.com> and the project contributors\n *\n * https://github.com/hunterlong/statup\n *\n * The licenses for most software and other practical works are designed\n * to take away your freedom to share and change the works.  By contrast,\n * the GNU General Public License is intended to guarantee your freedom to\n * share and change all versions of a program--to make sure it remains free\n * software for all its users.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n@media (max-width: 767px) {\n  HTML, BODY {\n    background-color: #fcfcfc; }\n\n  .sm-container {\n    margin-top: 40px !important;\n    padding: 0 !important; }\n\n  .list-group-item H5 {\n    font-size: 0.9rem; }\n\n  .container {\n    padding: 0 !important; }\n\n  .navbar {\n    margin-left: 0px;\n    margin-top: 0px;\n    width: 100%;\n    margin-bottom: 0; }\n\n  .btn-sm {\n    line-height: 0.9rem;\n    font-size: 0.65rem; }\n\n  .full-col-12 {\n    padding-left: 0px;\n    padding-right: 0px; }\n\n  .card {\n    border: 0;\n    border-radius: 0rem;\n    padding: 0;\n    background-color: #ffffff; }\n\n  .card-body {\n    font-size: 6pt;\n    padding: 5px 5px; }\n\n  .lg_number {\n    font-size: 7.8vw; }\n\n  .stats_area {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important; }\n\n  .stats_area .col-4 {\n    padding-left: 0;\n    padding-right: 0;\n    font-size: 0.6rem; }\n\n  .list-group-item {\n    border-top: 1px solid #e4e4e4;\n    border: 0px; }\n\n  .list-group-item:first-child {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0; }\n\n  .list-group-item:last-child {\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0; }\n\n  .list-group-item P {\n    font-size: 0.7rem; }\n\n  .service-chart-container {\n    height: 200px; } }\n\n/*# sourceMappingURL=base.css.map */\n"),
15
        }
16
        file3 := &embedded.EmbeddedFile{
17
                Filename:    "base.css.map",
18
                FileModTime: time.Unix(1539032000, 0),
19
                Content:     string("{\n\"version\": 3,\n\"mappings\": \";AAAA;;;;;;;;;;;;;;;GAeG;ACfH;;;;;;;;;;;;;;;GAeG;AAEH,wBAAwB;AAMxB,2BAA2B;AAQ3B,2BAA2B;AAK3B,yBAAyB;AAKzB,uBAAuB;AAIvB,yBAAyB;AAIzB,kCAAkC;AD7BlC,UAAU;EACN,gBAAgB,ECHD,OAAO;;ADM1B,UAAW;EACP,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;EACpB,SAAS,ECRD,KAAK;;ADWjB,aAAc;EACV,KAAK,ECXK,OAAO;;ADcrB,YAAa;EACT,KAAK,ECdW,OAAO;;ADiB3B,IAAK;EACD,aAAa,ECGM,MAAM;;ADA7B,mBAAoB;EAChB,UAAU,EAAE,MAAM;;AAGtB,OAAQ;EACJ,aAAa,EAAE,IAAI;;AAGvB,OAAQ;EACJ,WAAW,EAAE,GAAG;EAChB,SAAS,EAAE,OAAO;;AAGtB,iBAAkB;EACd,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAGf,mBAAoB;EAChB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,IAAI,EAAE,IAAI;EACV,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,OAAO;;AAGtB,UAAW;EACP,SAAS,ECzCQ,MAAM;ED0CvB,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,KAAK;EACd,KAAK,EC9Ca,OAAO;;ADiD7B,WAAY;EACR,UAAU,EAAE,MAAM;EAClB,KAAK,EAAE,OAAO;;AAGlB,aAAc;EACV,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,OAAO;EACzB,OAAO,EAAE,SAAS;EAClB,WAAW,EAAE,cAAc;EAC3B,YAAY,EAAE,cAAc;;AAGhC,kBAAmB;EACf,SAAS,EAAE,IAAI;EACf,KAAK,EChEmB,IAAI;;ADmEhC,OAAQ;EACJ,eAAe,EAAE,IAAI;EACrB,UAAU,EAAE,IAAI;;AAGpB,SAAU;EACN,KAAK,EChEW,OAAO;EDiEvB,eAAe,EAAE,IAAI;;AAGzB,eAAgB;EACZ,KAAK,EAAE,OAAO;;AAGlB,MAAO;EACH,KAAK,EAAE,KAAK;EACZ,aAAa,ECrEM,MAAM;;ADwE7B,UAAW;EACP,MAAM,EAAE,IAAI;EAEZ,YAAI;IACA,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,MAAM;;AAIzB,iBAAkB;EACd,KAAK,EAAE,IAAI;;AAGf,oBAAqB;EACjB,aAAa,ECtFM,MAAM;;ADyF7B,aAAc;EACV,aAAa,EC1FM,MAAM;;AD6F7B,KAAM;EACF,gBAAgB,EChHC,OAAO;EDiHxB,MAAM,EChHO,8BAA0B;;ADmH3C,UAAW;EACP,QAAQ,EAAE,MAAM;;AAGpB,eAAgB;EACZ,KAAK,ECvHO,OAAO;EDwHnB,eAAe,EAAE,IAAI;;AAGzB,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAGb,wBAAyB;EACvB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,IAAI;;AAkCb,YAAa;EACT,gBAAgB,EC/JJ,OAAO;EDgKnB,YAAY,EAAE,OAA2B;EACzC,KAAK,EAAE,KAAK;EAdZ,qBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,sBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAYrD,YAAa;EACT,gBAAgB,ECxKJ,OAAO;EDqJnB,qBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,sBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAiBrD,WAAY;EACR,gBAAgB,EC5KL,OAAO;EDoJlB,oBAAW;IACP,gBAAgB,EAAE,kBAA8B;IAChD,YAAY,EAAE,kBAA8B;EAEhD,qBAAY;IACR,gBAAgB,EAAE,kBAA+B;IACjD,YAAY,EAAE,kBAA+B;;AAsBrD,WAAY;EACR,gBAAgB,EAAE,kBAAyB;;AAG/C,UAAW;EACP,gBAAgB,EAAE,kBAAwB;;AAG9C,qBAAsB;EAClB,gBAAgB,EAAE,kBAAsC;;AAG5D,oBAAqB;EACjB,gBAAgB,EAAE,kBAAqC;;AAG3D,yDAAwD;EACpD,gBAAgB,EC5LJ,OAAO;;AD+LvB,YAAa;EACT,KAAK,EAAE,OAAO;;AAIlB,WAAY;EACV,wBAAwB;EACxB,UAAU,EAAE,UAAU;EACtB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,OAAO;EACb,QAAQ,EAAE,IAAI;EACd,WAAW,EAAE,OAAO;EACpB,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,IAAI;EACtB,gBAAgB,EAAE,IAAI;EACtB,MAAM,EAAE,cAAc;EACtB,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,oCAAmC;EAC/C,UAAU,EAAE,0DAA0D;EACtE,0BAA0B;EAC1B,WAAW,EAAE,SAAS;EACtB,QAAQ,EAAE,QAAQ;EAClB,QAAQ,EAAE,MAAM;EAChB,MAAM,EAAC,IAAI;;AAGb,mBAAoB;EAClB,wBAAwB;EACxB,YAAY,EAAE,OAAO;EACrB,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,sEAAiE;EAC7E,UAAU,EAAE,0DAA0D;;AAGxE,OAAQ;EACN,SAAS,EAAE,IAAI;EACf,QAAQ,EAAE,QAAQ;;AAEpB,aAAc;EACZ,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,aAAa;EACnB,SAAS,EAAE,UAAU;EACrB,QAAQ,EAAE,MAAM;EAChB,OAAO,EAAE,CAAC;;AAEZ,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAClB,SAAS,EAAE,6BAA6B;EACxC,aAAa,EAAE,mBAAmB;EAClC,MAAM,EAAE,mBAAmB;EAC3B,WAAW,EAAE,mBAAmB;EAChC,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,MAAM;EACtB,WAAW,EAAE,2CAA2C;;AAE1D;4BAC6B;EAC3B,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,6BAA6B;EACpC,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,KAAK;;AAEhB,6BAA8B;EAC5B,KAAK,EAAE,CAAC;EACR,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,mBAAmB;EAClC,UAAU,EAAE,QAAQ;;AAEtB,4BAA6B;EAC3B,GAAG,EAAE,GAAG;EACR,IAAI,EAAE,GAAG;EACT,KAAK,EAAE,yCAAyC;EAChD,MAAM,EAAE,yCAAyC;EACjD,aAAa,EAAE,GAAG;EAClB,gBAAgB,EAAE,KAAK;EACvB,UAAU,EAAE,QAAQ;;AAEtB,qCAAsC;EACpC,gBAAgB,EAAE,IAAI;;AAExB,oCAAqC;EACnC,WAAW,EAAE,mBAAmB;;AAElC,mCAAoC;EAClC,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,oCAAoC;;AAElD,8BAA+B;EAC7B,KAAK,EAAE,OAAO;EACd,MAAM,EAAE,WAAW;;AAErB,sCAAuC;EACrC,gBAAgB,EAAE,OAAO;;AAE3B,iBAAkB;EAChB,SAAS,EAAE,QAAQ;;AAErB,+BAAgC;EAC9B,SAAS,EAAE,8BAA8B;EACzC,MAAM,EAAE,oBAAoB;EAC5B,WAAW,EAAE,oBAAoB;EACjC,WAAW,EAAE,4CAA4C;;AAE3D,uCAAwC;EACtC,KAAK,EAAE,8BAA8B;;AAEvC,sCAAuC;EACrC,KAAK,EAAE,0CAA0C;EACjD,MAAM,EAAE,0CAA0C;;AAEpD,8CAA+C;EAC7C,WAAW,EAAE,oBAAoB;;AAEnC,iBAAkB;EAChB,SAAS,EAAE,OAAO;;AAEpB,+BAAgC;EAC9B,SAAS,EAAE,yBAAyB;EACpC,MAAM,EAAE,eAAe;EACvB,WAAW,EAAE,eAAe;EAC5B,WAAW,EAAE,uCAAuC;;AAEtD,uCAAwC;EACtC,KAAK,EAAE,yBAAyB;;AAElC,sCAAuC;EACrC,KAAK,EAAE,qCAAqC;EAC5C,MAAM,EAAE,qCAAqC;;AAE/C,8CAA+C;EAC7C,WAAW,EAAE,eAAe;;AAE9B,iBAAkB;EAChB,WAAW,EAAE,IAAI;;AAInB,0BASC;EARG,EAAG;IAAE,SAAS,EAAE,QAAQ;EACxB,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,WAAW;EAC5B,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,GAAI;IAAE,SAAS,EAAE,WAAW;EAC5B,GAAI;IAAE,SAAS,EAAE,QAAQ;EACzB,IAAK;IAAE,SAAS,EAAE,QAAQ;AAG9B,MAAO;EACH,cAAc,EAAE,eAAe;EAC/B,kBAAkB,EAAE,MAAM;EAC1B,gBAAgB,EAAC,OAAO;EACxB,yBAAyB,EAAE,QAAQ;EACnC,yBAAyB,EAAE,MAAM;;AAIrC,oBAYC;EAXC,EAAG;IACD,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,QAAQ;EAErB,GAAI;IACF,OAAO,EAAE,CAAC;EAEZ,IAAK;IACH,SAAS,EAAE,QAAQ;IACnB,OAAO,EAAE,CAAC;AAGd,WAAY;EACR,cAAc,EAAE,UAAU;EAC1B,kBAAkB,EAAE,KAAK;EACzB,gBAAgB,EAAE,OAAO;EACzB,yBAAyB,EAAE,QAAQ;EACnC,yBAAyB,EAAE,MAAM;;AAGrC;iBACkB;EACd,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,EAAE;EACX,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,OAAO;EACd,GAAG,EAAE,MAAM;EACX,KAAK,EAAE,OAAO;EACd,aAAa,EAAE,CAAC;EAChB,UAAU,EAAE,eAAe;EAC3B,SAAS,EAAE,8BAA8B;;AAG7C,cAAe;EACb,gBAAgB,EAAE,SAAS;;AAG7B,UAAW;EACT,MAAM,EAAE,IAAI;EAAE,4CAA4C;EAC1D,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,SAAS;EACjB,MAAM,EAAE,YAAY;EACpB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,GAAG;EACjB,WAAW,EAAE,KAAK;EAClB,UAAU,EAAE,MAAM;EAClB,KAAK,EAAE,OAAO;;AAGhB,oEAAoE;AACpE,iBAAkB;EAChB,MAAM,EAAE,QAAQ;EAChB,MAAM,EAAE,aAAa;EACrB,MAAM,EAAE,gBAAgB;;AAG1B,WAAY;EACV,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,gBAAgB;EACxB,OAAO,EAAE,KAAK;;AAGhB,gBAAiB;EACf,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,KAAK;EACd,UAAU,EAAE,IAAI;;AAGlB,cAAe;EACb,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,KAAK;EACd,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,CAAC;;AAGV,QAAS;EACP,MAAM,EAAE,OAAO;;AEhejB;;;GAGG;AA8BH,YAAa;EACT,OAAO,EAAE,IAAI;EACb,OAAO,EAAE,KAAK;EACd,QAAQ,EAAE,QAAQ;EAClB,KAAK,EA3BO,IAAI;EA4BhB,UAAU,EAzBC,IAAI;EA0Bf,MAAM,EAAE,cAA2B;EACnC,mBAAmB,EAzBG,IAAI;EA0B1B,WAAW,EAXE,8CAA8C;EAa3D,sBAAY;IACR,OAAO,EAAE,IAAI;EAGjB,qBAAW;IACP,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,kCAAiC;;AAMrD,YAAa;EACT,KAAK,EAAE,CAAC;EAER,uCACQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;EAGlB,kBAAQ;IAAE,KAAK,EAAE,IAAI;;AAGzB,YAAa;EACT,KAAK,EAAE,IAAI;EACX,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,GAAG;;AAGf,WAAY;EACR,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,MAAM;EAElB,kBAAO;IACH,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,GAAG;IACR,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,CAAC;;AAIlB,WAAY;EACR,OAAO,EAAE,YAAY;EACrB,QAAQ,EAAE,MAAM;EAChB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,MAAM;EAChB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,OAAO;EAChB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,IAAI;EACjB,KAAK,EAzFQ,IAAI;EA0FjB,gBAAgB,EAzFN,IAAI;;AA4FlB;UACW;EACP,OAAO,EAAE,KAAK;EACd,MAAM,EAAE,OAAO;EACf,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,MAAM;EACnB,QAAQ,EAAE,MAAM;EAChB,gBAAgB,EAAE,WAAW;EAC7B,mBAAmB,EAAE,aAAa;EAClC,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,OAAO,EAAE,EAAE;EACX,SAAS,EAAE,QAAQ;EACnB,IAAI,EAAE,CAAC;EAEP;kBAAQ;IACJ,OAAO,EAAE,CAAC;EAGd;wBAAc;IACV,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,EAAE;;AAInB;kBACmB;EACf,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,yNAAyN;EAC3O,KAAK,EAAE,CAAC;;AAGZ;kBACmB;EACf,KAAK,EAAE,KAAK;EACZ,gBAAgB,EAAE,yNAAyN;EAC3O,MAAM,EAAE,CAAC;;AAGb,YAAa;EACT,OAAO,EAAE,YAAY;EACrB,QAAQ,EAAE,MAAM;;AAGpB,WAAY;EACR,KAAK,EAAE,IAAI;EACX,eAAe,EAAE,QAAQ;EACzB,cAAc,EAAE,CAAC;EACjB,MAAM,EAAE,CAAC;EAET;gBACG;IACC,KAAK,EAAE,mBAAmB;IAC1B,OAAO,EAAE,CAAC;EAGd,cAAG;IACC,KAAK,EAtJC,IAAI;IAuJV,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,MAAM;EAGtB,gBAAK;IACD,aAAa,EAAE,IAAI;IACnB,MAAM,EAAE,IAAI;;AAIpB,YAAa;EACT,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,KAAK;EACd,eAAe,EAAE,UAAU;EAC3B,UAAU,EAAE,UAAU;EACtB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,CAAC;EACT,MAAM,EAAE,CAAC;EACT,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,GAAG;EACZ,KAAK,EA5KM,IAAI;EA6Kf,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,KAAK;EACjB,UAAU,EA/KF,OAAO;EAiLf,sBAAY;IACR,KAAK,EA/KQ,OAAO;IAgLpB,WAAW,EAAE,IAAI;EAGrB,yBAAe;IACX,KAAK,EAnLW,IAAI;IAoLpB,WAAW,EAAE,IAAI;IACjB,UAAU,EApLG,OAAO;IAqLpB,UAAU,EAAE,uBAAuC;IACnD,aAAa,EAAE,GAAG;EAGtB,iEAC4B;IACxB,KAAK,EAzLW,IAAI;IA0LpB,OAAO,EAAE,EAAE;EAGf,yBAAe;IACX,cAAc,EAAE,IAAI;IACpB,MAAM,EAAE,OAAO;EAGnB,kBAAQ;IACJ,KAAK,EAzMQ,IAAI;IA0MjB,UAAU,EAzMA,OAAO;IA0MjB,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,GAAG;EAGtB,mCAAuB;IACnB,cAAc,EAAE,IAAI;IACpB,MAAM,EAAE,OAAO;;AAIvB,UAAW;EACP,SAAS,EAAE,IAAI;EACf,KAAK,EAhNO,IAAI;;AAmNpB,wBAAyB;EACrB,UAAU,EAAE,OAAO;;AAGvB,2BAA4B;EACxB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,GAAG;;AAGtB,yBAA0B;EACtB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,GAAG;;AC7PtB;;;;;;;;;;;;;;;GAeG;AAEH,yBAA0B;EAEtB,UAAU;IACN,gBAAgB,EF0BF,OAAO;;EEvBzB,aAAc;IACV,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,YAAY;;EAGzB,mBAAoB;IAChB,SAAS,EAAE,MAAM;;EAGrB,UAAW;IACP,OAAO,EAAE,YAAY;;EAGzB,OAAQ;IACJ,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,CAAC;;EAGpB,OAAQ;IACJ,WAAW,EAAE,MAAM;IACnB,SAAS,EAAE,OAAO;;EAGtB,YAAa;IACT,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;;EAGtB,KAAM;IACF,MAAM,EAAE,CAAC;IACT,aAAa,EFRF,IAAI;IESf,OAAO,EFLF,CAAC;IEMN,gBAAgB,EFPA,OAAO;;EEU3B,UAAW;IACP,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,OAAO;;EAGpB,UAAW;IACP,SAAS,EAAE,KAAK;;EAGpB,WAAY;IACR,UAAU,EAAE,iBAAiB;IAC7B,aAAa,EAAE,iBAAiB;;EAGpC,kBAAmB;IACf,YAAY,EAAE,CAAC;IACf,aAAa,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM;;EAGrB,gBAAiB;IACb,UAAU,EAAE,iBAAiB;IAC7B,MAAM,EAAE,GAAG;;EAGf,4BAA6B;IACzB,sBAAsB,EAAE,CAAC;IACzB,uBAAuB,EAAE,CAAC;;EAG9B,2BAA4B;IACxB,0BAA0B,EAAE,CAAC;IAC7B,yBAAyB,EAAE,CAAC;;EAGhC,kBAAmB;IACf,SAAS,EAAE,MAAM;;EAGrB,wBAAyB;IACrB,MAAM,EAAE,KAAK\",\n\"sources\": [\"../scss/base.scss\",\"../scss/variables.scss\",\"../scss/pikaday.scss\",\"../scss/mobile.scss\"],\n\"names\": [],\n\"file\": \"base.css\"\n}\n"),
20
        }
21
        file4 := &embedded.EmbeddedFile{
22
                Filename:    "bootstrap.min.css",
23
                FileModTime: time.Unix(1530208361, 0),
24
                Content:     string("/*!\n * Bootstrap v4.1.1 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex=\"-1\"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:\"\\2014 \\00A0\"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:\"\"}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:\"\";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:\"\";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size=\"1\"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:\"Browse\"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:\"Browse\";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:\"\";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:\"/\"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{color:#000;text-decoration:none;opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:\"\";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:\"\";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:\"\";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-item-next,.carousel-item-prev,.carousel-item.active{transition:none}}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\")}.carousel-control-next-icon{background-image:url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:\"\"}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:\"\"}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:\"\"}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:\"\"}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:\" (\" attr(title) \")\"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}\n/*# sourceMappingURL=bootstrap.min.css.map */"),
25
        }
26
27
        // define dirs
28
        dir1 := &embedded.EmbeddedDir{
29
                Filename:   "",
30
                DirModTime: time.Unix(1538106376, 0),
31
                ChildFiles: []*embedded.EmbeddedFile{
32
                        file2, // "base.css"
33
                        file3, // "base.css.map"
34
                        file4, // "bootstrap.min.css"
35
36
                },
37
        }
38
39
        // link ChildDirs
40
        dir1.ChildDirs = []*embedded.EmbeddedDir{}
41
42
        // register embeddedBox
43
        embedded.RegisterEmbeddedBox(`css`, &embedded.EmbeddedBox{
44
                Name: `css`,
45
                Time: time.Unix(1538106376, 0),
46
                Dirs: map[string]*embedded.EmbeddedDir{
47
                        "": dir1,
48
                },
49
                Files: map[string]*embedded.EmbeddedFile{
50
                        "base.css":          file2,
51
                        "base.css.map":      file3,
52
                        "bootstrap.min.css": file4,
53
                },
54
        })
55
}
func Assets
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/source/source.go:

38
func Assets() {
39
        CssBox = rice.MustFindBox("css")
40
        ScssBox = rice.MustFindBox("scss")
41
        JsBox = rice.MustFindBox("js")
42
        TmplBox = rice.MustFindBox("tmpl")
43
}
@@ -1694,15 +1734,15 @@ PACKAGE:github.com/hunterlong/statup/plugin DONE:33.33 PACKAGE:github.com/hunterlong/statup/source DONE:77.71 --> -
Package Overview: github.com/hunterlong/statup/utils 54.76%

This is a coverage report created after analysis of the github.com/hunterlong/statup/utils package. It +

Package Overview: github.com/hunterlong/statup/utils 54.98%

This is a coverage report created after analysis of the github.com/hunterlong/statup/utils package. It has been generated with the following command:

gocov test github.com/hunterlong/statup/utils | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

- + + - @@ -1725,35 +1765,35 @@ PACKAGE:github.com/hunterlong/statup/source DONE:77.71 - - + + - +
Log(...)github.com/hunterlong/statup/utils/log.go100.00%16/16
UnderScoreString(...)github.com/hunterlong/statup/utils/utils.go100.00%10/10
NewSHA1Hash(...)github.com/hunterlong/statup/utils/encryption.go100.00%8/8
Http(...)github.com/hunterlong/statup/utils/log.go100.00%5/5
RandomString(...)github.com/hunterlong/statup/utils/encryption.go100.00%5/5
DeleteFile(...)github.com/hunterlong/statup/utils/utils.go100.00%5/5
Http(...)github.com/hunterlong/statup/utils/log.go100.00%5/5
newLogRow(...)github.com/hunterlong/statup/utils/log.go100.00%4/4
RandomString(...)github.com/hunterlong/statup/utils/encryption.go100.00%4/4
Timezoner(...)github.com/hunterlong/statup/utils/utils.go100.00%4/4
rotate(...)github.com/hunterlong/statup/utils/log.go100.00%3/3
@84:5(...)github.com/hunterlong/statup/utils/log.go100.00%3/3
LogRow.lineAsString(...)github.com/hunterlong/statup/utils/log.go0.00%0/5
dir(...)github.com/hunterlong/statup/utils/utils.go0.00%0/4
SaveFile(...)github.com/hunterlong/statup/utils/utils.go0.00%0/2
@157:5(...)github.com/hunterlong/statup/utils/utils.go0.00%0/1
@161:5(...)github.com/hunterlong/statup/utils/utils.go0.00%0/1
@164:5(...)github.com/hunterlong/statup/utils/utils.go0.00%0/1
@168:5(...)github.com/hunterlong/statup/utils/utils.go0.00%0/1
LogRow.FormatForHtml(...)github.com/hunterlong/statup/utils/log.go0.00%0/1
github.com/hunterlong/statup/utils54.76%115/210
github.com/hunterlong/statup/utils54.98%116/211
func Log
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

93
func Log(level int, err interface{}) error {
94
        pushLastLine(err)
95
        var outErr error
96
        switch level {
97
        case 5:
98
                _, outErr = fmt.Printf("PANIC: %v\n", err)
99
                fmtLogs.Printf("PANIC: %v\n", err)
100
        case 4:
101
                _, outErr = fmt.Printf("FATAL: %v\n", err)
102
                fmtLogs.Printf("FATAL: %v\n", err)
103
                //color.Red("ERROR: %v\n", err)
104
                //os.Exit(2)
105
        case 3:
106
                _, outErr = fmt.Printf("ERROR: %v\n", err)
107
                fmtLogs.Printf("ERROR: %v\n", err)
108
                //color.Red("ERROR: %v\n", err)
109
        case 2:
110
                _, outErr = fmt.Printf("WARNING: %v\n", err)
111
                fmtLogs.Printf("WARNING: %v\n", err)
112
                //color.Yellow("WARNING: %v\n", err)
113
        case 1:
114
                _, outErr = fmt.Printf("INFO: %v\n", err)
115
                fmtLogs.Printf("INFO: %v\n", err)
116
                //color.Blue("INFO: %v\n", err)
117
        case 0:
118
                _, outErr = fmt.Printf("%v\n", err)
119
                fmtLogs.Printf("%v\n", err)
120
                //color.White("%v\n", err)
121
        }
122
        return outErr
123
}
func UnderScoreString
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
99
func UnderScoreString(str string) string {
100
101
        // convert every letter to lower case
102
        newStr := strings.ToLower(str)
103
104
        // convert all spaces/tab to underscore
105
        regExp := regexp.MustCompile("[[:space:][:blank:]]")
106
        newStrByte := regExp.ReplaceAll([]byte(newStr), []byte("_"))
107
108
        regExp = regexp.MustCompile("`[^a-z0-9]`i")
109
        newStrByte = regExp.ReplaceAll(newStrByte, []byte("_"))
110
111
        regExp = regexp.MustCompile("[!/']")
112
        newStrByte = regExp.ReplaceAll(newStrByte, []byte("_"))
113
114
        // and remove underscore from beginning and ending
115
116
        newStr = strings.TrimPrefix(string(newStrByte), "_")
117
        newStr = strings.TrimSuffix(newStr, "_")
118
119
        return newStr
120
}
+102
func UnderScoreString(str string) string {
103
104
        // convert every letter to lower case
105
        newStr := strings.ToLower(str)
106
107
        // convert all spaces/tab to underscore
108
        regExp := regexp.MustCompile("[[:space:][:blank:]]")
109
        newStrByte := regExp.ReplaceAll([]byte(newStr), []byte("_"))
110
111
        regExp = regexp.MustCompile("`[^a-z0-9]`i")
112
        newStrByte = regExp.ReplaceAll(newStrByte, []byte("_"))
113
114
        regExp = regexp.MustCompile("[!/']")
115
        newStrByte = regExp.ReplaceAll(newStrByte, []byte("_"))
116
117
        // and remove underscore from beginning and ending
118
119
        newStr = strings.TrimPrefix(string(newStrByte), "_")
120
        newStr = strings.TrimSuffix(newStr, "_")
121
122
        return newStr
123
}
func NewSHA1Hash
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/encryption.go:

-
32
func NewSHA1Hash(n ...int) string {
33
        noRandomCharacters := 32
34
        if len(n) > 0 {
35
                noRandomCharacters = n[0]
36
        }
37
        randString := RandomString(noRandomCharacters)
38
        hash := sha1.New()
39
        hash.Write([]byte(randString))
40
        bs := hash.Sum(nil)
41
        return fmt.Sprintf("%x", bs)
42
}
+33
func NewSHA1Hash(n ...int) string {
34
        noRandomCharacters := 32
35
        if len(n) > 0 {
36
                noRandomCharacters = n[0]
37
        }
38
        randString := RandomString(noRandomCharacters)
39
        hash := sha1.New()
40
        hash.Write([]byte(randString))
41
        bs := hash.Sum(nil)
42
        return fmt.Sprintf("%x", bs)
43
}
+ +
func RandomString
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/encryption.go:

+
48
func RandomString(n int) string {
49
        b := make([]rune, n)
50
        rand.Seed(time.Now().UnixNano())
51
        for i := range b {
52
                b[i] = characterRunes[rand.Intn(len(characterRunes))]
53
        }
54
        return string(b)
55
}
+ +
func DeleteFile
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

+
138
func DeleteFile(file string) error {
139
        Log(1, "deleting file: "+file)
140
        err := os.Remove(file)
141
        if err != nil {
142
                return err
143
        }
144
        return nil
145
}
func Http
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

126
func Http(r *http.Request) string {
127
        msg := fmt.Sprintf("%v (%v) | IP: %v", r.RequestURI, r.Method, r.Host)
128
        fmtLogs.Printf("WEB: %v\n", msg)
129
        fmt.Printf("WEB: %v\n", msg)
130
        pushLastLine(msg)
131
        return msg
132
}
-
func DeleteFile
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
133
func DeleteFile(file string) error {
134
        Log(1, "deleting file: "+file)
135
        err := os.Remove(file)
136
        if err != nil {
137
                return err
138
        }
139
        return nil
140
}
-
func newLogRow
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

159
func newLogRow(line interface{}) (logRow *LogRow) {
160
        logRow = new(LogRow)
161
        logRow.Date = time.Now()
162
        logRow.Line = line
163
        return
164
}
-
func RandomString
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/encryption.go:

-
47
func RandomString(n int) string {
48
        b := make([]rune, n)
49
        for i := range b {
50
                b[i] = characterRunes[rand.Intn(len(characterRunes))]
51
        }
52
        return string(b)
53
}
-
func Timezoner
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
71
func Timezoner(t time.Time, zone float32) time.Time {
72
        zoneInt := float32(3600) * (zone + 1)
73
        loc := time.FixedZone("", int(zoneInt))
74
        timez := t.In(loc)
75
        return timez
76
}
+72
func Timezoner(t time.Time, zone float32) time.Time {
73
        zoneInt := float32(3600) * (zone + 1)
74
        loc := time.FixedZone("", int(zoneInt))
75
        timez := t.In(loc)
76
        return timez
77
}
func rotate
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

81
func rotate() {
82
        c := make(chan os.Signal, 1)
83
        signal.Notify(c, syscall.SIGHUP)
84
        go func() {
85
                for {
86
                        <-c
87
                        ljLogger.Rotate()
88
                }
89
        }()
90
}
@@ -1762,16 +1802,16 @@ PACKAGE:github.com/hunterlong/statup/source DONE:77.71 84
func() {
85
                for {
86
                        <-c
87
                        ljLogger.Rotate()
88
                }
89
        }
func Timestamp.Ago
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
93
func (t Timestamp) Ago() string {
94
        got, _ := timeago.TimeAgoWithTime(time.Now(), time.Time(t))
95
        return got
96
}
+94
func (t Timestamp) Ago() string {
95
        got, _ := timeago.TimeAgoWithTime(time.Now(), time.Time(t))
96
        return got
97
}
func StringInt
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

47
func StringInt(s string) int64 {
48
        num, _ := strconv.Atoi(s)
49
        return int64(num)
50
}
func HashPassword
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/encryption.go:

-
26
func HashPassword(password string) string {
27
        bytes, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
28
        return string(bytes)
29
}
+27
func HashPassword(password string) string {
28
        bytes, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
29
        return string(bytes)
30
}
func DeleteDirectory
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
143
func DeleteDirectory(directory string) error {
144
        return os.RemoveAll(directory)
145
}
+149
func DeleteDirectory(directory string) error {
150
        return os.RemoveAll(directory)
151
}
func rev
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/time.go:

77
func rev(f float64) float64 {
78
        return f * -1
79
}
@@ -1789,10 +1829,10 @@ PACKAGE:github.com/hunterlong/statup/source DONE:77.71 39
func createLog(dir string) error {
40
        var err error
41
        _, err = os.Stat(dir + "/logs")
42
        if err != nil {
43
                if os.IsNotExist(err) {
44
                        os.Mkdir(dir+"/logs", 0777)
45
                } else {
46
                        return err
47
                }
48
        }
49
        file, err := os.Create(dir + "/logs/statup.log")
50
        if err != nil {
51
                return err
52
        }
53
        defer file.Close()
54
        return err
55
}
func FileExists
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
123
func FileExists(name string) bool {
124
        if _, err := os.Stat(name); err != nil {
125
                if os.IsNotExist(err) {
126
                        return false
127
                }
128
        }
129
        return true
130
}
+127
func FileExists(name string) bool {
128
        if _, err := os.Stat(name); err != nil {
129
                if os.IsNotExist(err) {
130
                        return false
131
                }
132
        }
133
        return true
134
}
func DurationReadable
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
202
func DurationReadable(d time.Duration) string {
203
        if d.Hours() >= 1 {
204
                return fmt.Sprintf("%0.0f hours", d.Hours())
205
        } else if d.Minutes() >= 1 {
206
                return fmt.Sprintf("%0.0f minutes", d.Minutes())
207
        } else if d.Seconds() >= 1 {
208
                return fmt.Sprintf("%0.0f seconds", d.Seconds())
209
        }
210
        return d.String()
211
}
+213
func DurationReadable(d time.Duration) string {
214
        if d.Hours() >= 1 {
215
                return fmt.Sprintf("%0.0f hours", d.Hours())
216
        } else if d.Minutes() >= 1 {
217
                return fmt.Sprintf("%0.0f minutes", d.Minutes())
218
        } else if d.Seconds() >= 1 {
219
                return fmt.Sprintf("%0.0f seconds", d.Seconds())
220
        }
221
        return d.String()
222
}
func FormatDuration
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/time.go:

24
func FormatDuration(d time.Duration) string {
25
        var out string
26
        if d.Hours() >= 24 {
27
                out = fmt.Sprintf("%0.0f day", d.Hours()/24)
28
                if (d.Hours() / 24) >= 2 {
29
                        out += "s"
30
                }
31
                return out
32
        } else if d.Hours() >= 1 {
33
                out = fmt.Sprintf("%0.0f hour", d.Hours())
34
                if d.Hours() >= 2 {
35
                        out += "s"
36
                }
37
                return out
38
        } else if d.Minutes() >= 1 {
39
                out = fmt.Sprintf("%0.0f minute", d.Minutes())
40
                if d.Minutes() >= 2 {
41
                        out += "s"
42
                }
43
                return out
44
        } else if d.Seconds() >= 1 {
45
                out = fmt.Sprintf("%0.0f second", d.Seconds())
46
                if d.Seconds() >= 2 {
47
                        out += "s"
48
                }
49
                return out
50
        } else if rev(d.Hours()) >= 24 {
51
                out = fmt.Sprintf("%0.0f day", rev(d.Hours()/24))
52
                if rev(d.Hours()/24) >= 2 {
53
                        out += "s"
54
                }
55
                return out
56
        } else if rev(d.Hours()) >= 1 {
57
                out = fmt.Sprintf("%0.0f hour", rev(d.Hours()))
58
                if rev(d.Hours()) >= 2 {
59
                        out += "s"
60
                }
61
                return out
62
        } else if rev(d.Minutes()) >= 1 {
63
                out = fmt.Sprintf("%0.0f minute", rev(d.Minutes()))
64
                if rev(d.Minutes()) >= 2 {
65
                        out += "s"
66
                }
67
                return out
68
        } else {
69
                out = fmt.Sprintf("%0.0f second", rev(d.Seconds()))
70
                if rev(d.Seconds()) >= 2 {
71
                        out += "s"
72
                }
73
        }
74
        return out
75
}
@@ -1801,10 +1841,10 @@ PACKAGE:github.com/hunterlong/statup/source DONE:77.71 53
func ToString(s interface{}) string {
54
        switch v := s.(type) {
55
        case int, int32, int64:
56
                return fmt.Sprintf("%v", v)
57
        case float32, float64:
58
                return fmt.Sprintf("%v", v)
59
        case []byte:
60
                return string(v)
61
        case bool:
62
                if v {
63
                        return "true"
64
                }
65
                return "false"
66
        default:
67
                return fmt.Sprintf("%v", v)
68
        }
69
}
func Command
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
148
func Command(cmd string) (string, string, error) {
149
        Log(1, "running command: "+cmd)
150
        testCmd := exec.Command("sh", "-c", cmd)
151
        var stdout, stderr []byte
152
        var errStdout, errStderr error
153
        stdoutIn, _ := testCmd.StdoutPipe()
154
        stderrIn, _ := testCmd.StderrPipe()
155
        testCmd.Start()
156
157
        go func() {
158
                stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn)
159
        }()
160
161
        go func() {
162
                stderr, errStderr = copyAndCapture(os.Stderr, stderrIn)
163
        }()
164
165
        err := testCmd.Wait()
166
        if err != nil {
167
                return "", "", err
168
        }
169
170
        if errStdout != nil || errStderr != nil {
171
                return "", "", errors.New("failed to capture stdout or stderr")
172
        }
173
174
        outStr, errStr := string(stdout), string(stderr)
175
        return outStr, errStr, err
176
}
+155
func Command(cmd string) (string, string, error) {
156
        Log(1, "running command: "+cmd)
157
        testCmd := exec.Command("sh", "-c", cmd)
158
        var stdout, stderr []byte
159
        var errStdout, errStderr error
160
        stdoutIn, _ := testCmd.StdoutPipe()
161
        stderrIn, _ := testCmd.StderrPipe()
162
        testCmd.Start()
163
164
        go func() {
165
                stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn)
166
        }()
167
168
        go func() {
169
                stderr, errStderr = copyAndCapture(os.Stderr, stderrIn)
170
        }()
171
172
        err := testCmd.Wait()
173
        if err != nil {
174
                return "", "", err
175
        }
176
177
        if errStdout != nil || errStderr != nil {
178
                return "", "", errors.New("failed to capture stdout or stderr")
179
        }
180
181
        outStr, errStr := string(stdout), string(stderr)
182
        return outStr, errStr, err
183
}
func copyAndCapture
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
179
func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) {
180
        var out []byte
181
        buf := make([]byte, 1024, 1024)
182
        for {
183
                n, err := r.Read(buf[:])
184
                if n > 0 {
185
                        d := buf[:n]
186
                        out = append(out, d...)
187
                        _, err := w.Write(d)
188
                        if err != nil {
189
                                return out, err
190
                        }
191
                }
192
                if err != nil {
193
                        // Read returns io.EOF at the end of file, which is not an error for us
194
                        if err == io.EOF {
195
                                err = nil
196
                        }
197
                        return out, err
198
                }
199
        }
200
}
+186
func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) {
187
        var out []byte
188
        buf := make([]byte, 1024, 1024)
189
        for {
190
                n, err := r.Read(buf[:])
191
                if n > 0 {
192
                        d := buf[:n]
193
                        out = append(out, d...)
194
                        _, err := w.Write(d)
195
                        if err != nil {
196
                                return out, err
197
                        }
198
                }
199
                if err != nil {
200
                        // Read returns io.EOF at the end of file, which is not an error for us
201
                        if err == io.EOF {
202
                                err = nil
203
                        }
204
                        return out, err
205
                }
206
        }
207
}
func GetLastLine
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

145
func GetLastLine() *LogRow {
146
        LockLines.Lock()
147
        defer LockLines.Unlock()
148
        if len(LastLines) > 0 {
149
                return LastLines[len(LastLines)-1]
150
        }
151
        return nil
152
}
@@ -1813,25 +1853,25 @@ PACKAGE:github.com/hunterlong/statup/source DONE:77.71 166
func (o *LogRow) lineAsString() string {
167
        switch v := o.Line.(type) {
168
        case string:
169
                return v
170
        case error:
171
                return v.Error()
172
        case []byte:
173
                return string(v)
174
        }
175
        return ""
176
}
func dir
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
79
func dir() string {
80
        dir, err := os.Getwd()
81
        if err != nil {
82
                return "."
83
        }
84
        return dir
85
}
+80
func dir() string {
81
        dir, err := os.Getwd()
82
        if err != nil {
83
                return "."
84
        }
85
        return dir
86
}
func SaveFile
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
214
func SaveFile(filename string, data []byte) error {
215
        err := ioutil.WriteFile(filename, data, 0644)
216
        return err
217
}
+226
func SaveFile(filename string, data []byte) error {
227
        err := ioutil.WriteFile(filename, data, 0644)
228
        return err
229
}
-
func @157:5
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
157
func() {
158
                stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn)
159
        }
+
func @164:5
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

+
164
func() {
165
                stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn)
166
        }
-
func @161:5
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

-
161
func() {
162
                stderr, errStderr = copyAndCapture(os.Stderr, stderrIn)
163
        }
+
func @168:5
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/utils.go:

+
168
func() {
169
                stderr, errStderr = copyAndCapture(os.Stderr, stderrIn)
170
        }
func LogRow.FormatForHtml
Back

In /Users/hunterlong/go/src/github.com/hunterlong/statup/utils/log.go:

178
func (o *LogRow) FormatForHtml() string {
179
        return fmt.Sprintf("%s: %s", o.Date.Format("2006-01-02 15:04:05"), o.lineAsString())
180
}
Report Total
-
56.22%
+
55.30%
diff --git a/dev/README.md b/dev/README.md index 6f7d1448..3d434e98 100644 --- a/dev/README.md +++ b/dev/README.md @@ -33,13 +33,31 @@ More info on: https://github.com/ * [func InsertLargeSampleData() error](#InsertLargeSampleData) * [func InsertSampleData() error](#InsertSampleData) * [func InsertSampleHits() error](#InsertSampleHits) -* [func ReturnCheckin(c *types.Checkin) *checkin](#ReturnCheckin) * [func ReturnCheckinHit(c *types.CheckinHit) *checkinHit](#ReturnCheckinHit) * [func ReturnUser(u *types.User) *user](#ReturnUser) * [func SelectAllUsers() ([]*user, error)](#SelectAllUsers) -* [func SelectCheckin(api string) *checkin](#SelectCheckin) * [func SelectUser(id int64) (*user, error)](#SelectUser) * [func SelectUsername(username string) (*user, error)](#SelectUsername) +* [type Checkin](#Checkin) + * [func ReturnCheckin(c *types.Checkin) *Checkin](#ReturnCheckin) + * [func SelectCheckin(api string) *Checkin](#SelectCheckin) + * [func SelectCheckinId(id int64) *Checkin](#SelectCheckinId) + * [func (c *Checkin) AfterFind() (err error)](#Checkin.AfterFind) + * [func (c *Checkin) BeforeCreate() (err error)](#Checkin.BeforeCreate) + * [func (c *Checkin) Create() (int64, error)](#Checkin.Create) + * [func (c *Checkin) CreateFailure() (int64, error)](#Checkin.CreateFailure) + * [func (c *Checkin) Delete() error](#Checkin.Delete) + * [func (c *Checkin) Expected() time.Duration](#Checkin.Expected) + * [func (c *Checkin) Grace() time.Duration](#Checkin.Grace) + * [func (c *Checkin) Hits() []*checkinHit](#Checkin.Hits) + * [func (c *Checkin) Last() *checkinHit](#Checkin.Last) + * [func (c *Checkin) Link() string](#Checkin.Link) + * [func (c *Checkin) Period() time.Duration](#Checkin.Period) + * [func (c *Checkin) RecheckCheckinFailure(guard chan struct{})](#Checkin.RecheckCheckinFailure) + * [func (c *Checkin) Routine()](#Checkin.Routine) + * [func (c *Checkin) Service() *Service](#Checkin.Service) + * [func (c *Checkin) String() string](#Checkin.String) + * [func (c *Checkin) Update() (int64, error)](#Checkin.Update) * [type Core](#Core) * [func NewCore() *Core](#NewCore) * [func SelectCore() (*Core, error)](#SelectCore) @@ -88,7 +106,8 @@ More info on: https://github.com/ * [func (s *Service) BeforeCreate() (err error)](#Service.BeforeCreate) * [func (s *Service) Check(record bool)](#Service.Check) * [func (s *Service) CheckQueue(record bool)](#Service.CheckQueue) - * [func (s *Service) Checkins() []*checkin](#Service.Checkins) + * [func (s *Service) CheckinProcess()](#Service.CheckinProcess) + * [func (s *Service) Checkins() []*Checkin](#Service.Checkins) * [func (s *Service) Create(check bool) (int64, error)](#Service.Create) * [func (s *Service) CreateFailure(f *types.Failure) (int64, error)](#Service.CreateFailure) * [func (s *Service) CreateHit(h *types.Hit) (int64, error)](#Service.CreateHit) @@ -99,6 +118,7 @@ More info on: https://github.com/ * [func (s *Service) GraphData() string](#Service.GraphData) * [func (s *Service) Hits() ([]*types.Hit, error)](#Service.Hits) * [func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) *gorm.DB](#Service.HitsBetween) + * [func (s *Service) LimitedCheckins() []*Checkin](#Service.LimitedCheckins) * [func (s *Service) LimitedFailures() []*failure](#Service.LimitedFailures) * [func (s *Service) LimitedHits() ([]*types.Hit, error)](#Service.LimitedHits) * [func (s *Service) Online24() float32](#Service.Online24) @@ -168,7 +188,7 @@ CloseDB will close the database connection if available -## func [CountFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=2819:2846#L99) +## func [CountFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=2845:2872#L99) ``` go func CountFailures() uint64 ``` @@ -185,7 +205,7 @@ this function is currently set to delete records 7+ days old every 60 minutes -## func [Dbtimestamp](https://github.com/hunterlong/statup/tree/master/core/services.go?s=5171:5223#L180) +## func [Dbtimestamp](https://github.com/hunterlong/statup/tree/master/core/services.go?s=5755:5807#L200) ``` go func Dbtimestamp(group string, column string) string ``` @@ -257,15 +277,7 @@ InsertSampleHits will create a couple new hits for the sample services -## func [ReturnCheckin](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1064:1109#L40) -``` go -func ReturnCheckin(c *types.Checkin) *checkin -``` -ReturnCheckin converts *types.Checking to *core.checkin - - - -## func [ReturnCheckinHit](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1211:1265#L45) +## func [ReturnCheckinHit](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1942:1996#L71) ``` go func ReturnCheckinHit(c *types.CheckinHit) *checkinHit ``` @@ -289,14 +301,6 @@ SelectAllUsers returns all users -## func [SelectCheckin](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1369:1408#L50) -``` go -func SelectCheckin(api string) *checkin -``` -SelectCheckin will find a checkin based on the API supplied - - - ## func [SelectUser](https://github.com/hunterlong/statup/tree/master/core/users.go?s=1025:1065#L36) ``` go func SelectUser(id int64) (*user, error) @@ -314,6 +318,181 @@ SelectUsername returns the user based on the user's username +## type [Checkin](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=818:857#L26) +``` go +type Checkin struct { + *types.Checkin +} + +``` + + + + + + +### func [ReturnCheckin](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1795:1840#L66) +``` go +func ReturnCheckin(c *types.Checkin) *Checkin +``` +ReturnCheckin converts *types.Checking to *core.Checkin + + +### func [SelectCheckin](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=2646:2685#L94) +``` go +func SelectCheckin(api string) *Checkin +``` +SelectCheckin will find a Checkin based on the API supplied + + +### func [SelectCheckinId](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=2847:2886#L101) +``` go +func SelectCheckinId(id int64) *Checkin +``` +SelectCheckin will find a Checkin based on the API supplied + + + + + +### func (\*Checkin) [AfterFind](https://github.com/hunterlong/statup/tree/master/core/database.go?s=3493:3534#L119) +``` go +func (c *Checkin) AfterFind() (err error) +``` +AfterFind for Checkin will set the timezone + + + + +### func (\*Checkin) [BeforeCreate](https://github.com/hunterlong/statup/tree/master/core/database.go?s=4520:4564#L163) +``` go +func (c *Checkin) BeforeCreate() (err error) +``` +BeforeCreate for Checkin will set CreatedAt to UTC + + + + +### func (\*Checkin) [Create](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=4352:4393#L154) +``` go +func (c *Checkin) Create() (int64, error) +``` +Create will create a new Checkin + + + + +### func (\*Checkin) [CreateFailure](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=2134:2182#L80) +``` go +func (c *Checkin) CreateFailure() (int64, error) +``` + + + +### func (\*Checkin) [Delete](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=4218:4250#L147) +``` go +func (c *Checkin) Delete() error +``` +Create will create a new Checkin + + + + +### func (\*Checkin) [Expected](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=3500:3542#L120) +``` go +func (c *Checkin) Expected() time.Duration +``` +Expected returns the duration of when the serviec should receive a Checkin + + + + +### func (\*Checkin) [Grace](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=3290:3329#L114) +``` go +func (c *Checkin) Grace() time.Duration +``` +Grace will return the duration of the Checkin Grace Period (after service hasn't responded, wait a bit for a response) + + + + +### func (\*Checkin) [Hits](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=4016:4054#L140) +``` go +func (c *Checkin) Hits() []*checkinHit +``` +Hits returns all of the CheckinHits for a given Checkin + + + + +### func (\*Checkin) [Last](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=3727:3763#L129) +``` go +func (c *Checkin) Last() *checkinHit +``` +Last returns the last checkinHit for a Checkin + + + + +### func (\*Checkin) [Link](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=3857:3888#L135) +``` go +func (c *Checkin) Link() string +``` + + + +### func (\*Checkin) [Period](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=3038:3078#L108) +``` go +func (c *Checkin) Period() time.Duration +``` +Period will return the duration of the Checkin interval + + + + +### func (\*Checkin) [RecheckCheckinFailure](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=5358:5418#L196) +``` go +func (c *Checkin) RecheckCheckinFailure(guard chan struct{}) +``` +RecheckCheckinFailure will check if a Service Checkin has been reported yet + + + + +### func (\*Checkin) [Routine](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=974:1001#L35) +``` go +func (c *Checkin) Routine() +``` +Routine for checking if the last Checkin was within its interval + + + + +### func (\*Checkin) [Service](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=2037:2073#L75) +``` go +func (c *Checkin) Service() *Service +``` + + + +### func (\*Checkin) [String](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=1680:1713#L61) +``` go +func (c *Checkin) String() string +``` +String will return a Checkin API string + + + + +### func (\*Checkin) [Update](https://github.com/hunterlong/statup/tree/master/core/checkin.go?s=4621:4662#L167) +``` go +func (c *Checkin) Update() (int64, error) +``` +Update will update a Checkin + + + + ## type [Core](https://github.com/hunterlong/statup/tree/master/core/core.go?s=952:985#L31) ``` go type Core struct { @@ -334,7 +513,7 @@ func NewCore() *Core NewCore return a new *core.Core struct -### func [SelectCore](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3763:3795#L136) +### func [SelectCore](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3752:3784#L136) ``` go func SelectCore() (*Core, error) ``` @@ -351,7 +530,7 @@ UpdateCore will update the CoreApp variable inside of the 'core' table in databa -### func (Core) [AllOnline](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3537:3567#L126) +### func (Core) [AllOnline](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3526:3556#L126) ``` go func (c Core) AllOnline() bool ``` @@ -360,7 +539,7 @@ AllOnline will be true if all services are online -### func (Core) [BaseSASS](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3040:3071#L109) +### func (Core) [BaseSASS](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3029:3060#L109) ``` go func (c Core) BaseSASS() string ``` @@ -369,7 +548,7 @@ BaseSASS is the base design , this opens the file /assets/scss/base.scss to be e -### func (\*Core) [Count24HFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=2547:2587#L88) +### func (\*Core) [Count24HFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=2573:2613#L88) ``` go func (c *Core) Count24HFailures() uint64 ``` @@ -378,7 +557,7 @@ Count24HFailures returns the amount of failures for a service within the last 24 -### func (\*Core) [CountOnline](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10815:10847#L382) +### func (\*Core) [CountOnline](https://github.com/hunterlong/statup/tree/master/core/services.go?s=11399:11431#L402) ``` go func (c *Core) CountOnline() int ``` @@ -387,16 +566,16 @@ CountOnline -### func (Core) [CurrentTime](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2395:2429#L88) +### func (Core) [CurrentTime](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2384:2418#L88) ``` go func (c Core) CurrentTime() string ``` -UsingAssets will return true if /assets folder is present +CurrentTime will return the current local time -### func (Core) [MobileSASS](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3325:3358#L118) +### func (Core) [MobileSASS](https://github.com/hunterlong/statup/tree/master/core/core.go?s=3314:3347#L118) ``` go func (c Core) MobileSASS() string ``` @@ -406,7 +585,7 @@ file /assets/scss/mobile.scss to be edited in Theme -### func (Core) [SassVars](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2782:2813#L101) +### func (Core) [SassVars](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2771:2802#L101) ``` go func (c Core) SassVars() string ``` @@ -415,7 +594,7 @@ SassVars opens the file /assets/scss/variables.scss to be edited in Theme -### func (\*Core) [SelectAllServices](https://github.com/hunterlong/statup/tree/master/core/services.go?s=1729:1783#L62) +### func (\*Core) [SelectAllServices](https://github.com/hunterlong/statup/tree/master/core/services.go?s=2159:2213#L78) ``` go func (c *Core) SelectAllServices() ([]*Service, error) ``` @@ -424,7 +603,7 @@ SelectAllServices returns a slice of *core.Service to be store on []*core.Servic -### func (\*Core) [ServicesCount](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10736:10770#L377) +### func (\*Core) [ServicesCount](https://github.com/hunterlong/statup/tree/master/core/services.go?s=11320:11354#L397) ``` go func (c *Core) ServicesCount() int ``` @@ -442,7 +621,7 @@ ToCore will convert *core.Core to *types.Core -### func (Core) [UsingAssets](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2623:2655#L96) +### func (Core) [UsingAssets](https://github.com/hunterlong/statup/tree/master/core/core.go?s=2612:2644#L96) ``` go func (c Core) UsingAssets() bool ``` @@ -451,7 +630,7 @@ UsingAssets will return true if /assets folder is present -## type [DateScan](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3675:3757#L133) +## type [DateScan](https://github.com/hunterlong/statup/tree/master/core/services.go?s=4111:4193#L149) ``` go type DateScan struct { CreatedAt string `json:"x"` @@ -470,7 +649,7 @@ DateScan struct is for creating the charts.js graph JSON array -## type [DateScanObj](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3828:3887#L139) +## type [DateScanObj](https://github.com/hunterlong/statup/tree/master/core/services.go?s=4264:4323#L155) ``` go type DateScanObj struct { Array []DateScan `json:"data"` @@ -485,7 +664,7 @@ DateScanObj struct is for creating the charts.js graph JSON array -### func [GraphDataRaw](https://github.com/hunterlong/statup/tree/master/core/services.go?s=6296:6409#L216) +### func [GraphDataRaw](https://github.com/hunterlong/statup/tree/master/core/services.go?s=6880:6993#L236) ``` go func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group string, column string) *DateScanObj ``` @@ -495,7 +674,7 @@ GraphDataRaw will return all the hits between 2 times for a Service -### func (\*DateScanObj) [ToString](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7072:7111#L238) +### func (\*DateScanObj) [ToString](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7656:7695#L258) ``` go func (d *DateScanObj) ToString() string ``` @@ -742,7 +921,7 @@ AllFailures will return all failures attached to a service -### func (\*Service) [AvgTime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=2596:2631#L92) +### func (\*Service) [AvgTime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3032:3067#L108) ``` go func (s *Service) AvgTime() float64 ``` @@ -751,7 +930,7 @@ AvgTime will return the average amount of time for a service to response back su -### func (\*Service) [AvgUptime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7817:7866#L267) +### func (\*Service) [AvgUptime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=8401:8450#L287) ``` go func (s *Service) AvgUptime(ago time.Time) string ``` @@ -760,7 +939,7 @@ AvgUptime returns average online status for last 24 hours -### func (\*Service) [AvgUptime24](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7647:7685#L261) +### func (\*Service) [AvgUptime24](https://github.com/hunterlong/statup/tree/master/core/services.go?s=8231:8269#L281) ``` go func (s *Service) AvgUptime24() string ``` @@ -796,16 +975,25 @@ CheckQueue is the main go routine for checking a service -### func (\*Service) [Checkins](https://github.com/hunterlong/statup/tree/master/core/services.go?s=1463:1502#L55) +### func (\*Service) [CheckinProcess](https://github.com/hunterlong/statup/tree/master/core/services.go?s=1485:1519#L55) ``` go -func (s *Service) Checkins() []*checkin +func (s *Service) CheckinProcess() +``` +CheckinProcess runs the checkin routine for each checkin attached to service + + + + +### func (\*Service) [Checkins](https://github.com/hunterlong/statup/tree/master/core/services.go?s=1671:1710#L64) +``` go +func (s *Service) Checkins() []*Checkin ``` Checkins will return a slice of Checkins for a Service -### func (\*Service) [Create](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10250:10301#L361) +### func (\*Service) [Create](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10834:10885#L381) ``` go func (s *Service) Create(check bool) (int64, error) ``` @@ -832,7 +1020,7 @@ CreateHit will create a new 'hit' record in the database for a successful/online -### func (\*Service) [Delete](https://github.com/hunterlong/statup/tree/master/core/services.go?s=9104:9136#L321) +### func (\*Service) [Delete](https://github.com/hunterlong/statup/tree/master/core/services.go?s=9688:9720#L341) ``` go func (s *Service) Delete() error ``` @@ -841,7 +1029,7 @@ Delete will remove a service from the database, it will also end the service che -### func (\*Service) [DeleteFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=1672:1706#L59) +### func (\*Service) [DeleteFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=1698:1732#L59) ``` go func (s *Service) DeleteFailures() ``` @@ -850,7 +1038,7 @@ DeleteFailures will delete all failures for a service -### func (\*Service) [Downtime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=5906:5948#L202) +### func (\*Service) [Downtime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=6490:6532#L222) ``` go func (s *Service) Downtime() time.Duration ``` @@ -859,16 +1047,20 @@ Downtime returns the amount of time of a offline service -### func (\*Service) [DowntimeText](https://github.com/hunterlong/statup/tree/master/core/services.go?s=4970:5009#L175) +### func (\*Service) [DowntimeText](https://github.com/hunterlong/statup/tree/master/core/services.go?s=5554:5593#L195) ``` go func (s *Service) DowntimeText() string ``` DowntimeText will return the amount of downtime for a service based on the duration + service.DowntimeText() + // Service has been offline for 15 minutes -### func (\*Service) [GraphData](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7303:7339#L248) + + +### func (\*Service) [GraphData](https://github.com/hunterlong/statup/tree/master/core/services.go?s=7887:7923#L268) ``` go func (s *Service) GraphData() string ``` @@ -877,7 +1069,7 @@ GraphData returns the JSON object used by Charts.js to render the chart -### func (\*Service) [Hits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1139:1185#L39) +### func (\*Service) [Hits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1140:1186#L39) ``` go func (s *Service) Hits() ([]*types.Hit, error) ``` @@ -895,7 +1087,16 @@ HitsBetween returns the gorm database query for a collection of service hits bet -### func (\*Service) [LimitedFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=1964:2010#L68) +### func (\*Service) [LimitedCheckins](https://github.com/hunterlong/statup/tree/master/core/services.go?s=1876:1922#L71) +``` go +func (s *Service) LimitedCheckins() []*Checkin +``` +LimitedCheckins will return a slice of Checkins for a Service + + + + +### func (\*Service) [LimitedFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=1990:2036#L68) ``` go func (s *Service) LimitedFailures() []*failure ``` @@ -904,7 +1105,7 @@ LimitedFailures will return the last 10 failures from a service -### func (\*Service) [LimitedHits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1406:1459#L47) +### func (\*Service) [LimitedHits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1407:1460#L47) ``` go func (s *Service) LimitedHits() ([]*types.Hit, error) ``` @@ -913,7 +1114,7 @@ LimitedHits returns the last 1024 successful/online 'hit' records for a service -### func (\*Service) [Online24](https://github.com/hunterlong/statup/tree/master/core/services.go?s=2922:2958#L105) +### func (\*Service) [Online24](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3358:3394#L121) ``` go func (s *Service) Online24() float32 ``` @@ -922,7 +1123,7 @@ Online24 returns the service's uptime percent within last 24 hours -### func (\*Service) [OnlineSince](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3122:3174#L111) +### func (\*Service) [OnlineSince](https://github.com/hunterlong/statup/tree/master/core/services.go?s=3558:3610#L127) ``` go func (s *Service) OnlineSince(ago time.Time) float32 ``` @@ -940,16 +1141,20 @@ Select will return the *types.Service struct for Service -### func (\*Service) [SmallText](https://github.com/hunterlong/statup/tree/master/core/services.go?s=4172:4208#L154) +### func (\*Service) [SmallText](https://github.com/hunterlong/statup/tree/master/core/services.go?s=4682:4718#L172) ``` go func (s *Service) SmallText() string ``` SmallText returns a short description about a services status + service.SmallText() + // Online since Monday 3:04:05PM, Jan _2 2006 -### func (\*Service) [Sum](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=2458:2498#L79) + + +### func (\*Service) [Sum](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=2459:2499#L79) ``` go func (s *Service) Sum() (float64, error) ``` @@ -958,7 +1163,7 @@ Sum returns the added value Latency for all of the services successful hits. -### func (\*Service) [ToJSON](https://github.com/hunterlong/statup/tree/master/core/services.go?s=2414:2447#L86) +### func (\*Service) [ToJSON](https://github.com/hunterlong/statup/tree/master/core/services.go?s=2850:2883#L102) ``` go func (s *Service) ToJSON() string ``` @@ -967,7 +1172,7 @@ ToJSON will convert a service to a JSON string -### func (\*Service) [TotalFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3270:3319#L116) +### func (\*Service) [TotalFailures](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3296:3345#L116) ``` go func (s *Service) TotalFailures() (uint64, error) ``` @@ -976,7 +1181,7 @@ TotalFailures returns the total amount of failures for a service -### func (\*Service) [TotalFailures24](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3071:3122#L110) +### func (\*Service) [TotalFailures24](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3097:3148#L110) ``` go func (s *Service) TotalFailures24() (uint64, error) ``` @@ -985,7 +1190,7 @@ TotalFailures24 returns the amount of failures for a service within the last 24 -### func (\*Service) [TotalFailuresSince](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3544:3611#L124) +### func (\*Service) [TotalFailuresSince](https://github.com/hunterlong/statup/tree/master/core/failures.go?s=3570:3637#L124) ``` go func (s *Service) TotalFailuresSince(ago time.Time) (uint64, error) ``` @@ -994,7 +1199,7 @@ TotalFailuresSince returns the total amount of failures for a service since a sp -### func (\*Service) [TotalHits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1889:1934#L63) +### func (\*Service) [TotalHits](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=1890:1935#L63) ``` go func (s *Service) TotalHits() (uint64, error) ``` @@ -1003,7 +1208,7 @@ TotalHits returns the total amount of successful hits a service has -### func (\*Service) [TotalHitsSince](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=2134:2197#L71) +### func (\*Service) [TotalHitsSince](https://github.com/hunterlong/statup/tree/master/core/hits.go?s=2135:2198#L71) ``` go func (s *Service) TotalHitsSince(ago time.Time) (uint64, error) ``` @@ -1012,7 +1217,7 @@ TotalHitsSince returns the total amount of hits based on a specific time/date -### func (\*Service) [TotalUptime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=8292:8330#L289) +### func (\*Service) [TotalUptime](https://github.com/hunterlong/statup/tree/master/core/services.go?s=8876:8914#L309) ``` go func (s *Service) TotalUptime() string ``` @@ -1021,7 +1226,7 @@ TotalUptime returns the total uptime percent of a service -### func (\*Service) [Update](https://github.com/hunterlong/statup/tree/master/core/services.go?s=9766:9810#L342) +### func (\*Service) [Update](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10350:10394#L362) ``` go func (s *Service) Update(restart bool) error ``` @@ -1030,7 +1235,7 @@ Update will update a service in the database, the service's checking routine can -### func (\*Service) [UpdateSingle](https://github.com/hunterlong/statup/tree/master/core/services.go?s=9541:9598#L337) +### func (\*Service) [UpdateSingle](https://github.com/hunterlong/statup/tree/master/core/services.go?s=10125:10182#L357) ``` go func (s *Service) UpdateSingle(attr ...interface{}) error ``` @@ -1039,7 +1244,7 @@ UpdateSingle will update a single column for a service -## type [ServiceOrder](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4378:4420#L158) +## type [ServiceOrder](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4308:4350#L157) ``` go type ServiceOrder []types.ServiceInterface ``` @@ -1054,21 +1259,23 @@ ServiceOrder will reorder the services based on 'order_id' (Order) -### func (ServiceOrder) [Len](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4422:4453#L160) +### func (ServiceOrder) [Len](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4406:4437#L160) ``` go func (c ServiceOrder) Len() int ``` +Sort interface for resroting the Services in order -### func (ServiceOrder) [Less](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4552:4593#L162) + +### func (ServiceOrder) [Less](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4536:4577#L162) ``` go func (c ServiceOrder) Less(i, j int) bool ``` -### func (ServiceOrder) [Swap](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4482:4518#L161) +### func (ServiceOrder) [Swap](https://github.com/hunterlong/statup/tree/master/core/core.go?s=4466:4502#L161) ``` go func (c ServiceOrder) Swap(i, j int) ``` @@ -1219,8 +1426,9 @@ Package plugin contains the interfaces to build your own Golang Plugin that will ## Index * [Variables](#pkg-variables) -* [func SetDatabase(database *gorm.DB)](#SetDatabase) +* [func LoadPlugins(debug bool)](#LoadPlugins) * [type AdvancedNotifier](#AdvancedNotifier) +* [type Asseter](#Asseter) * [type Database](#Database) * [type Databaser](#Databaser) * [type Info](#Info) @@ -1238,7 +1446,7 @@ Package plugin contains the interfaces to build your own Golang Plugin that will #### Package files -[doc.go](https://github.com/hunterlong/statup/tree/master/plugin/doc.go) [main.go](https://github.com/hunterlong/statup/tree/master/plugin/main.go) +[doc.go](https://github.com/hunterlong/statup/tree/master/plugin/doc.go) [interfaces.go](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go) [main.go](https://github.com/hunterlong/statup/tree/master/plugin/main.go) @@ -1248,21 +1456,16 @@ var ( AllPlugins []*PluginObject ) ``` -``` go -var ( - DB *gorm.DB -) -``` -## func [SetDatabase](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1991:2026#L107) +## func [LoadPlugins](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1410:1438#L65) ``` go -func SetDatabase(database *gorm.DB) +func LoadPlugins(debug bool) ``` -## type [AdvancedNotifier](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1440:1583#L67) +## type [AdvancedNotifier](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=493:636#L35) ``` go type AdvancedNotifier interface { notifier.Notifier @@ -1281,7 +1484,22 @@ type AdvancedNotifier interface { -## type [Database](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1796:1818#L91) +## type [Asseter](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=364:421#L26) +``` go +type Asseter interface { + Asset(string) ([]byte, error) +} +``` + + + + + + + + + +## type [Database](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=827:849#L55) ``` go type Database *gorm.DB ``` @@ -1294,7 +1512,7 @@ type Database *gorm.DB -## type [Databaser](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1237:1291#L54) +## type [Databaser](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=207:261#L17) ``` go type Databaser interface { StatupDatabase(*gorm.DB) @@ -1309,7 +1527,7 @@ type Databaser interface { -## type [Info](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1714:1794#L85) +## type [Info](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=745:825#L49) ``` go type Info struct { Name string @@ -1327,7 +1545,7 @@ type Info struct { -## type [Notifier](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1370:1438#L62) +## type [Notifier](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=423:491#L30) ``` go type Notifier interface { notifier.Notifier @@ -1343,7 +1561,7 @@ type Notifier interface { -## type [Plugin](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1820:1882#L93) +## type [Plugin](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=851:913#L57) ``` go type Plugin struct { Name string @@ -1360,7 +1578,7 @@ type Plugin struct { -## type [PluginDatabase](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1884:1952#L98) +## type [PluginDatabase](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=915:983#L62) ``` go type PluginDatabase interface { Database(gorm.DB) @@ -1376,7 +1594,7 @@ type PluginDatabase interface { -## type [PluginInfo](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1954:1989#L103) +## type [PluginInfo](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=985:1020#L67) ``` go type PluginInfo struct { // contains filtered or unexported fields @@ -1392,16 +1610,18 @@ type PluginInfo struct { -### func (\*PluginInfo) [Form](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=2047:2081#L111) +### func (\*PluginInfo) [Form](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1349:1383#L61) ``` go func (p *PluginInfo) Form() string ``` -## type [PluginObject](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=977:1003#L36) +## type [PluginObject](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=112:152#L9) ``` go -type PluginObject struct{} +type PluginObject struct { + PluginInfo +} ``` @@ -1410,7 +1630,7 @@ type PluginObject struct{} -### func [Add](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1042:1076#L42) +### func [Add](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1207:1241#L53) ``` go func Add(p Pluginer) *PluginObject ``` @@ -1418,14 +1638,14 @@ func Add(p Pluginer) *PluginObject -### func (\*PluginObject) [AddRoute](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1106:1177#L46) +### func (\*PluginObject) [AddRoute](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1271:1342#L57) ``` go func (p *PluginObject) AddRoute(s string, i string, f http.HandlerFunc) ``` -## type [Pluginer](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1184:1235#L50) +## type [Pluginer](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=154:205#L13) ``` go type Pluginer interface { Select() *PluginObject @@ -1440,9 +1660,10 @@ type Pluginer interface { -## type [Router](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1293:1368#L58) +## type [Router](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=263:362#L21) ``` go type Router interface { + Routes() []interface{} AddRoute(string, string, http.HandlerFunc) error } ``` @@ -1455,7 +1676,7 @@ type Router interface { -## type [Routing](https://github.com/hunterlong/statup/tree/master/plugin/main.go?s=1607:1712#L79) +## type [Routing](https://github.com/hunterlong/statup/tree/master/plugin/interfaces.go?s=638:743#L43) ``` go type Routing struct { URL string @@ -1491,7 +1712,16 @@ Package source holds all the assets for Statup. This includes CSS, JS, SCSS, HTML and other website related content. This package uses Rice to compile all assets into a single 'rice-box.go' file. -To compile all the assets run `rice embed-go` in the source directory. +### Required Dependencies +- rice -> https://github.com/GeertJohan/go.rice +- sass -> https://sass-lang.com/install + +### Compile Assets +To compile all the HTML, JS, SCSS, CSS and image assets you'll need to have rice and sass installed on your local system. + + + sass source/scss/base.scss source/css/base.css + cd source && rice embed-go More info on: https://github.com/hunterlong/statup @@ -1652,6 +1882,9 @@ More info on: https://github.com/ * [Variables](#pkg-variables) * [type AllNotifiers](#AllNotifiers) * [type Checkin](#Checkin) + * [func (s *Checkin) Close()](#Checkin.Close) + * [func (s *Checkin) IsRunning() bool](#Checkin.IsRunning) + * [func (s *Checkin) Start()](#Checkin.Start) * [type CheckinHit](#CheckinHit) * [type Core](#Core) * [type DbConfig](#DbConfig) @@ -1710,16 +1943,18 @@ AllNotifiers contains all the Notifiers loaded -## type [Checkin](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=811:1230#L23) +## type [Checkin](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=811:1317#L23) ``` go type Checkin struct { Id int64 `gorm:"primary_key;column:id"` - Service int64 `gorm:"index;column:service"` + ServiceId int64 `gorm:"index;column:service"` + Name string `gorm:"column:name"` Interval int64 `gorm:"column:check_interval"` GracePeriod int64 `gorm:"column:grace_period"` ApiKey string `gorm:"column:api_key"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + Running chan bool `gorm:"-" json:"-"` } ``` @@ -1734,7 +1969,34 @@ Checkin struct will allow an application to send a recurring HTTP GET to confirm -## type [CheckinHit](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=1286:1532#L34) +### func (\*Checkin) [Close](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=1787:1812#L49) +``` go +func (s *Checkin) Close() +``` +Close will stop the checkin routine + + + + +### func (\*Checkin) [IsRunning](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=1923:1957#L56) +``` go +func (s *Checkin) IsRunning() bool +``` +IsRunning returns true if the checkin go routine is running + + + + +### func (\*Checkin) [Start](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=1688:1713#L44) +``` go +func (s *Checkin) Start() +``` +Start will create a channel for the checkin checking go routine + + + + +## type [CheckinHit](https://github.com/hunterlong/statup/tree/master/types/checkin.go?s=1373:1619#L36) ``` go type CheckinHit struct { Id int64 `gorm:"primary_key;column:id"` @@ -1828,12 +2090,13 @@ DbConfig struct is used for the database connection and creates the 'config.yml' -## type [Failure](https://github.com/hunterlong/statup/tree/master/types/failure.go?s=862:1324#L24) +## type [Failure](https://github.com/hunterlong/statup/tree/master/types/failure.go?s=862:1405#L24) ``` go type Failure struct { Id int64 `gorm:"primary_key;column:id" json:"id"` Issue string `gorm:"column:issue" json:"issue"` Method string `gorm:"column:method" json:"method,omitempty"` + MethodId int64 `gorm:"column:method_id" json:"method_id,omitempty"` Service int64 `gorm:"index;column:service" json:"-"` PingTime float64 `gorm:"column:ping_time"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` @@ -1853,7 +2116,7 @@ a new Failure will be inserted into database. -## type [FailureInterface](https://github.com/hunterlong/statup/tree/master/types/failure.go?s=1326:1511#L34) +## type [FailureInterface](https://github.com/hunterlong/statup/tree/master/types/failure.go?s=1407:1592#L35) ``` go type FailureInterface interface { Ago() string // Ago returns a human readble timestamp @@ -2102,7 +2365,7 @@ type ServiceInterface interface { -## type [User](https://github.com/hunterlong/statup/tree/master/types/user.go?s=707:1393#L22) +## type [User](https://github.com/hunterlong/statup/tree/master/types/user.go?s=744:1430#L23) ``` go type User struct { Id int64 `gorm:"primary_key;column:id" json:"id"` @@ -2118,6 +2381,7 @@ type User struct { } ``` +User is the main struct for Users @@ -2127,15 +2391,17 @@ type User struct { -## type [UserInterface](https://github.com/hunterlong/statup/tree/master/types/user.go?s=1395:1507#L35) + +## type [UserInterface](https://github.com/hunterlong/statup/tree/master/types/user.go?s=1483:1572#L37) ``` go type UserInterface interface { - // Database functions Create() (int64, error) Update() error Delete() error } ``` +UserInterface interfaces the database functions + @@ -2156,12 +2422,13 @@ type UserInterface interface { * [Overview](#pkg-overview) * [Index](#pkg-index) +* [Examples](#pkg-examples) ## Overview Package utils contains common methods used in most packages in Statup. This package contains multiple function like: Logging, encryption, type conversions, setting utils.Directory as the current directory, -running local CMD commands, and creaing/deleting files/folder. +running local CMD commands, and creating/deleting files/folder. You can overwrite the utils.Directory global variable by including STATUP_DIR environment variable to be an absolute path. @@ -2197,6 +2464,10 @@ More info on: https://github.com/ * [func (t Timestamp) Ago() string](#Timestamp.Ago) * [type Timestamper](#Timestamper) +#### Examples +* [DurationReadable](#example_DurationReadable) +* [StringInt](#example_StringInt) +* [ToString](#example_ToString) #### Package files [doc.go](https://github.com/hunterlong/statup/tree/master/utils/doc.go) [encryption.go](https://github.com/hunterlong/statup/tree/master/utils/encryption.go) [log.go](https://github.com/hunterlong/statup/tree/master/utils/log.go) [time.go](https://github.com/hunterlong/statup/tree/master/utils/time.go) [utils.go](https://github.com/hunterlong/statup/tree/master/utils/utils.go) @@ -2218,43 +2489,76 @@ var ( ``` -## func [Command](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3568:3616#L148) +## func [Command](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3868:3916#L155) ``` go func Command(cmd string) (string, string, error) ``` Command will run a terminal command with 'sh -c COMMAND' and return stdout and errOut as strings + in, out, err := Command("sass assets/scss assets/css/base.css") -## func [DeleteDirectory](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3386:3430#L143) + + +## func [DeleteDirectory](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3618:3662#L149) ``` go func DeleteDirectory(directory string) error ``` DeleteDirectory will attempt to delete a directory and all contents inside + DeleteDirectory("assets") -## func [DeleteFile](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3167:3201#L133) + + +## func [DeleteFile](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3369:3403#L138) ``` go func DeleteFile(file string) error ``` DeleteFile will attempt to delete a file + DeleteFile("newfile.json") -## func [DurationReadable](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=4754:4799#L202) + + +## func [DurationReadable](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=5212:5257#L213) ``` go func DurationReadable(d time.Duration) string ``` +DurationReadable will return a time.Duration into a human readable string -## func [FileExists](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2980:3013#L123) + t := time.Duration(5 * time.Minute) + DurationReadable(t) + // 5 minutes + + + +#### Example + +Code: +``` go +dur, _ := time.ParseDuration("25m") +readable := DurationReadable(dur) +fmt.Print(readable) +``` +Output: + + 25 minutes + + + +## func [FileExists](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=3151:3184#L127) ``` go func FileExists(name string) bool ``` FileExists returns true if a file exists + exists := FileExists("assets/css/base.css") + + ## func [FormatDuration](https://github.com/hunterlong/statup/tree/master/utils/time.go?s=771:814#L24) ``` go @@ -2264,7 +2568,7 @@ FormatDuration converts a time.Duration into a string -## func [HashPassword](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=825:866#L26) +## func [HashPassword](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=833:874#L27) ``` go func HashPassword(password string) string ``` @@ -2296,7 +2600,7 @@ Log creates a new entry in the Logger. Log has 1-5 levels depending on how criti -## func [NewSHA1Hash](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=1026:1059#L32) +## func [NewSHA1Hash](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=1034:1067#L33) ``` go func NewSHA1Hash(n ...int) string ``` @@ -2304,7 +2608,7 @@ NewSHA1Hash returns a random SHA1 hash based on a specific length -## func [RandomString](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=1439:1470#L47) +## func [RandomString](https://github.com/hunterlong/statup/tree/master/utils/encryption.go?s=1447:1478#L48) ``` go func RandomString(n int) string ``` @@ -2312,11 +2616,14 @@ RandomString generates a random string of n length -## func [SaveFile](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=5069:5118#L214) +## func [SaveFile](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=5629:5678#L226) ``` go func SaveFile(filename string, data []byte) error ``` -SaveFile +SaveFile will create a new file with data inside it + + + SaveFile("newfile.json", []byte('{"data": "success"}') @@ -2328,10 +2635,25 @@ StringInt converts a string to an int64 -## func [Timezoner](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1621:1672#L71) +#### Example + +Code: +``` go +amount := "42" +fmt.Print(StringInt(amount)) +``` +Output: + + 42 + + + +## func [Timezoner](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1683:1734#L72) ``` go func Timezoner(t time.Time, zone float32) time.Time ``` +Timezoner returns the time.Time with the user set timezone + ## func [ToString](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1312:1347#L53) @@ -2342,13 +2664,30 @@ ToString converts a int to a string -## func [UnderScoreString](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2295:2335#L99) +#### Example + +Code: +``` go +amount := 42 +fmt.Print(ToString(amount)) +``` +Output: + + 42 + + + +## func [UnderScoreString](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2418:2458#L102) ``` go func UnderScoreString(str string) string ``` UnderScoreString will return a string that replaces spaces and other characters to underscores + UnderScoreString("Example String") + // example_string + + ## type [LogRow](https://github.com/hunterlong/statup/tree/master/utils/log.go?s=3739:3795#L154) @@ -2382,7 +2721,7 @@ func (o *LogRow) FormatForHtml() string -## type [Timestamp](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1929:1953#L87) +## type [Timestamp](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1991:2015#L88) ``` go type Timestamp time.Time ``` @@ -2395,7 +2734,7 @@ type Timestamp time.Time -### func (Timestamp) [Ago](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2087:2118#L93) +### func (Timestamp) [Ago](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2149:2180#L94) ``` go func (t Timestamp) Ago() string ``` @@ -2404,7 +2743,7 @@ Ago returns a human readable timestamp based on the Timestamp (time.Time) interf -## type [Timestamper](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=1954:1998#L88) +## type [Timestamper](https://github.com/hunterlong/statup/tree/master/utils/utils.go?s=2016:2060#L89) ``` go type Timestamper interface { Ago() string