Repository: fuxiaohei/GoBlog Branch: master Commit: e7a14822cddb Files: 124 Total size: 802.6 KB Directory structure: gitextract_0hi50ltt/ ├── LICENSE ├── README.md ├── app/ │ ├── admin.go │ ├── app.go │ ├── cmd/ │ │ ├── backup.go │ │ ├── init.go │ │ ├── install.go │ │ ├── log.go │ │ ├── monitor.go │ │ ├── reboot.go │ │ ├── theme.go │ │ ├── upgrade.go │ │ └── zip.go │ ├── cmd.go │ ├── handler/ │ │ ├── admin.go │ │ ├── cmd.go │ │ ├── func.go │ │ ├── home.go │ │ ├── rss.go │ │ └── upload.go │ ├── log.go │ ├── model/ │ │ ├── article.go │ │ ├── comment.go │ │ ├── content.go │ │ ├── file.go │ │ ├── locker.go │ │ ├── message.go │ │ ├── page.go │ │ ├── setting.go │ │ ├── statis.go │ │ ├── storage.go │ │ ├── timer.go │ │ ├── token.go │ │ ├── user.go │ │ └── version.go │ ├── plugin/ │ │ ├── email.go │ │ ├── hello.go │ │ └── plugin.go │ ├── upgrade/ │ │ ├── v20140130.go │ │ ├── v20140131.go │ │ ├── v20140209.go │ │ └── v20140228.go │ └── utils/ │ ├── avatar.go │ ├── crypto.go │ ├── date.go │ ├── file.go │ ├── html.go │ ├── pager.go │ ├── sorter.go │ └── validator.go ├── main.go ├── static/ │ ├── css/ │ │ ├── admin.css │ │ ├── cmd.css │ │ ├── codemirror.css │ │ ├── common.css │ │ ├── highlight.css │ │ ├── ling.css │ │ ├── saber.css │ │ ├── sitemap.xsl │ │ └── style.css │ ├── js/ │ │ ├── home.js │ │ └── upload.js │ ├── koala-config.json │ └── less/ │ ├── admin.less │ ├── cmd.less │ ├── common/ │ │ ├── base.less │ │ ├── form.less │ │ ├── grid.less │ │ ├── label.less │ │ ├── markdown.less │ │ ├── pager.less │ │ ├── reset.less │ │ └── var.less │ ├── common.less │ ├── ling.less │ ├── saber.less │ └── style.less └── view/ ├── admin/ │ ├── admin.layout │ ├── articles.html │ ├── cmd/ │ │ ├── backup.html │ │ ├── log.html │ │ ├── message.html │ │ ├── monitor.html │ │ ├── reader.html │ │ └── theme.html │ ├── cmd.layout │ ├── comments.html │ ├── edit_article.html │ ├── edit_page.html │ ├── files.html │ ├── home.html │ ├── login.html │ ├── pages.html │ ├── password.html │ ├── plugin.html │ ├── plugin_setting.html │ ├── profile.html │ ├── setting.html │ ├── write_article.html │ └── write_page.html ├── default/ │ ├── article.html │ ├── comment.html │ ├── error/ │ │ ├── error.html │ │ └── notfound.html │ ├── home.layout │ ├── index.html │ └── page.html ├── ling/ │ ├── article.html │ ├── comment.html │ ├── error/ │ │ ├── error.html │ │ └── notfound.html │ ├── home.layout │ ├── index.html │ └── page.html ├── rss.xml ├── saber/ │ ├── article.html │ ├── comment.html │ ├── error/ │ │ ├── error.html │ │ └── notfound.html │ ├── home.layout │ ├── index.html │ ├── page.html │ └── sidebar.html └── sitemap.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 傅小黑 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ ### Notice: this project is deprecated. Please try my new blog engine [pugo](https://github.com/go-xiaohei/pugo). #Fxh.Go A fast and simple blog engine with [GoInk](https://github.com/fuxiaohei/GoInk) framework in Golang. [![Build Status](https://drone.io/github.com/fuxiaohei/GoBlog/status.png)](https://drone.io/github.com/fuxiaohei/GoBlog/latest) [![GoWalker](http://b.repl.ca/v1/Go_Walker-API_Documentation-green.png)](http://gowalker.org/github.com/fuxiaohei/GoBlog) Current version is **0.2.5** on 2014.02.28 Development board is in [Trello](https://trello.com/b/7AHrcQL8/fxh-go-with-goink). ### Overview `Fxh.Go` is a dynamic blog engine written in Golang. It's fast and very simple configs. Fxh.Go persists data into pieces of json files and support compress them as backup zip for next upgrade or installation. `Fxh.Go` supports markdown contents as articles or pages, ajax comments and dynamic administration. `Fxh.Go` contains two kinds of content as article and page. They can be customized as you want. ### Installation `Fxh.Go` requires **Go 1.2** or above. ##### Gobuild.io [Gobuild.io](http://gobuild.io/) can build cross-platform executable file for pure go projects. You can download `Fxh.Go` binary from Gobuild.io. [![Gobuild Download](http://gobuild.io/badge/github.com/fuxiaohei/GoBlog/download.png)](http://gobuild.io/github.com/fuxiaohei/GoBlog) ##### Manual Use go get command: go get github.com/fuxiaohei/GoBlog Then you can find binary file `GoBlog(.exe)` in `$GOPATH/bin`. ### Run Make a new dir to run `Fxh.Go`: cd new_dir Goblog Then it will unzip static files in `new_dir` , initialize raw data and start server at `localhost:9001`. ##### Admin Visit `localhost:9001/login/` to enter administrator with username `admin` and password `admin`. You'd better change them after installed successfully. ##### Deployment I prefer to use nginx as proxy. The server section in `nginx.conf`: server { listen 80; server_name your_domain; charset utf-8; access_log /var/log/nginx/your_domain.access.log; location / { proxy_pass http://127.0.0.1:9001; } location /static { root /var/www/your_domain; # binary file is in this directory expires 1d; add_header Cache-Control public; access_log off; } } ### Questions Create issues or pull requests here. ### Products * [抛弃世俗之浮躁,留我钻研之刻苦](http://wuwen.org) * [FuXiaoHei.Me](http://fuxiaohei.me) ### Thanks * [@Unknwon](https://github.com/Unknwon) on testing and [zip library](https://github.com/Unknwon/cae) support. ### License The MIT License ================================================ FILE: app/admin.go ================================================ package app import "github.com/fuxiaohei/GoBlog/app/handler" func registerAdminHandler() { // add admin handlers App.Get("/admin/", handler.Auth, handler.Admin) App.Route("GET,POST", "/admin/profile/", handler.Auth, handler.AdminProfile) App.Route("GET,POST", "/admin/password/", handler.Auth, handler.AdminPassword) App.Route("GET,POST", "/admin/article/write/", handler.Auth, handler.ArticleWrite) App.Get("/admin/articles/", handler.Auth, handler.AdminArticle) App.Route("GET,POST,DELETE", "/admin/article/:id/", handler.Auth, handler.ArticleEdit) App.Route("GET,POST", "/admin/page/write/", handler.Auth, handler.PageWrite) App.Get("/admin/pages/", handler.Auth, handler.AdminPage) App.Route("GET,POST,DELETE", "/admin/page/:id/", handler.Auth, handler.PageEdit) App.Route("GET,POST,PUT,DELETE", "/admin/comments/", handler.Auth, handler.AdminComments) App.Route("GET,POST", "/admin/setting/", handler.Auth, handler.AdminSetting) App.Post("/admin/setting/custom/", handler.Auth, handler.CustomSetting) App.Post("/admin/setting/nav/", handler.Auth, handler.NavigatorSetting) App.Route("GET,DELETE", "/admin/files/", handler.Auth, handler.AdminFiles) App.Post("/admin/files/upload/", handler.Auth, handler.FileUpload) App.Route("GET,POST", "/admin/plugins/", handler.Auth, handler.AdminPlugin) App.Route("GET,POST", "/admin/plugins/:plugin_key/", handler.Auth, handler.PluginSetting) App.Post("/admin/message/read/", handler.Auth, handler.AdminMessageRead) } ================================================ FILE: app/app.go ================================================ package app import ( "fmt" "github.com/fuxiaohei/GoBlog/app/handler" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/plugin" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" "net/http" "os" "os/signal" "path" "runtime/debug" "strconv" "strings" "syscall" ) var ( // APP VERSION, as date version VERSION = 20140228 // Global GoInk application App *GoInk.App staticFileSuffix = ".css,.js,.jpg,.jpeg,.png,.gif,.ico,.xml,.zip,.txt,.html,.otf,.svg,.eot,.woff,.ttf,.doc,.ppt,.xls,.docx,.pptx,.xlsx,.xsl" uploadFileSuffix = ".jpg,.png,.gif,.zip,.txt,.doc,.docx,.xls,.xlsx,.ppt,.pptx" ) func init() { // init application App = GoInk.New() // init some settings App.Config().StringOr("app.static_dir", "static") App.Config().StringOr("app.log_dir", "tmp/log") os.MkdirAll(App.Get("log_dir"), os.ModePerm) os.MkdirAll("tmp/data", os.ModePerm) App.Config().IntOr("app.upload_size", 1024*1024*10) App.Config().StringOr("app.upload_files", uploadFileSuffix) App.Config().StringOr("app.upload_dir", path.Join(App.Get("static_dir"), "upload")) os.MkdirAll(App.Get("upload_dir"), os.ModePerm) if App.Get("static_files") != "" { staticFileSuffix = App.Get("static_files") } App.Static(func(context *GoInk.Context) { static := App.Config().String("app.static_dir") url := strings.TrimPrefix(context.Url, "/") if url == "favicon.ico" { url = path.Join(static, url) } if !strings.HasPrefix(url, static) { return } if !strings.Contains(staticFileSuffix, context.Ext) { context.Status = 403 context.End() return } f, e := os.Stat(url) if e == nil { if f.IsDir() { context.Status = 403 context.End() return } } /*_, e := os.Stat(url) if e != nil { context.Throw(404) return }*/ http.ServeFile(context.Response, context.Request, url) context.IsEnd = true }) // set recover handler App.Recover(func(context *GoInk.Context) { go LogError(append(append(context.Body, []byte("\n")...), debug.Stack()...)) theme := handler.Theme(context) if theme.Has("error/error.html") { theme.Layout("").Render("error/error", map[string]interface{}{ "error": string(context.Body), "stack": string(debug.Stack()), "context": context, }) } else { context.Body = append([]byte("
"), context.Body...)
			context.Body = append(context.Body, []byte("\n")...)
			context.Body = append(context.Body, debug.Stack()...)
			context.Body = append(context.Body, []byte("
")...) } context.End() }) // set not found handler App.NotFound(func(context *GoInk.Context) { theme := handler.Theme(context) if theme.Has("error/notfound.html") { theme.Layout("").Render("error/notfound", map[string]interface{}{ "context": context, }) } context.End() }) // add recover defer defer func() { e := recover() if e != nil { bytes := append([]byte(fmt.Sprint(e)+"\n"), debug.Stack()...) LogError(bytes) println("panic error, crash down") os.Exit(1) } }() // catch exit command go catchExit() } // code from https://github.com/Unknwon/gowalker/blob/master/gowalker.go func catchExit() { sigTerm := syscall.Signal(15) sig := make(chan os.Signal) signal.Notify(sig, os.Interrupt, sigTerm) for { switch <-sig { case os.Interrupt, sigTerm: println("before exit, saving data") model.SyncAll() println("ready to exit") os.Exit(0) } } } // Init starts Fxh.Go application preparation. // Load models and plugins, update views. func Init() { // init storage model.Init(VERSION) // load all data model.All() // init plugin plugin.Init() // update plugin handlers plugin.Update(App) App.View().FuncMap["DateInt64"] = utils.DateInt64 App.View().FuncMap["DateString"] = utils.DateString App.View().FuncMap["DateTime"] = utils.DateTime App.View().FuncMap["Now"] = utils.Now App.View().FuncMap["Html2str"] = utils.Html2str App.View().FuncMap["FileSize"] = utils.FileSize App.View().FuncMap["Setting"] = model.GetSetting App.View().FuncMap["Navigator"] = model.GetNavigators App.View().FuncMap["Md2html"] = utils.Markdown2HtmlTemplate App.View().IsCache = (model.GetSetting("theme_cache") == "true") println("app version @ " + strconv.Itoa(model.GetVersion().Version)) } func registerHomeHandler() { App.Route("GET,POST", "/login/", handler.Login) App.Get("/logout/", handler.Logout) App.Get("/article/:id/:slug", handler.Article) App.Get("/page/:id/:slug", handler.Page) App.Get("/p/:page/", handler.Home) App.Post("/comment/:id/", handler.Comment) App.Get("/tag/:tag/", handler.TagArticles) App.Get("/tag/:tag/p/:page/", handler.TagArticles) App.Get("/feed/", handler.Rss) App.Get("/sitemap", handler.SiteMap) App.Get("/:slug", handler.TopPage) App.Get("/", handler.Home) } // Run begins Fxh.Go http server. func Run() { registerAdminHandler() registerCmdHandler() registerHomeHandler() App.Run() } ================================================ FILE: app/cmd/backup.go ================================================ package cmd import ( "github.com/Unknwon/cae/zip" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" "os" "path" "path/filepath" "time" ) var backupDir = "backup" func init() { // close zip terminal output zip.Verbose = false } // DoBackup backups whole files to zip archive. // If withData is false, it compresses static files to zip archive without data files, config files and install lock file. func DoBackup(app *GoInk.App, withData bool) (string, error) { os.Mkdir(backupDir, os.ModePerm) // create zip file name from time unix filename := path.Join(backupDir, utils.DateTime(time.Now(), "YYYYMMDDHHmmss")) if withData { filename += ".zip" } else { filename += "_static.zip" } z, e := zip.Create(filename) if e != nil { return "", e } root, _ := os.Getwd() if withData { // if with data, add install lock file and config file lockFile := path.Join(root, "install.lock") if utils.IsFile(lockFile) { z.AddFile("install.lock", lockFile) } configFile := path.Join(root, "config.json") if utils.IsFile(configFile) { z.AddFile("config.json", configFile) } } z.AddDir("static/css", path.Join(root, "static", "css")) z.AddDir("static/img", path.Join(root, "static", "img")) z.AddDir("static/js", path.Join(root, "static", "js")) z.AddDir("static/lib", path.Join(root, "static", "lib")) z.AddFile("static/favicon.ico", path.Join(root, "static", "favicon.ico")) if withData { // if with data, backup data files and uploaded files z.AddDir("data", path.Join(root, "data")) z.AddDir("static/upload", path.Join(root, "static", "upload")) } z.AddDir(app.View().Dir, path.Join(root, app.View().Dir)) e = z.Flush() if e != nil { return "", e } println("backup success in " + filename) return filename, nil } // RemoveBackupFile removes backup zip file with filename(not filepath). func RemoveBackupFile(file string) { file = path.Join(backupDir, file) os.Remove(file) } // GetBackupFileAbsPath returns backup zip absolute filepath by filename. func GetBackupFileAbsPath(name string) string { return path.Join(backupDir, name) } // GetBackupFile returns fileinfo slice of all backup files. func GetBackupFiles() ([]os.FileInfo, error) { fi := make([]os.FileInfo, 0) e := filepath.Walk(backupDir, func(_ string, info os.FileInfo, _ error) error { if info == nil { return nil } if !info.IsDir() { fi = append([]os.FileInfo{info}, fi...) } return nil }) return fi, e } // StartBackupTimer starts backup operation timer for auto backup stuff. func StartBackupTimer(app *GoInk.App, t int) { model.SetTimerFunc("backup-data", 144, func() { filename, e := DoBackup(app, true) if e != nil { model.CreateMessage("backup", "[0]"+e.Error()) } else { model.CreateMessage("backup", "[1]"+filename) } println("backup files in", t, "hours") }) } ================================================ FILE: app/cmd/init.go ================================================ package cmd import "github.com/fuxiaohei/GoInk" func Init(app *GoInk.App) { StartBackupTimer(app, 24) } ================================================ FILE: app/cmd/install.go ================================================ package cmd import ( "bytes" "encoding/base64" "fmt" "github.com/Unknwon/cae/zip" "github.com/fuxiaohei/GoBlog/app/utils" "io/ioutil" "os" ) var ( tmpZipFile = "tmp.zip" installLockFile = "install.lock" ) func CheckInstall() bool { _, e := os.Stat(installLockFile) return e == nil } func ExtractBundleBytes() { // origin from https://github.com/wendal/gor/blob/master/gor/gor.go decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(zipBytes)) b, _ := ioutil.ReadAll(decoder) ioutil.WriteFile(tmpZipFile, b, os.ModePerm) z, e := zip.Open(tmpZipFile) if e != nil { panic(e) os.Exit(1) } z.ExtractTo("") defer func() { z.Close() decoder = nil os.Remove(tmpZipFile) }() } func DoInstall() { ExtractBundleBytes() ioutil.WriteFile(installLockFile, []byte(fmt.Sprint(utils.Now())), os.ModePerm) println("install success") } func DoUpdateZipBytes(file string) error { // copy from https://github.com/wendal/gor/blob/master/gor/gor.go bytes, _ := ioutil.ReadFile(file) zipWriter, _ := os.OpenFile("app/cmd/zip.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm) header := `package cmd const zipBytes="` zipWriter.Write([]byte(header)) encoder := base64.NewEncoder(base64.StdEncoding, zipWriter) encoder.Write(bytes) encoder.Close() zipWriter.Write([]byte(`"`)) zipWriter.Sync() zipWriter.Close() println("update success") return nil } ================================================ FILE: app/cmd/log.go ================================================ package cmd import ( "github.com/fuxiaohei/GoInk" "io/ioutil" "os" "path/filepath" ) type logItem struct { Name string CreateTime int64 Text string } func GetLogs(app *GoInk.App) []*logItem { dir := app.Get("log_dir") logs := make([]*logItem, 0) filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error { if err == nil { if info.IsDir() { return nil } ext := filepath.Ext(info.Name()) if ext != ".log" { return nil } bytes, e := ioutil.ReadFile(filepath.Join(dir, info.Name())) if e != nil { return nil } l := new(logItem) l.Name = info.Name() l.CreateTime = info.ModTime().Unix() l.Text = string(bytes) logs = append([]*logItem{l}, logs...) } return nil }) return logs } func RemoveLogFile(app *GoInk.App, file string) { f := filepath.Join(app.Get("log_dir"), file) os.Remove(f) } ================================================ FILE: app/cmd/monitor.go ================================================ package cmd import ( "fmt" "github.com/fuxiaohei/GoBlog/app/utils" "runtime" "time" ) type monitorStats struct { NumGoroutine int MemAllocated string MemMalloc string MemTotal string MemSys string MemHeap string MemGc string LastGcTime string } func ReadMemStats() *monitorStats { m := new(runtime.MemStats) runtime.ReadMemStats(m) ms := new(monitorStats) ms.NumGoroutine = runtime.NumGoroutine() ms.MemAllocated = utils.FileSize(int64(m.Alloc)) ms.MemTotal = utils.FileSize(int64(m.TotalAlloc)) ms.MemSys = utils.FileSize(int64(m.Sys)) ms.MemHeap = utils.FileSize(int64(m.HeapAlloc)) ms.MemMalloc = utils.FileSize(int64(m.Mallocs)) ms.LastGcTime = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000) ms.MemGc = utils.FileSize(int64(m.NextGC)) return ms } ================================================ FILE: app/cmd/reboot.go ================================================ package cmd ================================================ FILE: app/cmd/theme.go ================================================ package cmd import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "io/ioutil" "path/filepath" ) var adminTheme = "admin" type themeItem struct { Name string Files []string ErrorFiles []string Layout []string } func SetThemeCache(ctx *GoInk.Context, cache bool) { ctx.App().View().NoCache() ctx.App().View().IsCache = cache if cache { model.SetSetting("theme_cache", "true") } else { model.SetSetting("theme_cache", "false") } model.SyncSettings() } func GetThemes(dir string) map[string]*themeItem { m := make(map[string]*themeItem) files, e := ioutil.ReadDir(dir) if e != nil { panic(e) } for _, fi := range files { if fi.IsDir() && fi.Name() != adminTheme { theme, e := createThemeItem(filepath.Join(dir, fi.Name())) if e != nil { continue } theme.Name = fi.Name() m[fi.Name()] = theme } } return m } func createThemeItem(dir string) (*themeItem, error) { files, e := ioutil.ReadDir(dir) if e != nil { return nil, e } theme := new(themeItem) theme.Files = make([]string, 0) theme.Layout = make([]string, 0) for _, fi := range files { if fi.IsDir() { if fi.Name() == "error" { theme.ErrorFiles, _ = filepath.Glob(filepath.Join(dir, fi.Name(), "*.html")) for i, f := range theme.ErrorFiles { theme.ErrorFiles[i] = filepath.Join(fi.Name(), filepath.Base(f)) } } else { f, _ := filepath.Glob(filepath.Join(dir, fi.Name(), "*.html")) for _, ff := range f { theme.Files = append(theme.Files, filepath.Join(fi.Name(), filepath.Base(ff))) } } } else { ext := filepath.Ext(fi.Name()) if ext == ".html" { theme.Files = append(theme.Files, fi.Name()) continue } if ext == ".layout" { theme.Layout = append(theme.Layout, fi.Name()) } } } return theme, nil } ================================================ FILE: app/cmd/upgrade.go ================================================ package cmd import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "sort" "strconv" ) var upgradeScript map[int]func(app *GoInk.App) bool func init() { upgradeScript = make(map[int]func(app *GoInk.App) bool) } func SetUpgradeScript(v int, script func(app *GoInk.App) bool) { upgradeScript[v] = script } func CheckUpgrade(v int, print bool) bool { model.Init(v) appV := model.GetVersion() b := v > appV.Version if b && print { println("app version @ " + strconv.Itoa(v) + " is ahead of current version @ " + strconv.Itoa(appV.Version) + " , please run 'GoBlog upgrade'") } return b } func DoUpgrade(v int, app *GoInk.App) { if !CheckUpgrade(v, false) { println("app version @", v, "is updated") return } oldVersion := model.GetVersion().Version scriptIndex := []int{} for vr, _ := range upgradeScript { if vr <= v && vr > oldVersion { scriptIndex = append(scriptIndex, vr) } } sort.Sort(sort.IntSlice(scriptIndex)) for _, cv := range scriptIndex { upgradeScript[cv](app) println("upgrade @", cv, "success") } model.GetVersion().Version = v model.SyncVersion() println("app has upgraded to version @", v, "successfully, restart and keep enjoy !!") } ================================================ FILE: app/cmd/zip.go ================================================ package cmd const zipBytes="UEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAc3RhdGljL1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAAsAAABzdGF0aWNcY3NzL1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABQAAABzdGF0aWNcY3NzXGFkbWluLmNzc2JvZHksZGl2LGRsLGR0LGRkLHVsLG9sLGxpLGgxLGgyLGgzLGg0LGg1LGg2LHByZSxjb2RlLGZvcm0sZmllbGRzZXQsbGVnZW5kLGlucHV0LHRleHRhcmVhLHAsYmxvY2txdW90ZSx0aCx0ZHttYXJnaW46MDtwYWRkaW5nOjB9aGVhZGVyLGZvb3RlcixzZWN0aW9uLGFydGljbGUsYXNpZGUsbmF2LGhncm91cCxhZGRyZXNzLGZpZ3VyZSxmaWdjYXB0aW9uLG1lbnUsZGV0YWlsc3tkaXNwbGF5OmJsb2NrfWF1ZGlvLGNhbnZhcyx2aWRlb3tkaXNwbGF5OmlubGluZS1ibG9ja310YWJsZXtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Ym9yZGVyLXNwYWNpbmc6MH1maWVsZHNldCxpbWd7Ym9yZGVyOjB9YWRkcmVzcyxjYXB0aW9uLGNpdGUsY29kZSxkZm4sZW0sdGgsdmFye2ZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbH1vbCx1bHtsaXN0LXN0eWxlOm5vbmV9Y2FwdGlvbix0aHt0ZXh0LWFsaWduOmxlZnR9aDEsaDIsaDMsaDQsaDUsaDZ7Zm9udC1zaXplOjEwMCU7Zm9udC13ZWlnaHQ6bm9ybWFsfXE6YmVmb3JlLHE6YWZ0ZXJ7Y29udGVudDonJ31hYmJyLGFjcm9ueW17Ym9yZGVyOjA7Zm9udC12YXJpYW50Om5vcm1hbH1zdXB7dmVydGljYWwtYWxpZ246dGV4dC10b3B9c3Vie3ZlcnRpY2FsLWFsaWduOnRleHQtYm90dG9tfWlucHV0LHRleHRhcmVhLHNlbGVjdHtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZTppbmhlcml0O2ZvbnQtd2VpZ2h0OmluaGVyaXR9bGVnZW5ke2NvbG9yOiMwMDB9aHRtbCxib2R5e2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNHB4O2xpbmUtaGVpZ2h0OjMwcHg7Y29sb3I6IzMzMztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9YXt0ZXh0LWRlY29yYXRpb246bm9uZTtjb2xvcjojMDA3OWJjfWE6aG92ZXJ7Y29sb3I6IzAwNWI5Yn1we21hcmdpbi1ib3R0b206MThweH1oMSxoMixoMyxoNCxoNSxoNntwYWRkaW5nOjEycHggMH1oMXtmb250LXNpemU6MjhweH1oMntmb250LXNpemU6MjRweH1oM3tmb250LXNpemU6MjFweH1oNHtmb250LXNpemU6MTlweH1oNXtmb250LXNpemU6MTZweH1oNntmb250LXNpemU6MTRweH0udGV4dC1sZWZ0e3RleHQtYWxpZ246bGVmdH0udGV4dC1yaWdodHt0ZXh0LWFsaWduOnJpZ2h0fS50ZXh0LWNlbnRlcnt0ZXh0LWFsaWduOmNlbnRlcn0ubGVmdHtmbG9hdDpsZWZ0fS5yaWdodHtmbG9hdDpyaWdodH0uYWJzb2x1dGV7cG9zaXRpb246YWJzb2x1dGV9LnJlbGF0aXZle3Bvc2l0aW9uOnJlbGF0aXZlfS5jbGVhcjphZnRlcnt2aXNpYmlsaXR5OmhpZGRlbjtkaXNwbGF5OmJsb2NrO2ZvbnQtc2l6ZTowO2NvbnRlbnQ6IiAiO2NsZWFyOmJvdGg7aGVpZ2h0OjB9LnZlcnRpY2FsLW1pZGRsZXt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9LmlubGluZXtkaXNwbGF5OmlubGluZX0uaW5saW5lLWJsb2Nre2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5ibG9ja3tkaXNwbGF5OmJsb2NrfS5mYWRlLW91dHtvcGFjaXR5OjB9LmhpZGV7ZGlzcGxheTpub25lICFpbXBvcnRhbnR9LmNvbnRhaW5lcnttYXgtd2lkdGg6MTIwMHB4O21hcmdpbjphdXRvfS5jb250YWluZXI5NjB7bWF4LXdpZHRoOjk2MHB4O21hcmdpbjphdXRvfS5ncmlkLTEtMnt3aWR0aDo1MCV9LmdyaWQtMS0ze3dpZHRoOjMzLjMzMzMlfS5ncmlkLTEtNHt3aWR0aDoyNSV9LmdyaWQtMS01e3dpZHRoOjIwJX0uZ3JpZC0xLTZ7d2lkdGg6MTYuNjY2NiV9LmdyaWQtMi0ze3dpZHRoOjY2LjY2NjYlfS5ncmlkLTMtNHt3aWR0aDo3NSV9LmdyaWQtMy01e3dpZHRoOjYwJX0uZ3JpZC00LTV7d2lkdGg6ODAlfS5ncmlkLTUtNnt3aWR0aDo4My4zMzMzJX1pbnB1dCx0ZXh0YXJlYSxzZWxlY3QsYnV0dG9ue2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmfS5mb3JtIGxlZ2VuZHtmb250LXNpemU6MThweDttYXJnaW4tYm90dG9tOjE0cHh9LmZvcm0gbGFiZWx7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLmlwdHtwYWRkaW5nOjhweCAxMnB4O2JvcmRlcjoxcHggc29saWQgIzk5OTtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHg7b3V0bGluZTpub25lO21pbi13aWR0aDoxODBweH0uZm9ybSAuaXB0OmZvY3Vze2JvcmRlci1jb2xvcjojMDA3OWJjfS5mb3JtIC5jaGt7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luOjJweCA2cHggMCAwO2xpbmUtaGVpZ2h0Om5vcm1hbH0uZm9ybSAuZmllbGR7bWFyZ2luLWJvdHRvbToyNHB4fS5mb3JtIC5pbnZhbGlke21hcmdpbi1yaWdodDoxMnB4fS5mb3JtIC50aXB7Zm9udC1zaXplOjEzcHg7Y29sb3I6Izk5OTttYXJnaW4tbGVmdDoxMnB4fS5mb3JtLXZlcnRpY2FsIGxhYmVse2Rpc3BsYXk6YmxvY2s7bWFyZ2luLWJvdHRvbTo4cHh9LmZvcm0tdmVydGljYWwgLmlwdHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveH0uZm9ybS12ZXJ0aWNhbCAuaW52YWxpZHttYXJnaW4tcmlnaHQ6MDttYXJnaW4tdG9wOjZweH0uZm9ybS1hbGlnbiBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttaW4td2lkdGg6NjBweDt0ZXh0LWFsaWduOnJpZ2h0fS5mb3JtLWFsaWduIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5idG57bWluLXdpZHRoOjEyMHB4O2hlaWdodDozNnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7Ym9yZGVyOm5vbmU7bWFyZ2luOjB9LmJ0bjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM5OTk7Y3Vyc29yOnBvaW50ZXJ9YS5idG57bGluZS1oZWlnaHQ6MzZweDtjb2xvcjojZmZmfS5idG4tcmVke2JhY2tncm91bmQtY29sb3I6I2U2NDM0Njtjb2xvcjojZmJmYmZifS5idG4tcmVkOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2M3MzgzYX0uYnRuLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9LmJ0bi1ibHVlOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzAwNWI5Yn0uYnRuLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifS5idG4tZ3JlZW46aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNjQ5NDYyfS5sYmx7cGFkZGluZzo0cHggMTJweDtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7Y29sb3I6IzMzMztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LmxibC1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9YS5sYmx7bGluZS1oZWlnaHQ6MjZweH1hLmxibC1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhO2NvbG9yOiNmYmZiZmJ9LmxibC1ibHVle2JhY2tncm91bmQtY29sb3I6IzAwNzliYztjb2xvcjojZmJmYmZifWEubGJsLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjliO2NvbG9yOiNmYmZiZmJ9LmxibC1ncmVlbntiYWNrZ3JvdW5kLWNvbG9yOiM3YWIyNzc7Y29sb3I6I2ZiZmJmYn1hLmxibC1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjI7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLml0ZW17cGFkZGluZzoycHggOHB4O21hcmdpbjowIDZweDtjb2xvcjojMzMzO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2xpbmUtaGVpZ2h0OjIwcHh9LnBhZ2VyIC5pdGVtIGF7Y29sb3I6IzMzM30ucGFnZXIgLml0ZW06aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLml0ZW06aG92ZXIgYXtjb2xvcjojZmZmfS5wYWdlciAuY3VycmVudHtiYWNrZ3JvdW5kLWNvbG9yOiM2NjY7Y29sb3I6I2ZiZmJmYjtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LnBhZ2VyIC5jdXJyZW50IGF7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLmN1cnJlbnQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjfS5tYXJrZG93biBoMSwubWFya2Rvd24gaDIsLm1hcmtkb3duIGgzLC5tYXJrZG93biBoNCwubWFya2Rvd24gaDUsLm1hcmtkb3duIGg2e3BhZGRpbmc6MThweCAwIDlweCAwO2ZvbnQtd2VpZ2h0OmJvbGR9Lm1hcmtkb3duIGgxe2ZvbnQtc2l6ZToyNHB4fS5tYXJrZG93biBoMntmb250LXNpemU6MjFweH0ubWFya2Rvd24gaDEsLm1hcmtkb3duIGgye21hcmdpbi1ib3R0b206MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfS5tYXJrZG93biBoM3tmb250LXNpemU6MTlweH0ubWFya2Rvd24gaDR7Zm9udC1zaXplOjE4cHh9Lm1hcmtkb3duIGg1e2ZvbnQtc2l6ZToxNnB4fS5tYXJrZG93biBoNntmb250LXNpemU6MTRweH0ubWFya2Rvd24gcHttYXJnaW4tYm90dG9tOjEwcHh9Lm1hcmtkb3duIHVse2xpc3Qtc3R5bGU6ZGlzYyBpbnNpZGV9Lm1hcmtkb3duIG9se2xpc3Qtc3R5bGU6ZGVjaW1hbCBpbnNpZGV9Lm1hcmtkb3duIGNvZGV7Zm9udC1mYW1pbHk6Q29uc29sYXMsIkNvdXJpZXIgTmV3IixBcmlhbH0ubWFya2Rvd24gcCBjb2Rle2NvbG9yOiNjNzM4M2F9Lm1hcmtkb3duIGJsb2NrcXVvdGV7cGFkZGluZzo4cHggMThweDtib3JkZXItbGVmdDo0cHggc29saWQgI2NjYztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9Lm1hcmtkb3duIGJsb2NrcXVvdGUgcHttYXJnaW4tYm90dG9tOjB9Lm1hcmtkb3duIHByZSBjb2Rle2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjE4cHggIWltcG9ydGFudDtwYWRkaW5nOjhweCAxOHB4O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjEycHggMCAxOHB4IDB9Lm1hcmtkb3duIG9sLC5tYXJrZG93biB1bHttYXJnaW46MTJweCAyNHB4fS5tYXJrZG93biBwIGltZ3ttYXgtd2lkdGg6OTklO2hlaWdodDphdXRvO21hcmdpbjowIGF1dG87ZGlzcGxheTpibG9ja30ubWFya2Rvd24gdGFibGV7bWFyZ2luOjEycHggMDt3aWR0aDo5OCV9Lm1hcmtkb3duIHRhYmxlIHRoLC5tYXJrZG93biB0YWJsZSB0ZHtib3JkZXI6MXB4IHNvbGlkICNjY2M7cGFkZGluZzo0cHggMTJweH0ubWFya2Rvd24gdGFibGUgdGhlYWR7YmFja2dyb3VuZDojZjZmNmY2fTo6LXdlYmtpdC1zY3JvbGxiYXJ7d2lkdGg6OHB4O21hcmdpbi1yaWdodDoycHh9Ojotd2Via2l0LXNjcm9sbGJhci10cmFjay1waWVjZXtiYWNrZ3JvdW5kLWNvbG9yOiNmNWY1ZjU7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkICNkMmQyZDJ9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYntiYWNrZ3JvdW5kOiM5ZmEwOWM7d2lkdGg6OHB4fTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXJ7YmFja2dyb3VuZDojYjdiOGFkfSNoZWFkZXJ7aGVpZ2h0OjM5cHg7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICM5OTk7bGluZS1oZWlnaHQ6MzlweDtib3gtc2hhZG93OjAgMCAycHggI2NjYzstbW96LWJveC1zaGFkb3c6MCAwIDJweCAjY2NjOy13ZWJraXQtYm94LXNoYWRvdzowIDAgMnB4ICNjY2N9I2hlYWRlciAubmF2PmF7ZGlzcGxheTppbmxpbmUtYmxvY2s7cGFkZGluZzowIDE4cHg7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkICNjY2M7Ym9yZGVyLXJpZ2h0OjFweCBzb2xpZCAjY2NjO2NvbG9yOiM2NjY7bWFyZ2luLWxlZnQ6LTFweH0jaGVhZGVyIC5uYXY+YTpob3Zlcntib3JkZXItY29sb3I6IzAwNzliYztiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmM7Y29sb3I6I2ZiZmJmYn0jaGVhZGVyIC5sb2dve2xpbmUtaGVpZ2h0OjM2cHg7cGFkZGluZzowIDE0cHggMCAwO21hcmdpbjowO2ZvbnQtc2l6ZToxNHB4fSNoZWFkZXIgLm5hdi1pdGVte2Rpc3BsYXk6aW5saW5lLWJsb2NrO3BhZGRpbmc6MCAxOHB4O2JvcmRlci1sZWZ0OjFweCBzb2xpZCAjY2NjO2JvcmRlci1yaWdodDoxcHggc29saWQgI2NjYztjb2xvcjojNjY2O21hcmdpbi1yaWdodDotMXB4fSNoZWFkZXIgLm5hdi1pdGVtOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2VlZX0jaGVhZGVyIC5vdXR7Y29sb3I6I2M3MzgzYX0jaGVhZGVyIC5vdXQ6aG92ZXJ7Ym9yZGVyLWNvbG9yOiNlNjQzNDY7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9I2Zvb3RlcntwYWRkaW5nOjI0cHg7YmFja2dyb3VuZDojZjZmNmY2O2JvcmRlci10b3A6MXB4IHNvbGlkICNkZGQ7bWFyZ2luLXRvcDozMHB4O2NvbG9yOiM5OTk7Zm9udC1zaXplOjEycHh9I2Zvb3RlciBwe21hcmdpbi1ib3R0b206MH0jZm9vdGVyIGF7Y29sb3I6Izk5OTtwYWRkaW5nOjZweCAxMnB4fSNmb290ZXIgYTpob3Zlcntib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2JiYn0uYWRtaW57bWFyZ2luOjI0cHggYXV0byA0OHB4IGF1dG99I3Byb2ZpbGV7d2lkdGg6ODAwcHg7bWFyZ2luOjI0cHggYXV0byA0OHB4IGF1dG99I3Byb2ZpbGUgLmF2YXRhciBpbWd7d2lkdGg6MTgwcHg7cGFkZGluZzo0cHg7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JvcmRlcjoxcHggc29saWQgI2RkZDtib3JkZXItcmFkaXVzOjRweDstbW96LWJvcmRlci1yYWRpdXM6NHB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czo0cHg7aGVpZ2h0OjE4MHB4fSNwcm9maWxlIC5pcHR7d2lkdGg6MjgwcHh9I3Byb2ZpbGUgLmludmFsaWR7bWFyZ2luLWxlZnQ6NzVweH0jcHJvZmlsZSAuYmlve21hcmdpbi1sZWZ0Ojc1cHg7aGVpZ2h0OjE2MHB4fSNwYXNzd29yZHt3aWR0aDo0MDBweDttYXJnaW46MjRweCBhdXRvIDQ4cHggYXV0b30jcGFzc3dvcmQgLmludmFsaWR7bWFyZ2luLWxlZnQ6NzVweH0jYXJ0aWNsZS1saXN0e21hcmdpbi1ib3R0b206MjRweH0jYXJ0aWNsZS1saXN0IGxpe21hcmdpbi1ib3R0b206OHB4O3BhZGRpbmctYm90dG9tOjhweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jYXJ0aWNsZS1saXN0IGxpPip7bWFyZ2luLXJpZ2h0OjE2cHh9I2FydGljbGUtbGlzdCBsaSAudGltZSwjYXJ0aWNsZS1saXN0IGxpIC5jb21tZW50e2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWY7Y29sb3I6Izk5OX0jYXJ0aWNsZS1saXN0IGxpIC5jb21tZW50e2NvbG9yOiM2NDk0NjJ9I2FydGljbGUtbGlzdCBsaSAuY29tbWVudCAuZmF7bWFyZ2luLXJpZ2h0OjZweH0jYXJ0aWNsZS1saXN0IGxpIC5pcy1jb21tZW50e2NvbG9yOiNmZjQ0NDd9I2FydGljbGUtbGlzdCBsaSAuaXMtY29tbWVudCAuZmF7bWFyZ2luLXJpZ2h0OjZweH0jYXJ0aWNsZS1saXN0IGxpIC5kZWwsI2FydGljbGUtbGlzdCBsaSAuZWRpdHtvcGFjaXR5OjB9I2FydGljbGUtbGlzdCBsaTpob3ZlciAuZGVsLCNhcnRpY2xlLWxpc3QgbGk6aG92ZXIgLmVkaXR7b3BhY2l0eToxfSNhcnRpY2xlLWxpc3QgbGk6Zmlyc3QtY2hpbGQgaDR7cGFkZGluZy10b3A6MH0jYXJ0aWNsZS1mb3Jte21hcmdpbjoyNHB4IGF1dG8gNDhweCBhdXRvfSNhcnRpY2xlLWZvcm0gaW5wdXQudGl0bGV7d2lkdGg6MTAwJTtib3gtc2l6aW5nOmJvcmRlci1ib3g7Ym9yZGVyLWJvdHRvbTpub25lO21hcmdpbi1ib3R0b206LTFweDtmb250LXNpemU6MThweH0jYXJ0aWNsZS1mb3JtIHNlbGVjdHtwYWRkaW5nOjRweCA2cHh9I2FydGljbGUtZm9ybSAucHJldmlld3tib3JkZXI6MXB4IHNvbGlkICM5OTk7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JveC1zaXppbmc6Ym9yZGVyLWJveDtwYWRkaW5nOjAgMTJweDtoZWlnaHQ6NzAwcHg7bWFyZ2luLWxlZnQ6LTFweDtib3JkZXItcmFkaXVzOjJweDtvdmVyZmxvdy14OnNjcm9sbH0jYXJ0aWNsZS1mb3JtIC5mb3JtLXZlcnRpY2Fse3dpZHRoOjEwMCU7bWFyZ2luLXRvcDoxOHB4fSNhcnRpY2xlLWZvcm0gLmZvcm0tdmVydGljYWwgaW5wdXQuaXB0e3dpZHRoOjMwMHB4fSNhcnRpY2xlLWZvcm0gLmZvcm0tdmVydGljYWwgLml0ZW17ZmxvYXQ6bGVmdDttYXJnaW4tcmlnaHQ6MThweH0jYXJ0aWNsZS1mb3JtIC5mb3JtLXZlcnRpY2FsIC5idG57bWFyZ2luLXJpZ2h0OjE2cHh9I2FydGljbGUtZm9ybSAuZm9ybS12ZXJ0aWNhbCAuaW52YWxpZHtkaXNwbGF5OmlubGluZX0jYXJ0aWNsZS1mb3JtIC5maWxlLXByb2dyZXNze3BhZGRpbmc6MCAxMnB4O2JhY2tncm91bmQ6cmdiYSgwLDE1MCwyMjMsMC4yKTtjb2xvcjojNjY2O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWY7Ym94LXNpemluZzpib3JkZXItYm94O2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0jYXJ0aWNsZS1mb3JtIC5maWxlLXByb2dyZXNzLmVycntiYWNrZ3JvdW5kOnJnYmEoMjU1LDY4LDcxLDAuMik7Y29sb3I6I2FhMzkzY30jc2V0dGluZy1uYXZ7d2lkdGg6MTAwMHB4O21hcmdpbi10b3A6MjRweDttYXJnaW4tYm90dG9tOjEycHg7cGFkZGluZy1ib3R0b206MTJweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jc2V0dGluZy1uYXYgbGl7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luOjAgMTJweH0jc2V0dGluZy1uYXYgbGkgYXtwYWRkaW5nOjNweCAxMHB4fSNzZXR0aW5nLW5hdiBsaSBhOmhvdmVyLCNzZXR0aW5nLW5hdiBsaSBhLmN1cnJlbnR7Ym9yZGVyLWJvdHRvbToycHggc29saWQgIzAwNWI5Yn0uc2V0dGluZy1wYW5lbHtkaXNwbGF5Om5vbmV9LnNldHRpbmctZm9ybXt3aWR0aDo4MjBweDttYXJnaW46MjRweCBhdXRvIDQ4cHggYXV0b30uc2V0dGluZy1mb3JtIC5pcHR7d2lkdGg6NDgwcHh9LnNldHRpbmctZm9ybSAuaW52YWxpZHttYXJnaW4tbGVmdDo3NXB4fS5zZXR0aW5nLWZvcm0gbGFiZWx7bWluLXdpZHRoOjEwZW19LnNldHRpbmctZm9ybSAudGlwLmJsb2Nre21hcmdpbi1sZWZ0OjEyZW19I3NldHRpbmctY3VzdG9tLWZvcm17d2lkdGg6MTAwMHB4fSNzZXR0aW5nLWN1c3RvbS1mb3JtIGlucHV0LmtleXt3aWR0aDoyNDBweH0jc2V0dGluZy1jdXN0b20tZm9ybSBpbnB1dC52YWx1ZXt3aWR0aDo2NDBweH0jc2V0dGluZy1jdXN0b20tZm9ybSAuaXRlbXttYXJnaW4tYm90dG9tOjEycHg7cGFkZGluZy1ib3R0b206MTJweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jc2V0dGluZy1jdXN0b20tZm9ybSAuZGVse21hcmdpbi1sZWZ0OjEycHg7Y29sb3I6I2U2NDM0Njtmb250LXNpemU6MTJweH0jc2V0dGluZy1jdXN0b20tZm9ybSAudGlwe21hcmdpbi1sZWZ0OjB9I3NldHRpbmctbmF2LWZvcm17d2lkdGg6MTAwMHB4fSNzZXR0aW5nLW5hdi1mb3JtIC5pdGVte21hcmdpbi1ib3R0b206MTJweDtwYWRkaW5nLWJvdHRvbToxMnB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfSNzZXR0aW5nLW5hdi1mb3JtIHNwYW4ubGFiZWx7bWFyZ2luLXJpZ2h0OjZweH0jc2V0dGluZy1uYXYtZm9ybSBpbnB1dC5vcmRlcnt3aWR0aDoyLjVlbTttaW4td2lkdGg6MH0jc2V0dGluZy1uYXYtZm9ybSBpbnB1dC50ZXh0e3dpZHRoOjgwcHg7bWluLXdpZHRoOjB9I3NldHRpbmctbmF2LWZvcm0gaW5wdXQudGl0bGV7d2lkdGg6MTUwcHg7bWluLXdpZHRoOjB9I3NldHRpbmctbmF2LWZvcm0gaW5wdXQubGlua3t3aWR0aDozNDBweH0jc2V0dGluZy1uYXYtZm9ybSAuZGVse21hcmdpbi1sZWZ0OjEycHg7Y29sb3I6I2U2NDM0Nn0jY29tbWVudC1saXN0IC5jLWF2YXRhcnt3aWR0aDo0OHB4O2hlaWdodDo0OHB4O3BhZGRpbmc6MnB4O2JvcmRlcjoxcHggc29saWQgI2NjYztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHg7bWFyZ2luLXJpZ2h0OjE4cHh9I2NvbW1lbnQtbGlzdCAuY29tbWVudHttYXJnaW4tYm90dG9tOjEycHg7cGFkZGluZy1ib3R0b206MTJweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jY29tbWVudC1saXN0IC5jLW1ldGE+KnttYXJnaW4tcmlnaHQ6MTZweH0jY29tbWVudC1saXN0IC5jLXRpbWV7Y29sb3I6Izk5OTtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNjb21tZW50LWxpc3QgLmMtdGltZSAuZmF7bWFyZ2luLXJpZ2h0OjZweH0jY29tbWVudC1saXN0IC5jLWNudCwjY29tbWVudC1saXN0IC5jLWVtYWlse2NvbG9yOiM5OTk7Zm9udC1zaXplOjEycHh9I2NvbW1lbnQtbGlzdCAuYy1hdXRob3J7Zm9udC1zaXplOjEzcHh9I2NvbW1lbnQtbGlzdCAuYy1hdXRob3IuYWRtaW57YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9I2NvbW1lbnQtbGlzdCAuYy1wLW1ke21hcmdpbi10b3A6OHB4O2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjE4cHg7Y29sb3I6IzY2Nn0jY29tbWVudC1saXN0IC5jLXNlY3Rpb257bWF4LXdpZHRoOjgzMHB4fSNjb21tZW50LWxpc3QgLmMtY2hlY2ssI2NvbW1lbnQtbGlzdCAuYy1kZWx7Y29sb3I6I2U2NDM0Nn0jY29tbWVudC1saXN0IC5jLWNoZWNrIC5mYSwjY29tbWVudC1saXN0IC5jLWRlbCAuZmF7bWFyZ2luLXJpZ2h0OjZweH0jY29tbWVudC1saXN0IC5jLWNoZWNrOmhvdmVyLCNjb21tZW50LWxpc3QgLmMtZGVsOmhvdmVye2NvbG9yOiNhYTM5M2N9I2NvbW1lbnQtbGlzdCAuYy1yZXBseSwjY29tbWVudC1saXN0IC5jLWNoZWNrLCNjb21tZW50LWxpc3QgLmMtZGVse2ZvbnQtc2l6ZToxMnB4fSNjb21tZW50LWZvcm17cGFkZGluZy10b3A6MTJweDtkaXNwbGF5Om5vbmU7bWFyZ2luLWxlZnQ6NzJweH0jY29tbWVudC1mb3JtIC5idG57bWFyZ2luLXJpZ2h0OjI0cHh9I2NvbW1lbnQtY29udGVudHt3aWR0aDo1MDBweDtoZWlnaHQ6ODBweDttYXJnaW4tcmlnaHQ6MjRweH0jZmlsZXMtbGlzdCBsaS5maWxle21hcmdpbi1ib3R0b206OHB4O3BhZGRpbmctYm90dG9tOjhweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jZmlsZXMtbGlzdCBsaS5maWxlPip7bWFyZ2luLXJpZ2h0OjE2cHh9I2ZpbGVzLWxpc3QgbGkuZmlsZTpob3ZlciAuZGVse29wYWNpdHk6MSAhaW1wb3J0YW50fSNmaWxlcy1saXN0IC51cGxvYWQtdGltZXtjb2xvcjojOTk5O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWZ9I2ZpbGVzLWxpc3QgLmRlbHtjb2xvcjojZTY0MzQ2fSNmaWxlcy1saXN0IC5maWxlLXByb2dyZXNze3BhZGRpbmc6MCAxMnB4O2JhY2tncm91bmQ6cmdiYSgwLDE1MCwyMjMsMC4yKTtjb2xvcjojNjY2O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWY7Ym94LXNpemluZzpib3JkZXItYm94O2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0jZmlsZXMtbGlzdCAuZmlsZS1wcm9ncmVzcy5lcnJ7YmFja2dyb3VuZDpyZ2JhKDI1NSw2OCw3MSwwLjIpO2NvbG9yOiNhYTM5M2N9I2ZpbGVzLWxpc3QgLnNpemV7d2lkdGg6NGVtO2Rpc3BsYXk6aW5saW5lLWJsb2NrfSNwbHVnaW4tbGlzdCBsaXttYXJnaW4tYm90dG9tOjE2cHg7cGFkZGluZy1ib3R0b206MTZweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jcGx1Z2luLWxpc3QgbGkgLmRlc2N7bWFyZ2luLWJvdHRvbTowO3dpZHRoOjk5JTtjb2xvcjojOTk5fSNwbHVnaW4tbGlzdCBsaSBhLmxibHtwYWRkaW5nOjAgOHB4O21hcmdpbi1sZWZ0OjE2cHh9I3BsdWdpbi1saXN0IGxpIC52ZXJzaW9ue2NvbG9yOiM1MDc2NTA7bWFyZ2luLWxlZnQ6MTZweH0jcGx1Z2luLWxpc3QgbGkgLm5hbWV7Zm9udC1zaXplOjE2cHh9I3BsdWdpbi1saXN0IGxpIC5hY3RpdmV7d2lkdGg6MTJweDtoZWlnaHQ6MTJweDttYXJnaW4tcmlnaHQ6MTZweDtwYWRkaW5nOjA7bWFyZ2luLXRvcDoxMHB4fSNwbHVnaW4tbGlzdCBsaSAuc2V0dGluZ3ttYXJnaW4tbGVmdDoxNnB4fSNwbHVnaW4tc2V0dGluZy1mb3JtIHAuaXRlbXtjbGVhcjpib3RofSNwbHVnaW4tc2V0dGluZy1mb3JtIGxhYmVse2Zsb2F0OmxlZnQ7bWluLXdpZHRoOjZlbTt0ZXh0LWFsaWduOnJpZ2h0O21hcmdpbi1yaWdodDoyZW19I3BsdWdpbi1zZXR0aW5nLWZvcm0gLnRpdGxle3BhZGRpbmctdG9wOjA7bWFyZ2luLWJvdHRvbToxOHB4fSNwbHVnaW4tc2V0dGluZy1mb3JtIGlucHV0LmlwdHt3aWR0aDo2MDBweH0jZGFzaGJvYXJkIC5ncmlkLTEtNXttYXJnaW4tcmlnaHQ6MiV9I2Rhc2hib2FyZCAucXVpY2stbGluayBsaXtsaXN0LXN0eWxlOmluc2lkZSBkaXNjO21hcmdpbi1ib3R0b206NnB4O3BhZGRpbmctYm90dG9tOjZweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jZGFzaGJvYXJkIC5zdGF0cyAubGJse3BhZGRpbmc6MXB4IDVweDttYXJnaW46MCAzcHh9I2Rhc2hib2FyZCAuYWN0aXZpdHkgLm1zZ3twYWRkaW5nOjhweCAxMnB4O21hcmdpbi1ib3R0b206OHB4O3BhZGRpbmctYm90dG9tOjhweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZDtsaW5lLWhlaWdodDoyNHB4O2ZvbnQtc2l6ZToxMnB4fSNkYXNoYm9hcmQgLmFjdGl2aXR5IC5tc2cgLnRpbWV7Zm9udC1mYW1pbHk6VmVyZGFuYSxUYWhvbWEsJ+W+rui9r+mbhem7kScsJ+Wui+S9kycsc2Fucy1zZXJpZn0jZGFzaGJvYXJkIC5hY3Rpdml0eSAubXNnIC5kYXRhe2NvbG9yOiM2NjY7bWFyZ2luLWxlZnQ6MS4yZW19I2Rhc2hib2FyZCAuYWN0aXZpdHkgLm1zZyAuZGF0YSBwe21hcmdpbi1ib3R0b206MDtsaW5lLWhlaWdodDoyNHB4fSNkYXNoYm9hcmQgLmFjdGl2aXR5IC5tc2cgLnJlYWR7dG9wOjA7cmlnaHQ6MTJweDtvcGFjaXR5OjB9I2Rhc2hib2FyZCAuYWN0aXZpdHkgLm1zZyAucmVhZDpob3Zlcntjb2xvcjojZTY0MzQ2fSNkYXNoYm9hcmQgLmFjdGl2aXR5IC5tc2c6aG92ZXJ7YmFja2dyb3VuZDpyZ2JhKDAsMTUwLDIyMywwLjA2KX0jZGFzaGJvYXJkIC5hY3Rpdml0eSAubXNnOmhvdmVyIC5yZWFke29wYWNpdHk6MX1QSwcISUNrj9cyAADXMgAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAc3RhdGljXGNzc1xjbWQuY3NzYm9keSxkaXYsZGwsZHQsZGQsdWwsb2wsbGksaDEsaDIsaDMsaDQsaDUsaDYscHJlLGNvZGUsZm9ybSxmaWVsZHNldCxsZWdlbmQsaW5wdXQsdGV4dGFyZWEscCxibG9ja3F1b3RlLHRoLHRke21hcmdpbjowO3BhZGRpbmc6MH1oZWFkZXIsZm9vdGVyLHNlY3Rpb24sYXJ0aWNsZSxhc2lkZSxuYXYsaGdyb3VwLGFkZHJlc3MsZmlndXJlLGZpZ2NhcHRpb24sbWVudSxkZXRhaWxze2Rpc3BsYXk6YmxvY2t9YXVkaW8sY2FudmFzLHZpZGVve2Rpc3BsYXk6aW5saW5lLWJsb2NrfXRhYmxle2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowfWZpZWxkc2V0LGltZ3tib3JkZXI6MH1hZGRyZXNzLGNhcHRpb24sY2l0ZSxjb2RlLGRmbixlbSx0aCx2YXJ7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsfW9sLHVse2xpc3Qtc3R5bGU6bm9uZX1jYXB0aW9uLHRoe3RleHQtYWxpZ246bGVmdH1oMSxoMixoMyxoNCxoNSxoNntmb250LXNpemU6MTAwJTtmb250LXdlaWdodDpub3JtYWx9cTpiZWZvcmUscTphZnRlcntjb250ZW50OicnfWFiYnIsYWNyb255bXtib3JkZXI6MDtmb250LXZhcmlhbnQ6bm9ybWFsfXN1cHt2ZXJ0aWNhbC1hbGlnbjp0ZXh0LXRvcH1zdWJ7dmVydGljYWwtYWxpZ246dGV4dC1ib3R0b219aW5wdXQsdGV4dGFyZWEsc2VsZWN0e2ZvbnQtZmFtaWx5OmluaGVyaXQ7Zm9udC1zaXplOmluaGVyaXQ7Zm9udC13ZWlnaHQ6aW5oZXJpdH1sZWdlbmR7Y29sb3I6IzAwMH1odG1sLGJvZHl7Zm9udC1mYW1pbHk6VWJ1bnR1LENvbnNvbGFzLCJNaWNyb3NvZnQgWWFIZWkiLFZlcmRhbmEsVGFob21hLEFyaWFsLHNhbnMtc2VyaWY7Zm9udC1zaXplOjE0cHg7bGluZS1oZWlnaHQ6MzBweDtjb2xvcjojMzMzO2JhY2tncm91bmQtY29sb3I6I2ZiZmJmYn1he3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOiMwMDc5YmN9YTpob3Zlcntjb2xvcjojMDA1YjlifXB7bWFyZ2luLWJvdHRvbToxOHB4fWgxLGgyLGgzLGg0LGg1LGg2e3BhZGRpbmc6MTJweCAwfWgxe2ZvbnQtc2l6ZToyOHB4fWgye2ZvbnQtc2l6ZToyNHB4fWgze2ZvbnQtc2l6ZToyMXB4fWg0e2ZvbnQtc2l6ZToxOXB4fWg1e2ZvbnQtc2l6ZToxNnB4fWg2e2ZvbnQtc2l6ZToxNHB4fS50ZXh0LWxlZnR7dGV4dC1hbGlnbjpsZWZ0fS50ZXh0LXJpZ2h0e3RleHQtYWxpZ246cmlnaHR9LnRleHQtY2VudGVye3RleHQtYWxpZ246Y2VudGVyfS5sZWZ0e2Zsb2F0OmxlZnR9LnJpZ2h0e2Zsb2F0OnJpZ2h0fS5hYnNvbHV0ZXtwb3NpdGlvbjphYnNvbHV0ZX0ucmVsYXRpdmV7cG9zaXRpb246cmVsYXRpdmV9LmNsZWFyOmFmdGVye3Zpc2liaWxpdHk6aGlkZGVuO2Rpc3BsYXk6YmxvY2s7Zm9udC1zaXplOjA7Y29udGVudDoiICI7Y2xlYXI6Ym90aDtoZWlnaHQ6MH0udmVydGljYWwtbWlkZGxle3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0uaW5saW5le2Rpc3BsYXk6aW5saW5lfS5pbmxpbmUtYmxvY2t7ZGlzcGxheTppbmxpbmUtYmxvY2t9LmJsb2Nre2Rpc3BsYXk6YmxvY2t9LmZhZGUtb3V0e29wYWNpdHk6MH0uaGlkZXtkaXNwbGF5Om5vbmUgIWltcG9ydGFudH0uY29udGFpbmVye21heC13aWR0aDoxMjAwcHg7bWFyZ2luOmF1dG99LmNvbnRhaW5lcjk2MHttYXgtd2lkdGg6OTYwcHg7bWFyZ2luOmF1dG99LmdyaWQtMS0ye3dpZHRoOjUwJX0uZ3JpZC0xLTN7d2lkdGg6MzMuMzMzMyV9LmdyaWQtMS00e3dpZHRoOjI1JX0uZ3JpZC0xLTV7d2lkdGg6MjAlfS5ncmlkLTEtNnt3aWR0aDoxNi42NjY2JX0uZ3JpZC0yLTN7d2lkdGg6NjYuNjY2NiV9LmdyaWQtMy00e3dpZHRoOjc1JX0uZ3JpZC0zLTV7d2lkdGg6NjAlfS5ncmlkLTQtNXt3aWR0aDo4MCV9LmdyaWQtNS02e3dpZHRoOjgzLjMzMzMlfWlucHV0LHRleHRhcmVhLHNlbGVjdCxidXR0b257Zm9udC1mYW1pbHk6VWJ1bnR1LENvbnNvbGFzLCJNaWNyb3NvZnQgWWFIZWkiLFZlcmRhbmEsVGFob21hLEFyaWFsLHNhbnMtc2VyaWZ9LmZvcm0gbGVnZW5ke2ZvbnQtc2l6ZToxOHB4O21hcmdpbi1ib3R0b206MTRweH0uZm9ybSBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW4tcmlnaHQ6MTJweH0uZm9ybSAuaXB0e3BhZGRpbmc6OHB4IDEycHg7Ym9yZGVyOjFweCBzb2xpZCAjOTk5O2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7bWluLXdpZHRoOjE4MHB4fS5mb3JtIC5pcHQ6Zm9jdXN7Ym9yZGVyLWNvbG9yOiMwMDc5YmN9LmZvcm0gLmNoa3tkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW46MnB4IDZweCAwIDA7bGluZS1oZWlnaHQ6bm9ybWFsfS5mb3JtIC5maWVsZHttYXJnaW4tYm90dG9tOjI0cHh9LmZvcm0gLmludmFsaWR7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLnRpcHtmb250LXNpemU6MTNweDtjb2xvcjojOTk5O21hcmdpbi1sZWZ0OjEycHh9LmZvcm0tdmVydGljYWwgbGFiZWx7ZGlzcGxheTpibG9jazttYXJnaW4tYm90dG9tOjhweH0uZm9ybS12ZXJ0aWNhbCAuaXB0e3dpZHRoOjEwMCU7Ym94LXNpemluZzpib3JkZXItYm94fS5mb3JtLXZlcnRpY2FsIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5mb3JtLWFsaWduIGxhYmVse2Rpc3BsYXk6aW5saW5lLWJsb2NrO21pbi13aWR0aDo2MHB4O3RleHQtYWxpZ246cmlnaHR9LmZvcm0tYWxpZ24gLmludmFsaWR7bWFyZ2luLXJpZ2h0OjA7bWFyZ2luLXRvcDo2cHh9LmJ0bnttaW4td2lkdGg6MTIwcHg7aGVpZ2h0OjM2cHg7YmFja2dyb3VuZC1jb2xvcjojY2NjO2NvbG9yOiMzMzM7Ym9yZGVyLXJhZGl1czoycHg7LW1vei1ib3JkZXItcmFkaXVzOjJweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MnB4O291dGxpbmU6bm9uZTtib3JkZXI6bm9uZTttYXJnaW46MH0uYnRuOmhvdmVye2JhY2tncm91bmQtY29sb3I6Izk5OTtjdXJzb3I6cG9pbnRlcn1hLmJ0bntsaW5lLWhlaWdodDozNnB4O2NvbG9yOiNmZmZ9LmJ0bi1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9LmJ0bi1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhfS5idG4tYmx1ZXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmM7Y29sb3I6I2ZiZmJmYn0uYnRuLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjlifS5idG4tZ3JlZW57YmFja2dyb3VuZC1jb2xvcjojN2FiMjc3O2NvbG9yOiNmYmZiZmJ9LmJ0bi1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjJ9LmxibHtwYWRkaW5nOjRweCAxMnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ubGJsLXJlZHtiYWNrZ3JvdW5kLWNvbG9yOiNlNjQzNDY7Y29sb3I6I2ZiZmJmYn1hLmxibHtsaW5lLWhlaWdodDoyNnB4fWEubGJsLXJlZDpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiNjNzM4M2E7Y29sb3I6I2ZiZmJmYn0ubGJsLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9YS5sYmwtYmx1ZTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDViOWI7Y29sb3I6I2ZiZmJmYn0ubGJsLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifWEubGJsLWdyZWVuOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzY0OTQ2Mjtjb2xvcjojZmJmYmZifS5wYWdlciAuaXRlbXtwYWRkaW5nOjJweCA4cHg7bWFyZ2luOjAgNnB4O2NvbG9yOiMzMzM7ZGlzcGxheTppbmxpbmUtYmxvY2s7bGluZS1oZWlnaHQ6MjBweH0ucGFnZXIgLml0ZW0gYXtjb2xvcjojMzMzfS5wYWdlciAuaXRlbTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmM7Ym9yZGVyLXJhZGl1czoycHg7LW1vei1ib3JkZXItcmFkaXVzOjJweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MnB4fS5wYWdlciAuaXRlbTpob3ZlciBhe2NvbG9yOiNmZmZ9LnBhZ2VyIC5jdXJyZW50e2JhY2tncm91bmQtY29sb3I6IzY2Njtjb2xvcjojZmJmYmZiO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLmN1cnJlbnQgYXtjb2xvcjojZmJmYmZifS5wYWdlciAuY3VycmVudDpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmN9Lm1hcmtkb3duIGgxLC5tYXJrZG93biBoMiwubWFya2Rvd24gaDMsLm1hcmtkb3duIGg0LC5tYXJrZG93biBoNSwubWFya2Rvd24gaDZ7cGFkZGluZzoxOHB4IDAgOXB4IDA7Zm9udC13ZWlnaHQ6Ym9sZH0ubWFya2Rvd24gaDF7Zm9udC1zaXplOjI0cHh9Lm1hcmtkb3duIGgye2ZvbnQtc2l6ZToyMXB4fS5tYXJrZG93biBoMSwubWFya2Rvd24gaDJ7bWFyZ2luLWJvdHRvbToxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7Ym9yZGVyLWJvdHRvbToxcHggZGFzaGVkICNkZGR9Lm1hcmtkb3duIGgze2ZvbnQtc2l6ZToxOXB4fS5tYXJrZG93biBoNHtmb250LXNpemU6MThweH0ubWFya2Rvd24gaDV7Zm9udC1zaXplOjE2cHh9Lm1hcmtkb3duIGg2e2ZvbnQtc2l6ZToxNHB4fS5tYXJrZG93biBwe21hcmdpbi1ib3R0b206MTBweH0ubWFya2Rvd24gdWx7bGlzdC1zdHlsZTpkaXNjIGluc2lkZX0ubWFya2Rvd24gb2x7bGlzdC1zdHlsZTpkZWNpbWFsIGluc2lkZX0ubWFya2Rvd24gY29kZXtmb250LWZhbWlseTpDb25zb2xhcywiQ291cmllciBOZXciLEFyaWFsfS5tYXJrZG93biBwIGNvZGV7Y29sb3I6I2M3MzgzYX0ubWFya2Rvd24gYmxvY2txdW90ZXtwYWRkaW5nOjhweCAxOHB4O2JvcmRlci1sZWZ0OjRweCBzb2xpZCAjY2NjO2JhY2tncm91bmQtY29sb3I6I2ZiZmJmYn0ubWFya2Rvd24gYmxvY2txdW90ZSBwe21hcmdpbi1ib3R0b206MH0ubWFya2Rvd24gcHJlIGNvZGV7Zm9udC1zaXplOjEycHg7bGluZS1oZWlnaHQ6MThweCAhaW1wb3J0YW50O3BhZGRpbmc6OHB4IDE4cHg7ZGlzcGxheTpibG9jazttYXJnaW46MTJweCAwIDE4cHggMH0ubWFya2Rvd24gb2wsLm1hcmtkb3duIHVse21hcmdpbjoxMnB4IDI0cHh9Lm1hcmtkb3duIHAgaW1ne21heC13aWR0aDo5OSU7aGVpZ2h0OmF1dG87bWFyZ2luOjAgYXV0bztkaXNwbGF5OmJsb2NrfS5tYXJrZG93biB0YWJsZXttYXJnaW46MTJweCAwO3dpZHRoOjk4JX0ubWFya2Rvd24gdGFibGUgdGgsLm1hcmtkb3duIHRhYmxlIHRke2JvcmRlcjoxcHggc29saWQgI2NjYztwYWRkaW5nOjRweCAxMnB4fS5tYXJrZG93biB0YWJsZSB0aGVhZHtiYWNrZ3JvdW5kOiNmNmY2ZjZ9Ojotd2Via2l0LXNjcm9sbGJhcnt3aWR0aDo4cHg7bWFyZ2luLXJpZ2h0OjJweH06Oi13ZWJraXQtc2Nyb2xsYmFyLXRyYWNrLXBpZWNle2JhY2tncm91bmQtY29sb3I6I2Y1ZjVmNTtib3JkZXItbGVmdDoxcHggc29saWQgI2QyZDJkMn06Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1ie2JhY2tncm91bmQ6IzlmYTA5Yzt3aWR0aDo4cHh9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlcntiYWNrZ3JvdW5kOiNiN2I4YWR9LmNtZHttYXJnaW46MjRweCA0OHB4fS5jbWQtaGVhZGVye21hcmdpbi1ib3R0b206MTJweDtwYWRkaW5nLWJvdHRvbToxMnB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfSNiYWNrdXAtYnRuLCN0aGVtZS1jYWNoZS1idG57bWFyZ2luOjEwcHggMCAwIDMwcHg7bWluLXdpZHRoOjA7cGFkZGluZzowIDJlbX0jdGhlbWUtY2FjaGUtYnRue2JhY2tncm91bmQtY29sb3I6I2U2NDM0Njtjb2xvcjojZmJmYmZifSN0aGVtZS1jYWNoZS1idG46aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhfSN0aGVtZS1jYWNoZS1idG4udHJ1ZXtiYWNrZ3JvdW5kLWNvbG9yOiM3YWIyNzc7Y29sb3I6I2ZiZmJmYn0jdGhlbWUtY2FjaGUtYnRuLnRydWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNjQ5NDYyfS5jbWQtbGlzdCBsaXttYXJnaW4tYm90dG9tOjEycHg7cGFkZGluZy1ib3R0b206MTJweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jYmFja3VwLWxpc3QgbGl7bGlzdC1zdHlsZTpkaXNjIGluc2lkZTtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNiYWNrdXAtbGlzdCBsaT5zcGFuLCNiYWNrdXAtbGlzdCBsaT5he21hcmdpbi1yaWdodDoxNnB4fSNiYWNrdXAtbGlzdCBsaSAuZGVse2NvbG9yOiNlNjQzNDY7b3BhY2l0eTowfSNiYWNrdXAtbGlzdCBsaSAubGlua3ttYXJnaW4tbGVmdDoxMnB4fSNiYWNrdXAtbGlzdCBsaTpob3ZlciAuZGVse29wYWNpdHk6MX0jbWVzc2FnZS1saXN0IC5tZXNzYWdle3BhZGRpbmc6OHB4IDEycHg7bWFyZ2luLWJvdHRvbTo4cHg7cGFkZGluZy1ib3R0b206OHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkO2xpbmUtaGVpZ2h0OjI0cHg7Zm9udC1zaXplOjEycHh9I21lc3NhZ2UtbGlzdCAubWVzc2FnZSAudGltZXtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNtZXNzYWdlLWxpc3QgLm1lc3NhZ2UgLmRhdGF7Y29sb3I6IzY2NjttYXJnaW4tbGVmdDoxLjJlbX0jbWVzc2FnZS1saXN0IC5tZXNzYWdlIC5kYXRhIHB7bWFyZ2luLWJvdHRvbTowO2xpbmUtaGVpZ2h0OjI0cHh9I21lc3NhZ2UtbGlzdCAubWVzc2FnZSAucmVhZHt0b3A6MDtyaWdodDoxMnB4O29wYWNpdHk6MH0jbWVzc2FnZS1saXN0IC5tZXNzYWdlIC5yZWFkOmhvdmVye2NvbG9yOiNlNjQzNDZ9I21lc3NhZ2UtbGlzdCAubWVzc2FnZTpob3ZlciAucmVhZHtvcGFjaXR5OjF9I2xvZy1saXN0IC5sb2d7Zm9udC1zaXplOjEycHh9I2xvZy1saXN0IC5uYW1le21hcmdpbi1yaWdodDoxLjVlbTtmb250LXdlaWdodDpib2xkfSNsb2ctbGlzdCAudGltZSwjbG9nLWxpc3QgLm5hbWV7Zm9udC1mYW1pbHk6VmVyZGFuYSxUYWhvbWEsJ+W+rui9r+mbhem7kScsJ+Wui+S9kycsc2Fucy1zZXJpZn0jbG9nLWxpc3QgLnRleHR7bGluZS1oZWlnaHQ6MjBweDtmb250LWZhbWlseTpDb25zb2xhcywiQ291cmllciBOZXciLEFyaWFsO2NvbG9yOiM2NjY7cGFkZGluZzo4cHggMTJweDtiYWNrZ3JvdW5kOiNmM2YzZjN9I2xvZy1saXN0IC5yZW1vdmV7dG9wOjA7cmlnaHQ6MTJweDtjb2xvcjojZTY0MzQ2fSN0aGVtZS1saXN0IHNwYW57bWFyZ2luLWxlZnQ6MTJweH0jdGhlbWUtbGlzdCBzcGFuLmZpbGV7Y29sb3I6IzAwNzliY30jdGhlbWUtbGlzdCBzcGFuLmVycm9yLWZpbGV7Y29sb3I6I2M3MzgzYX0jdGhlbWUtbGlzdCBoNXtjdXJzb3I6cG9pbnRlcn0jcmVhZGVyLWxpc3QgbGk+KnttYXJnaW4tcmlnaHQ6MThweH0jcmVhZGVyLWxpc3QgLmVtYWlse2NvbG9yOiM5OTl9I3JlYWRlci1saXN0IC5jb21tZW50c3tmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxMnB4O3BhZGRpbmc6MnB4IDZweH1QSwcIZG84qfQcAAD0HAAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAc3RhdGljXGNzc1xjb2RlbWlycm9yLmNzcy8qIEJBU0lDUyAqLwoKLkNvZGVNaXJyb3IgewogICAgLyogU2V0IGhlaWdodCwgd2lkdGgsIGJvcmRlcnMsIGFuZCBnbG9iYWwgZm9udCBwcm9wZXJ0aWVzIGhlcmUgKi8KICAgIGZvbnQtZmFtaWx5OiBDb25zb2xhcywgIk1pY3Jvc29mdCBZYUhlaSIsICJDb3VyaWVyIE5ldyIsIEFyaWFsOwogICAgaGVpZ2h0OiA2NjBweDsKICAgIGZvbnQtc2l6ZTogMTNweDsKICAgIGJvcmRlcjoxcHggc29saWQgIzk5OTsKfQoKLkNvZGVNaXJyb3Itc2Nyb2xsIHsKICAgIC8qIFNldCBzY3JvbGxpbmcgYmVoYXZpb3VyIGhlcmUgKi8KICAgIG92ZXJmbG93OiBhdXRvOwp9CgovKiBQQURESU5HICovCgouQ29kZU1pcnJvci1saW5lcyB7CiAgICBwYWRkaW5nOiA0cHggMDsgLyogVmVydGljYWwgcGFkZGluZyBhcm91bmQgY29udGVudCAqLwp9CgouQ29kZU1pcnJvciBwcmUgewogICAgcGFkZGluZzogMCA0cHg7IC8qIEhvcml6b250YWwgcGFkZGluZyBvZiBjb250ZW50ICovCn0KCi5Db2RlTWlycm9yLXNjcm9sbGJhci1maWxsZXIsIC5Db2RlTWlycm9yLWd1dHRlci1maWxsZXIgewogICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IC8qIFRoZSBsaXR0bGUgc3F1YXJlIGJldHdlZW4gSCBhbmQgViBzY3JvbGxiYXJzICovCn0KCi8qIEdVVFRFUiAqLwoKLkNvZGVNaXJyb3ItZ3V0dGVycyB7CiAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZGRkOwogICAgYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjdmNzsKICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5Db2RlTWlycm9yLWxpbmVudW1iZXJzIHsKfQoKLkNvZGVNaXJyb3ItbGluZW51bWJlciB7CiAgICBwYWRkaW5nOiAwIDNweCAwIDVweDsKICAgIG1pbi13aWR0aDogMjBweDsKICAgIHRleHQtYWxpZ246IHJpZ2h0OwogICAgY29sb3I6ICM1NTU7CiAgICBsaW5lLWhlaWdodDogMjBweDsKfQoKLyogQ1VSU09SICovCgouQ29kZU1pcnJvciBkaXYuQ29kZU1pcnJvci1jdXJzb3IgewogICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCBibGFjazsKICAgIHotaW5kZXg6IDM7Cn0KCi8qIFNob3duIHdoZW4gbW92aW5nIGluIGJpLWRpcmVjdGlvbmFsIHRleHQgKi8KLkNvZGVNaXJyb3IgZGl2LkNvZGVNaXJyb3Itc2Vjb25kYXJ5Y3Vyc29yIHsKICAgIGJvcmRlci1sZWZ0OiAxcHggc29saWQgc2lsdmVyOwp9CgouQ29kZU1pcnJvci5jbS1rZXltYXAtZmF0LWN1cnNvciBkaXYuQ29kZU1pcnJvci1jdXJzb3IgewogICAgd2lkdGg6IGF1dG87CiAgICBib3JkZXI6IDA7CiAgICBiYWNrZ3JvdW5kOiAjN2U3OwogICAgei1pbmRleDogMTsKfQoKLyogQ2FuIHN0eWxlIGN1cnNvciBkaWZmZXJlbnQgaW4gb3ZlcndyaXRlIChub24taW5zZXJ0KSBtb2RlICovCi5Db2RlTWlycm9yIGRpdi5Db2RlTWlycm9yLWN1cnNvci5Db2RlTWlycm9yLW92ZXJ3cml0ZSB7Cn0KCi5jbS10YWIgewogICAgZGlzcGxheTogaW5saW5lLWJsb2NrOwp9CgovKiBERUZBVUxUIFRIRU1FICovCgouY20tcy1kZWZhdWx0IC5jbS1rZXl3b3JkIHsKICAgIGNvbG9yOiAjNzA4Owp9CgouY20tcy1kZWZhdWx0IC5jbS1hdG9tIHsKICAgIGNvbG9yOiAjMjE5Owp9CgouY20tcy1kZWZhdWx0IC5jbS1udW1iZXIgewogICAgY29sb3I6ICMxNjQ7Cn0KCi5jbS1zLWRlZmF1bHQgLmNtLWRlZiB7CiAgICBjb2xvcjogIzAwZjsKfQoKLmNtLXMtZGVmYXVsdCAuY20tdmFyaWFibGUgewogICAgY29sb3I6IGJsYWNrOwp9CgouY20tcy1kZWZhdWx0IC5jbS12YXJpYWJsZS0yIHsKICAgIGNvbG9yOiAjMDVhOwp9CgouY20tcy1kZWZhdWx0IC5jbS12YXJpYWJsZS0zIHsKICAgIGNvbG9yOiAjMDg1Owp9CgouY20tcy1kZWZhdWx0IC5jbS1wcm9wZXJ0eSB7CiAgICBjb2xvcjogYmxhY2s7Cn0KCi5jbS1zLWRlZmF1bHQgLmNtLW9wZXJhdG9yIHsKICAgIGNvbG9yOiBibGFjazsKfQoKLmNtLXMtZGVmYXVsdCAuY20tY29tbWVudCB7CiAgICBjb2xvcjogI2E1MDsKfQoKLmNtLXMtZGVmYXVsdCAuY20tc3RyaW5nIHsKICAgIGNvbG9yOiAjYTExOwp9CgouY20tcy1kZWZhdWx0IC5jbS1zdHJpbmctMiB7CiAgICBjb2xvcjogI2Y1MDsKfQoKLmNtLXMtZGVmYXVsdCAuY20tbWV0YSB7CiAgICBjb2xvcjogIzU1NTsKfQoKLmNtLXMtZGVmYXVsdCAuY20tcXVhbGlmaWVyIHsKICAgIGNvbG9yOiAjNTU1Owp9CgouY20tcy1kZWZhdWx0IC5jbS1idWlsdGluIHsKICAgIGNvbG9yOiAjMzBhOwp9CgouY20tcy1kZWZhdWx0IC5jbS1icmFja2V0IHsKICAgIGNvbG9yOiAjOTk3Owp9CgouY20tcy1kZWZhdWx0IC5jbS10YWcgewogICAgY29sb3I6ICMxNzA7Cn0KCi5jbS1zLWRlZmF1bHQgLmNtLWF0dHJpYnV0ZSB7CiAgICBjb2xvcjogIzAwYzsKfQoKLmNtLXMtZGVmYXVsdCAuY20taGVhZGVyIHsKICAgIGNvbG9yOiBibHVlOwp9CgouY20tcy1kZWZhdWx0IC5jbS1xdW90ZSB7CiAgICBjb2xvcjogIzA5MDsKfQoKLmNtLXMtZGVmYXVsdCAuY20taHIgewogICAgY29sb3I6ICM5OTk7Cn0KCi5jbS1zLWRlZmF1bHQgLmNtLWxpbmsgewogICAgY29sb3I6ICMwMGM7Cn0KCi5jbS1uZWdhdGl2ZSB7CiAgICBjb2xvcjogI2Q0NDsKfQoKLmNtLXBvc2l0aXZlIHsKICAgIGNvbG9yOiAjMjkyOwp9CgouY20taGVhZGVyLCAuY20tc3Ryb25nIHsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwp9CgouY20tZW0gewogICAgZm9udC1zdHlsZTogaXRhbGljOwp9CgouY20tbGluayB7CiAgICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsKfQoKLmNtLXMtZGVmYXVsdCAuY20tZXJyb3IgewogICAgY29sb3I6ICNmMDA7Cn0KCi5jbS1pbnZhbGlkY2hhciB7CiAgICBjb2xvcjogI2YwMDsKfQoKZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW1hdGNoaW5nYnJhY2tldCB7CiAgICBjb2xvcjogIzBmMDsKfQoKZGl2LkNvZGVNaXJyb3Igc3Bhbi5Db2RlTWlycm9yLW5vbm1hdGNoaW5nYnJhY2tldCB7CiAgICBjb2xvcjogI2YyMjsKfQoKLkNvZGVNaXJyb3ItYWN0aXZlbGluZS1iYWNrZ3JvdW5kIHsKICAgIGJhY2tncm91bmQ6ICNlOGYyZmY7Cn0KCi8qIFNUT1AgKi8KCi8qIFRoZSByZXN0IG9mIHRoaXMgZmlsZSBjb250YWlucyBzdHlsZXMgcmVsYXRlZCB0byB0aGUgbWVjaGFuaWNzIG9mCiAgIHRoZSBlZGl0b3IuIFlvdSBwcm9iYWJseSBzaG91bGRuJ3QgdG91Y2ggdGhlbS4gKi8KCi5Db2RlTWlycm9yIHsKICAgIGxpbmUtaGVpZ2h0OiAxOwogICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgb3ZlcmZsb3c6IGhpZGRlbjsKICAgIGJhY2tncm91bmQ6IHdoaXRlOwogICAgY29sb3I6IGJsYWNrOwp9CgouQ29kZU1pcnJvci1zY3JvbGwgewogICAgLyogMzBweCBpcyB0aGUgbWFnaWMgbWFyZ2luIHVzZWQgdG8gaGlkZSB0aGUgZWxlbWVudCdzIHJlYWwgc2Nyb2xsYmFycyAqLwogICAgLyogU2VlIG92ZXJmbG93OiBoaWRkZW4gaW4gLkNvZGVNaXJyb3IgKi8KICAgIG1hcmdpbi1ib3R0b206IC0zMHB4OwogICAgbWFyZ2luLXJpZ2h0OiAtMzBweDsKICAgIHBhZGRpbmctYm90dG9tOiAzMHB4OwogICAgcGFkZGluZy1yaWdodDogMzBweDsKICAgIGhlaWdodDogMTAwJTsKICAgIG91dGxpbmU6IG5vbmU7IC8qIFByZXZlbnQgZHJhZ2dpbmcgZnJvbSBoaWdobGlnaHRpbmcgdGhlIGVsZW1lbnQgKi8KICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgIC1tb3otYm94LXNpemluZzogY29udGVudC1ib3g7CiAgICBib3gtc2l6aW5nOiBjb250ZW50LWJveDsKfQoKLkNvZGVNaXJyb3Itc2l6ZXIgewogICAgcG9zaXRpb246IHJlbGF0aXZlOwp9CgovKiBUaGUgZmFrZSwgdmlzaWJsZSBzY3JvbGxiYXJzLiBVc2VkIHRvIGZvcmNlIHJlZHJhdyBkdXJpbmcgc2Nyb2xsaW5nCiAgIGJlZm9yZSBhY3R1YWxsIHNjcm9sbGluZyBoYXBwZW5zLCB0aHVzIHByZXZlbnRpbmcgc2hha2luZyBhbmQKICAgZmxpY2tlcmluZyBhcnRpZmFjdHMuICovCi5Db2RlTWlycm9yLXZzY3JvbGxiYXIsIC5Db2RlTWlycm9yLWhzY3JvbGxiYXIsIC5Db2RlTWlycm9yLXNjcm9sbGJhci1maWxsZXIsIC5Db2RlTWlycm9yLWd1dHRlci1maWxsZXIgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgei1pbmRleDogNjsKICAgIGRpc3BsYXk6IG5vbmU7Cn0KCi5Db2RlTWlycm9yLXZzY3JvbGxiYXIgewogICAgcmlnaHQ6IDA7CiAgICB0b3A6IDA7CiAgICBvdmVyZmxvdy14OiBoaWRkZW47CiAgICBvdmVyZmxvdy15OiBzY3JvbGw7Cn0KCi5Db2RlTWlycm9yLWhzY3JvbGxiYXIgewogICAgYm90dG9tOiAwOwogICAgbGVmdDogMDsKICAgIG92ZXJmbG93LXk6IGhpZGRlbjsKICAgIG92ZXJmbG93LXg6IHNjcm9sbDsKfQoKLkNvZGVNaXJyb3Itc2Nyb2xsYmFyLWZpbGxlciB7CiAgICByaWdodDogMDsKICAgIGJvdHRvbTogMDsKfQoKLkNvZGVNaXJyb3ItZ3V0dGVyLWZpbGxlciB7CiAgICBsZWZ0OiAwOwogICAgYm90dG9tOiAwOwp9CgouQ29kZU1pcnJvci1ndXR0ZXJzIHsKICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICAgIGxlZnQ6IDA7CiAgICB0b3A6IDA7CiAgICBwYWRkaW5nLWJvdHRvbTogMzBweDsKICAgIHotaW5kZXg6IDM7Cn0KCi5Db2RlTWlycm9yLWd1dHRlciB7CiAgICB3aGl0ZS1zcGFjZTogbm9ybWFsOwogICAgaGVpZ2h0OiAxMDAlOwogICAgLW1vei1ib3gtc2l6aW5nOiBjb250ZW50LWJveDsKICAgIGJveC1zaXppbmc6IGNvbnRlbnQtYm94OwogICAgcGFkZGluZy1ib3R0b206IDMwcHg7CiAgICBtYXJnaW4tYm90dG9tOiAtMzJweDsKICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgIC8qIEhhY2sgdG8gbWFrZSBJRTcgYmVoYXZlICovCiAgICAqem9vbTogMTsKICAgICpkaXNwbGF5OiBpbmxpbmU7Cn0KCi5Db2RlTWlycm9yLWd1dHRlci1lbHQgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgY3Vyc29yOiBkZWZhdWx0OwogICAgei1pbmRleDogNDsKfQoKLkNvZGVNaXJyb3ItbGluZXMgewogICAgY3Vyc29yOiB0ZXh0Owp9CgouQ29kZU1pcnJvciBwcmUgewogICAgLyogUmVzZXQgc29tZSBzdHlsZXMgdGhhdCB0aGUgcmVzdCBvZiB0aGUgcGFnZSBtaWdodCBoYXZlIHNldCAqLwogICAgLW1vei1ib3JkZXItcmFkaXVzOiAwOwogICAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAwOwogICAgYm9yZGVyLXJhZGl1czogMDsKICAgIGJvcmRlci13aWR0aDogMDsKICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OwogICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7CiAgICBmb250LXNpemU6IGluaGVyaXQ7CiAgICBtYXJnaW46IDA7CiAgICBsaW5lLWhlaWdodDogMjBweDsKICAgIGNvbG9yOiBpbmhlcml0OwogICAgei1pbmRleDogMjsKICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgIG92ZXJmbG93OiB2aXNpYmxlOwogICAgd29yZC13cmFwOiBicmVhay13b3JkOwogICAgd2hpdGUtc3BhY2U6IHByZS13cmFwOwogICAgd29yZC1icmVhazogYnJlYWstYWxsOwp9CgouQ29kZU1pcnJvci13cmFwIHByZSB7CiAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7CiAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7CiAgICB3b3JkLWJyZWFrOiBub3JtYWw7Cn0KCi5Db2RlTWlycm9yLWNvZGUgcHJlIHsKICAgIHdpZHRoOiAtd2Via2l0LWZpdC1jb250ZW50OwogICAgd2lkdGg6IC1tb3otZml0LWNvbnRlbnQ7CiAgICB3aWR0aDogZml0LWNvbnRlbnQ7Cn0KCi5Db2RlTWlycm9yLXdyYXAgLkNvZGVNaXJyb3ItY29kZSBwcmUgewogICAgYm9yZGVyLXJpZ2h0OiBub25lOwogICAgd2lkdGg6IGF1dG87Cn0KCi5Db2RlTWlycm9yLWxpbmViYWNrZ3JvdW5kIHsKICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICAgIGxlZnQ6IDA7CiAgICByaWdodDogMDsKICAgIHRvcDogMDsKICAgIGJvdHRvbTogMDsKICAgIHotaW5kZXg6IDA7Cn0KCi5Db2RlTWlycm9yLWxpbmV3aWRnZXQgewogICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgei1pbmRleDogMjsKICAgIG92ZXJmbG93OiBhdXRvOwp9CgouQ29kZU1pcnJvci13aWRnZXQgewp9CgouQ29kZU1pcnJvci13cmFwIC5Db2RlTWlycm9yLXNjcm9sbCB7CiAgICBvdmVyZmxvdy14OiBoaWRkZW47Cn0KCi5Db2RlTWlycm9yLW1lYXN1cmUgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgd2lkdGg6IDEwMCU7CiAgICBoZWlnaHQ6IDA7CiAgICBvdmVyZmxvdzogaGlkZGVuOwogICAgdmlzaWJpbGl0eTogaGlkZGVuOwp9CgouQ29kZU1pcnJvci1tZWFzdXJlIHByZSB7CiAgICBwb3NpdGlvbjogc3RhdGljOwp9CgouQ29kZU1pcnJvciBkaXYuQ29kZU1pcnJvci1jdXJzb3IgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgdmlzaWJpbGl0eTogaGlkZGVuOwogICAgYm9yZGVyLXJpZ2h0OiBub25lOwogICAgd2lkdGg6IDA7Cn0KCi5Db2RlTWlycm9yLWZvY3VzZWQgZGl2LkNvZGVNaXJyb3ItY3Vyc29yIHsKICAgIHZpc2liaWxpdHk6IHZpc2libGU7Cn0KCi5Db2RlTWlycm9yLXNlbGVjdGVkIHsKICAgIGJhY2tncm91bmQ6ICNkOWQ5ZDk7Cn0KCi5Db2RlTWlycm9yLWZvY3VzZWQgLkNvZGVNaXJyb3Itc2VsZWN0ZWQgewogICAgYmFja2dyb3VuZDogI2Q3ZDRmMDsKfQoKLmNtLXNlYXJjaGluZyB7CiAgICBiYWNrZ3JvdW5kOiAjZmZhOwogICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMCwgLjQpOwp9CgovKiBJRTcgaGFjayB0byBwcmV2ZW50IGl0IGZyb20gcmV0dXJuaW5nIGZ1bm55IG9mZnNldFRvcHMgb24gdGhlIHNwYW5zICovCi5Db2RlTWlycm9yIHNwYW4gewogICAgKnZlcnRpY2FsLWFsaWduOiB0ZXh0LWJvdHRvbTsKfQoKQG1lZGlhIHByaW50IHsKICAgIC8qIEhpZGUgdGhlIGN1cnNvciB3aGVuIHByaW50aW5nICovCiAgICAuQ29kZU1pcnJvciBkaXYuQ29kZU1pcnJvci1jdXJzb3IgewogICAgICAgIHZpc2liaWxpdHk6IGhpZGRlbjsKICAgIH0KfQoKLmNtLXMtYmFzZTE2LWRhcmsuQ29kZU1pcnJvciB7CiAgICBiYWNrZ3JvdW5kOiAjMTUxNTE1OwogICAgY29sb3I6ICNlMGUwZTA7Cn0KCi5jbS1zLWJhc2UxNi1kYXJrIGRpdi5Db2RlTWlycm9yLXNlbGVjdGVkIHsKICAgIGJhY2tncm91bmQ6ICMyMDIwMjAgIWltcG9ydGFudDsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgLkNvZGVNaXJyb3ItZ3V0dGVycyB7CiAgICBiYWNrZ3JvdW5kOiAjMTUxNTE1OwogICAgYm9yZGVyLXJpZ2h0OiAwcHg7Cn0KCi5jbS1zLWJhc2UxNi1kYXJrIC5Db2RlTWlycm9yLWxpbmVudW1iZXIgewogICAgY29sb3I6ICM1NTU7Cn0KCi5jbS1zLWJhc2UxNi1kYXJrIC5Db2RlTWlycm9yLWN1cnNvciB7CiAgICBib3JkZXItbGVmdDogMXB4IHNvbGlkICNiMGIwYjAgIWltcG9ydGFudDsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS1jb21tZW50IHsKICAgIGNvbG9yOiAjOGY1NTM2Owp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLWF0b20gewogICAgY29sb3I6ICNhYTc1OWY7Cn0KCi5jbS1zLWJhc2UxNi1kYXJrIHNwYW4uY20tbnVtYmVyIHsKICAgIGNvbG9yOiAjYWE3NTlmOwp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLXByb3BlcnR5LCAuY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLWF0dHJpYnV0ZSB7CiAgICBjb2xvcjogIzkwYTk1OTsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS1rZXl3b3JkIHsKICAgIGNvbG9yOiAjYWM0MTQyOwp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLXN0cmluZyB7CiAgICBjb2xvcjogI2Y0YmY3NTsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS12YXJpYWJsZSB7CiAgICBjb2xvcjogIzkwYTk1OTsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS12YXJpYWJsZS0yIHsKICAgIGNvbG9yOiAjNmE5ZmI1Owp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLWRlZiB7CiAgICBjb2xvcjogI2QyODQ0NTsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS1icmFja2V0IHsKICAgIGNvbG9yOiAjZTBlMGUwOwp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLXRhZyB7CiAgICBjb2xvcjogI2FjNDE0MjsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgc3Bhbi5jbS1saW5rIHsKICAgIGNvbG9yOiAjYWE3NTlmOwp9CgouY20tcy1iYXNlMTYtZGFyayBzcGFuLmNtLWVycm9yIHsKICAgIGJhY2tncm91bmQ6ICNhYzQxNDI7CiAgICBjb2xvcjogI2IwYjBiMDsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgLkNvZGVNaXJyb3ItYWN0aXZlbGluZS1iYWNrZ3JvdW5kIHsKICAgIGJhY2tncm91bmQ6ICMyRjJGMkYgIWltcG9ydGFudDsKfQoKLmNtLXMtYmFzZTE2LWRhcmsgLkNvZGVNaXJyb3ItbWF0Y2hpbmdicmFja2V0IHsKICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOwogICAgY29sb3I6IHdoaXRlICFpbXBvcnRhbnQ7Cn0KUEsHCCMDNYJOIAAATiAAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFQAAAHN0YXRpY1xjc3NcY29tbW9uLmNzc2JvZHksZGl2LGRsLGR0LGRkLHVsLG9sLGxpLGgxLGgyLGgzLGg0LGg1LGg2LHByZSxjb2RlLGZvcm0sZmllbGRzZXQsbGVnZW5kLGlucHV0LHRleHRhcmVhLHAsYmxvY2txdW90ZSx0aCx0ZHttYXJnaW46MDtwYWRkaW5nOjB9aGVhZGVyLGZvb3RlcixzZWN0aW9uLGFydGljbGUsYXNpZGUsbmF2LGhncm91cCxhZGRyZXNzLGZpZ3VyZSxmaWdjYXB0aW9uLG1lbnUsZGV0YWlsc3tkaXNwbGF5OmJsb2NrfWF1ZGlvLGNhbnZhcyx2aWRlb3tkaXNwbGF5OmlubGluZS1ibG9ja310YWJsZXtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Ym9yZGVyLXNwYWNpbmc6MH1maWVsZHNldCxpbWd7Ym9yZGVyOjB9YWRkcmVzcyxjYXB0aW9uLGNpdGUsY29kZSxkZm4sZW0sdGgsdmFye2ZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbH1vbCx1bHtsaXN0LXN0eWxlOm5vbmV9Y2FwdGlvbix0aHt0ZXh0LWFsaWduOmxlZnR9aDEsaDIsaDMsaDQsaDUsaDZ7Zm9udC1zaXplOjEwMCU7Zm9udC13ZWlnaHQ6bm9ybWFsfXE6YmVmb3JlLHE6YWZ0ZXJ7Y29udGVudDonJ31hYmJyLGFjcm9ueW17Ym9yZGVyOjA7Zm9udC12YXJpYW50Om5vcm1hbH1zdXB7dmVydGljYWwtYWxpZ246dGV4dC10b3B9c3Vie3ZlcnRpY2FsLWFsaWduOnRleHQtYm90dG9tfWlucHV0LHRleHRhcmVhLHNlbGVjdHtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZTppbmhlcml0O2ZvbnQtd2VpZ2h0OmluaGVyaXR9bGVnZW5ke2NvbG9yOiMwMDB9aHRtbCxib2R5e2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNHB4O2xpbmUtaGVpZ2h0OjMwcHg7Y29sb3I6IzMzMztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9YXt0ZXh0LWRlY29yYXRpb246bm9uZTtjb2xvcjojMDA3OWJjfWE6aG92ZXJ7Y29sb3I6IzAwNWI5Yn1we21hcmdpbi1ib3R0b206MThweH1oMSxoMixoMyxoNCxoNSxoNntwYWRkaW5nOjEycHggMH1oMXtmb250LXNpemU6MjhweH1oMntmb250LXNpemU6MjRweH1oM3tmb250LXNpemU6MjFweH1oNHtmb250LXNpemU6MTlweH1oNXtmb250LXNpemU6MTZweH1oNntmb250LXNpemU6MTRweH0udGV4dC1sZWZ0e3RleHQtYWxpZ246bGVmdH0udGV4dC1yaWdodHt0ZXh0LWFsaWduOnJpZ2h0fS50ZXh0LWNlbnRlcnt0ZXh0LWFsaWduOmNlbnRlcn0ubGVmdHtmbG9hdDpsZWZ0fS5yaWdodHtmbG9hdDpyaWdodH0uYWJzb2x1dGV7cG9zaXRpb246YWJzb2x1dGV9LnJlbGF0aXZle3Bvc2l0aW9uOnJlbGF0aXZlfS5jbGVhcjphZnRlcnt2aXNpYmlsaXR5OmhpZGRlbjtkaXNwbGF5OmJsb2NrO2ZvbnQtc2l6ZTowO2NvbnRlbnQ6IiAiO2NsZWFyOmJvdGg7aGVpZ2h0OjB9LnZlcnRpY2FsLW1pZGRsZXt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9LmlubGluZXtkaXNwbGF5OmlubGluZX0uaW5saW5lLWJsb2Nre2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5ibG9ja3tkaXNwbGF5OmJsb2NrfS5mYWRlLW91dHtvcGFjaXR5OjB9LmhpZGV7ZGlzcGxheTpub25lICFpbXBvcnRhbnR9LmNvbnRhaW5lcnttYXgtd2lkdGg6MTIwMHB4O21hcmdpbjphdXRvfS5jb250YWluZXI5NjB7bWF4LXdpZHRoOjk2MHB4O21hcmdpbjphdXRvfS5ncmlkLTEtMnt3aWR0aDo1MCV9LmdyaWQtMS0ze3dpZHRoOjMzLjMzMzMlfS5ncmlkLTEtNHt3aWR0aDoyNSV9LmdyaWQtMS01e3dpZHRoOjIwJX0uZ3JpZC0xLTZ7d2lkdGg6MTYuNjY2NiV9LmdyaWQtMi0ze3dpZHRoOjY2LjY2NjYlfS5ncmlkLTMtNHt3aWR0aDo3NSV9LmdyaWQtMy01e3dpZHRoOjYwJX0uZ3JpZC00LTV7d2lkdGg6ODAlfS5ncmlkLTUtNnt3aWR0aDo4My4zMzMzJX1pbnB1dCx0ZXh0YXJlYSxzZWxlY3QsYnV0dG9ue2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmfS5mb3JtIGxlZ2VuZHtmb250LXNpemU6MThweDttYXJnaW4tYm90dG9tOjE0cHh9LmZvcm0gbGFiZWx7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLmlwdHtwYWRkaW5nOjhweCAxMnB4O2JvcmRlcjoxcHggc29saWQgIzk5OTtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHg7b3V0bGluZTpub25lO21pbi13aWR0aDoxODBweH0uZm9ybSAuaXB0OmZvY3Vze2JvcmRlci1jb2xvcjojMDA3OWJjfS5mb3JtIC5jaGt7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luOjJweCA2cHggMCAwO2xpbmUtaGVpZ2h0Om5vcm1hbH0uZm9ybSAuZmllbGR7bWFyZ2luLWJvdHRvbToyNHB4fS5mb3JtIC5pbnZhbGlke21hcmdpbi1yaWdodDoxMnB4fS5mb3JtIC50aXB7Zm9udC1zaXplOjEzcHg7Y29sb3I6Izk5OTttYXJnaW4tbGVmdDoxMnB4fS5mb3JtLXZlcnRpY2FsIGxhYmVse2Rpc3BsYXk6YmxvY2s7bWFyZ2luLWJvdHRvbTo4cHh9LmZvcm0tdmVydGljYWwgLmlwdHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveH0uZm9ybS12ZXJ0aWNhbCAuaW52YWxpZHttYXJnaW4tcmlnaHQ6MDttYXJnaW4tdG9wOjZweH0uZm9ybS1hbGlnbiBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttaW4td2lkdGg6NjBweDt0ZXh0LWFsaWduOnJpZ2h0fS5mb3JtLWFsaWduIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5idG57bWluLXdpZHRoOjEyMHB4O2hlaWdodDozNnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7Ym9yZGVyOm5vbmU7bWFyZ2luOjB9LmJ0bjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM5OTk7Y3Vyc29yOnBvaW50ZXJ9YS5idG57bGluZS1oZWlnaHQ6MzZweDtjb2xvcjojZmZmfS5idG4tcmVke2JhY2tncm91bmQtY29sb3I6I2U2NDM0Njtjb2xvcjojZmJmYmZifS5idG4tcmVkOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2M3MzgzYX0uYnRuLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9LmJ0bi1ibHVlOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzAwNWI5Yn0uYnRuLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifS5idG4tZ3JlZW46aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNjQ5NDYyfS5sYmx7cGFkZGluZzo0cHggMTJweDtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7Y29sb3I6IzMzMztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LmxibC1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9YS5sYmx7bGluZS1oZWlnaHQ6MjZweH1hLmxibC1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhO2NvbG9yOiNmYmZiZmJ9LmxibC1ibHVle2JhY2tncm91bmQtY29sb3I6IzAwNzliYztjb2xvcjojZmJmYmZifWEubGJsLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjliO2NvbG9yOiNmYmZiZmJ9LmxibC1ncmVlbntiYWNrZ3JvdW5kLWNvbG9yOiM3YWIyNzc7Y29sb3I6I2ZiZmJmYn1hLmxibC1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjI7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLml0ZW17cGFkZGluZzoycHggOHB4O21hcmdpbjowIDZweDtjb2xvcjojMzMzO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2xpbmUtaGVpZ2h0OjIwcHh9LnBhZ2VyIC5pdGVtIGF7Y29sb3I6IzMzM30ucGFnZXIgLml0ZW06aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLml0ZW06aG92ZXIgYXtjb2xvcjojZmZmfS5wYWdlciAuY3VycmVudHtiYWNrZ3JvdW5kLWNvbG9yOiM2NjY7Y29sb3I6I2ZiZmJmYjtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LnBhZ2VyIC5jdXJyZW50IGF7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLmN1cnJlbnQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjfS5tYXJrZG93biBoMSwubWFya2Rvd24gaDIsLm1hcmtkb3duIGgzLC5tYXJrZG93biBoNCwubWFya2Rvd24gaDUsLm1hcmtkb3duIGg2e3BhZGRpbmc6MThweCAwIDlweCAwO2ZvbnQtd2VpZ2h0OmJvbGR9Lm1hcmtkb3duIGgxe2ZvbnQtc2l6ZToyNHB4fS5tYXJrZG93biBoMntmb250LXNpemU6MjFweH0ubWFya2Rvd24gaDEsLm1hcmtkb3duIGgye21hcmdpbi1ib3R0b206MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfS5tYXJrZG93biBoM3tmb250LXNpemU6MTlweH0ubWFya2Rvd24gaDR7Zm9udC1zaXplOjE4cHh9Lm1hcmtkb3duIGg1e2ZvbnQtc2l6ZToxNnB4fS5tYXJrZG93biBoNntmb250LXNpemU6MTRweH0ubWFya2Rvd24gcHttYXJnaW4tYm90dG9tOjEwcHh9Lm1hcmtkb3duIHVse2xpc3Qtc3R5bGU6ZGlzYyBpbnNpZGV9Lm1hcmtkb3duIG9se2xpc3Qtc3R5bGU6ZGVjaW1hbCBpbnNpZGV9Lm1hcmtkb3duIGNvZGV7Zm9udC1mYW1pbHk6Q29uc29sYXMsIkNvdXJpZXIgTmV3IixBcmlhbH0ubWFya2Rvd24gcCBjb2Rle2NvbG9yOiNjNzM4M2F9Lm1hcmtkb3duIGJsb2NrcXVvdGV7cGFkZGluZzo4cHggMThweDtib3JkZXItbGVmdDo0cHggc29saWQgI2NjYztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9Lm1hcmtkb3duIGJsb2NrcXVvdGUgcHttYXJnaW4tYm90dG9tOjB9Lm1hcmtkb3duIHByZSBjb2Rle2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjE4cHggIWltcG9ydGFudDtwYWRkaW5nOjhweCAxOHB4O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjEycHggMCAxOHB4IDB9Lm1hcmtkb3duIG9sLC5tYXJrZG93biB1bHttYXJnaW46MTJweCAyNHB4fS5tYXJrZG93biBwIGltZ3ttYXgtd2lkdGg6OTklO2hlaWdodDphdXRvO21hcmdpbjowIGF1dG87ZGlzcGxheTpibG9ja30ubWFya2Rvd24gdGFibGV7bWFyZ2luOjEycHggMDt3aWR0aDo5OCV9Lm1hcmtkb3duIHRhYmxlIHRoLC5tYXJrZG93biB0YWJsZSB0ZHtib3JkZXI6MXB4IHNvbGlkICNjY2M7cGFkZGluZzo0cHggMTJweH0ubWFya2Rvd24gdGFibGUgdGhlYWR7YmFja2dyb3VuZDojZjZmNmY2fTo6LXdlYmtpdC1zY3JvbGxiYXJ7d2lkdGg6OHB4O21hcmdpbi1yaWdodDoycHh9Ojotd2Via2l0LXNjcm9sbGJhci10cmFjay1waWVjZXtiYWNrZ3JvdW5kLWNvbG9yOiNmNWY1ZjU7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkICNkMmQyZDJ9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYntiYWNrZ3JvdW5kOiM5ZmEwOWM7d2lkdGg6OHB4fTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXJ7YmFja2dyb3VuZDojYjdiOGFkfVBLBwgCIbcNaRUAAGkVAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABgAAABzdGF0aWNcY3NzXGhpZ2hsaWdodC5jc3MvKg0KDQpTdW5idXJzdC1saWtlIHN0eWxlIChjKSBWYXNpbHkgUG9sb3ZueW92IDx2YXN0QHdoaXRlYW50cy5uZXQ+DQoNCiovDQoNCnByZSBjb2RlIHsNCiAgICBkaXNwbGF5OiBibG9jazsgcGFkZGluZzogMC41ZW07DQogICAgYmFja2dyb3VuZDogIzAwMDsgY29sb3I6ICNmOGY4Zjg7DQp9DQoNCnByZSAuY29tbWVudCwNCnByZSAudGVtcGxhdGVfY29tbWVudCwNCnByZSAuamF2YWRvYyB7DQogICAgY29sb3I6ICNhZWFlYWU7DQogICAgZm9udC1zdHlsZTogaXRhbGljOw0KfQ0KDQpwcmUgLmtleXdvcmQsDQpwcmUgLnJ1YnkgLmZ1bmN0aW9uIC5rZXl3b3JkLA0KcHJlIC5yZXF1ZXN0LA0KcHJlIC5zdGF0dXMsDQpwcmUgLm5naW54IC50aXRsZSB7DQogICAgY29sb3I6ICNFMjg5NjQ7DQp9DQoNCnByZSAuZnVuY3Rpb24gLmtleXdvcmQsDQpwcmUgLnN1YiAua2V5d29yZCwNCnByZSAubWV0aG9kLA0KcHJlIC5saXN0IC50aXRsZSB7DQogICAgY29sb3I6ICM5OUNGNTA7DQp9DQoNCnByZSAuc3RyaW5nLA0KcHJlIC50YWcgLnZhbHVlLA0KcHJlIC5jZGF0YSwNCnByZSAuZmlsdGVyIC5hcmd1bWVudCwNCnByZSAuYXR0cl9zZWxlY3RvciwNCnByZSAuYXBhY2hlIC5jYnJhY2tldCwNCnByZSAuZGF0ZSwNCnByZSAudGV4IC5jb21tYW5kLA0KcHJlIC5jb2ZmZWVzY3JpcHQgLmF0dHJpYnV0ZSB7DQogICAgY29sb3I6ICM2NUIwNDI7DQp9DQoNCnByZSAuc3Vic3Qgew0KICAgIGNvbG9yOiAjREFFRkEzOw0KfQ0KDQpwcmUgLnJlZ2V4cCB7DQogICAgY29sb3I6ICNFOUMwNjI7DQp9DQoNCnByZSAudGl0bGUsDQpwcmUgLnN1YiAuaWRlbnRpZmllciwNCnByZSAucGksDQpwcmUgLnRhZywNCnByZSAudGFnIC5rZXl3b3JkLA0KcHJlIC5kZWNvcmF0b3IsDQpwcmUgLnNoZWJhbmcsDQpwcmUgLnByb21wdCB7DQogICAgY29sb3I6ICM4OUJERkY7DQp9DQoNCnByZSAuY2xhc3MgLnRpdGxlLA0KcHJlIC5oYXNrZWxsIC50eXBlLA0KcHJlIC5zbWFsbHRhbGsgLmNsYXNzLA0KcHJlIC5qYXZhZG9jdGFnLA0KcHJlIC55YXJkb2N0YWcsDQpwcmUgLnBocGRvYyB7DQogICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7DQp9DQoNCnByZSAuc3ltYm9sLA0KcHJlIC5ydWJ5IC5zeW1ib2wgLnN0cmluZywNCnByZSAubnVtYmVyIHsNCiAgICBjb2xvcjogIzMzODdDQzsNCn0NCg0KcHJlIC5wYXJhbXMsDQpwcmUgLnZhcmlhYmxlLA0KcHJlIC5jbG9qdXJlIC5hdHRyaWJ1dGUgew0KICAgIGNvbG9yOiAjM0U4N0UzOw0KfQ0KDQpwcmUgLmNzcyAudGFnLA0KcHJlIC5ydWxlcyAucHJvcGVydHksDQpwcmUgLnBzZXVkbywNCnByZSAudGV4IC5zcGVjaWFsIHsNCiAgICBjb2xvcjogI0NEQTg2OTsNCn0NCg0KcHJlIC5jc3MgLmNsYXNzIHsNCiAgICBjb2xvcjogIzlCNzAzRjsNCn0NCg0KcHJlIC5ydWxlcyAua2V5d29yZCB7DQogICAgY29sb3I6ICNDNUFGNzU7DQp9DQoNCnByZSAucnVsZXMgLnZhbHVlIHsNCiAgICBjb2xvcjogI0NGNkE0QzsNCn0NCg0KcHJlIC5jc3MgLmlkIHsNCiAgICBjb2xvcjogIzhCOThBQjsNCn0NCg0KcHJlIC5hbm5vdGF0aW9uLA0KcHJlIC5hcGFjaGUgLnNxYnJhY2tldCwNCnByZSAubmdpbnggLmJ1aWx0X2luIHsNCiAgICBjb2xvcjogIzlCODU5RDsNCn0NCg0KcHJlIC5wcmVwcm9jZXNzb3IsDQpwcmUgLnByYWdtYSB7DQogICAgY29sb3I6ICM4OTk2QTg7DQp9DQoNCnByZSAuaGV4Y29sb3IsDQpwcmUgLmNzcyAudmFsdWUgLm51bWJlciB7DQogICAgY29sb3I6ICNERDdCM0I7DQp9DQoNCnByZSAuY3NzIC5mdW5jdGlvbiB7DQogICAgY29sb3I6ICNEQUQwODU7DQp9DQoNCnByZSAuZGlmZiAuaGVhZGVyLA0KcHJlIC5jaHVuaywNCnByZSAudGV4IC5mb3JtdWxhIHsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMEUyMjMxOw0KICAgIGNvbG9yOiAjRjhGOEY4Ow0KICAgIGZvbnQtc3R5bGU6IGl0YWxpYzsNCn0NCg0KcHJlIC5kaWZmIC5jaGFuZ2Ugew0KICAgIGJhY2tncm91bmQtY29sb3I6ICM0QTQxMEQ7DQogICAgY29sb3I6ICNGOEY4Rjg7DQp9DQoNCnByZSAuYWRkaXRpb24gew0KICAgIGJhY2tncm91bmQtY29sb3I6ICMyNTNCMjI7DQogICAgY29sb3I6ICNGOEY4Rjg7DQp9DQoNCnByZSAuZGVsZXRpb24gew0KICAgIGJhY2tncm91bmQtY29sb3I6ICM0MjBFMDk7DQogICAgY29sb3I6ICNGOEY4Rjg7DQp9DQoNCnByZSAuY29mZmVlc2NyaXB0IC5qYXZhc2NyaXB0LA0KcHJlIC5qYXZhc2NyaXB0IC54bWwsDQpwcmUgLnRleCAuZm9ybXVsYSwNCnByZSAueG1sIC5qYXZhc2NyaXB0LA0KcHJlIC54bWwgLnZic2NyaXB0LA0KcHJlIC54bWwgLmNzcywNCnByZSAueG1sIC5jZGF0YSB7DQogICAgb3BhY2l0eTogMC41Ow0KfQ0KDQpwcmUgLmdvIC50eXBlbmFtZXsNCiAgICBjb2xvcjogI2ZmYmM1NDsNCn1QSwcIw2jj3l0JAABdCQAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAATAAAAc3RhdGljXGNzc1xsaW5nLmNzc2JvZHksZGl2LGRsLGR0LGRkLHVsLG9sLGxpLGgxLGgyLGgzLGg0LGg1LGg2LHByZSxjb2RlLGZvcm0sZmllbGRzZXQsbGVnZW5kLGlucHV0LHRleHRhcmVhLHAsYmxvY2txdW90ZSx0aCx0ZHttYXJnaW46MDtwYWRkaW5nOjB9aGVhZGVyLGZvb3RlcixzZWN0aW9uLGFydGljbGUsYXNpZGUsbmF2LGhncm91cCxhZGRyZXNzLGZpZ3VyZSxmaWdjYXB0aW9uLG1lbnUsZGV0YWlsc3tkaXNwbGF5OmJsb2NrfWF1ZGlvLGNhbnZhcyx2aWRlb3tkaXNwbGF5OmlubGluZS1ibG9ja310YWJsZXtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Ym9yZGVyLXNwYWNpbmc6MH1maWVsZHNldCxpbWd7Ym9yZGVyOjB9YWRkcmVzcyxjYXB0aW9uLGNpdGUsY29kZSxkZm4sZW0sdGgsdmFye2ZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbH1vbCx1bHtsaXN0LXN0eWxlOm5vbmV9Y2FwdGlvbix0aHt0ZXh0LWFsaWduOmxlZnR9aDEsaDIsaDMsaDQsaDUsaDZ7Zm9udC1zaXplOjEwMCU7Zm9udC13ZWlnaHQ6bm9ybWFsfXE6YmVmb3JlLHE6YWZ0ZXJ7Y29udGVudDonJ31hYmJyLGFjcm9ueW17Ym9yZGVyOjA7Zm9udC12YXJpYW50Om5vcm1hbH1zdXB7dmVydGljYWwtYWxpZ246dGV4dC10b3B9c3Vie3ZlcnRpY2FsLWFsaWduOnRleHQtYm90dG9tfWlucHV0LHRleHRhcmVhLHNlbGVjdHtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZTppbmhlcml0O2ZvbnQtd2VpZ2h0OmluaGVyaXR9bGVnZW5ke2NvbG9yOiMwMDB9aHRtbCxib2R5e2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNHB4O2xpbmUtaGVpZ2h0OjMwcHg7Y29sb3I6IzMzMztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9YXt0ZXh0LWRlY29yYXRpb246bm9uZTtjb2xvcjojMDA3OWJjfWE6aG92ZXJ7Y29sb3I6IzAwNWI5Yn1we21hcmdpbi1ib3R0b206MThweH1oMSxoMixoMyxoNCxoNSxoNntwYWRkaW5nOjEycHggMH1oMXtmb250LXNpemU6MjhweH1oMntmb250LXNpemU6MjRweH1oM3tmb250LXNpemU6MjFweH1oNHtmb250LXNpemU6MTlweH1oNXtmb250LXNpemU6MTZweH1oNntmb250LXNpemU6MTRweH0udGV4dC1sZWZ0e3RleHQtYWxpZ246bGVmdH0udGV4dC1yaWdodHt0ZXh0LWFsaWduOnJpZ2h0fS50ZXh0LWNlbnRlcnt0ZXh0LWFsaWduOmNlbnRlcn0ubGVmdHtmbG9hdDpsZWZ0fS5yaWdodHtmbG9hdDpyaWdodH0uYWJzb2x1dGV7cG9zaXRpb246YWJzb2x1dGV9LnJlbGF0aXZle3Bvc2l0aW9uOnJlbGF0aXZlfS5jbGVhcjphZnRlcnt2aXNpYmlsaXR5OmhpZGRlbjtkaXNwbGF5OmJsb2NrO2ZvbnQtc2l6ZTowO2NvbnRlbnQ6IiAiO2NsZWFyOmJvdGg7aGVpZ2h0OjB9LnZlcnRpY2FsLW1pZGRsZXt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9LmlubGluZXtkaXNwbGF5OmlubGluZX0uaW5saW5lLWJsb2Nre2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5ibG9ja3tkaXNwbGF5OmJsb2NrfS5mYWRlLW91dHtvcGFjaXR5OjB9LmhpZGV7ZGlzcGxheTpub25lICFpbXBvcnRhbnR9LmNvbnRhaW5lcnttYXgtd2lkdGg6MTIwMHB4O21hcmdpbjphdXRvfS5jb250YWluZXI5NjB7bWF4LXdpZHRoOjk2MHB4O21hcmdpbjphdXRvfS5ncmlkLTEtMnt3aWR0aDo1MCV9LmdyaWQtMS0ze3dpZHRoOjMzLjMzMzMlfS5ncmlkLTEtNHt3aWR0aDoyNSV9LmdyaWQtMS01e3dpZHRoOjIwJX0uZ3JpZC0xLTZ7d2lkdGg6MTYuNjY2NiV9LmdyaWQtMi0ze3dpZHRoOjY2LjY2NjYlfS5ncmlkLTMtNHt3aWR0aDo3NSV9LmdyaWQtMy01e3dpZHRoOjYwJX0uZ3JpZC00LTV7d2lkdGg6ODAlfS5ncmlkLTUtNnt3aWR0aDo4My4zMzMzJX1pbnB1dCx0ZXh0YXJlYSxzZWxlY3QsYnV0dG9ue2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmfS5mb3JtIGxlZ2VuZHtmb250LXNpemU6MThweDttYXJnaW4tYm90dG9tOjE0cHh9LmZvcm0gbGFiZWx7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLmlwdHtwYWRkaW5nOjhweCAxMnB4O2JvcmRlcjoxcHggc29saWQgIzk5OTtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHg7b3V0bGluZTpub25lO21pbi13aWR0aDoxODBweH0uZm9ybSAuaXB0OmZvY3Vze2JvcmRlci1jb2xvcjojMDA3OWJjfS5mb3JtIC5jaGt7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luOjJweCA2cHggMCAwO2xpbmUtaGVpZ2h0Om5vcm1hbH0uZm9ybSAuZmllbGR7bWFyZ2luLWJvdHRvbToyNHB4fS5mb3JtIC5pbnZhbGlke21hcmdpbi1yaWdodDoxMnB4fS5mb3JtIC50aXB7Zm9udC1zaXplOjEzcHg7Y29sb3I6Izk5OTttYXJnaW4tbGVmdDoxMnB4fS5mb3JtLXZlcnRpY2FsIGxhYmVse2Rpc3BsYXk6YmxvY2s7bWFyZ2luLWJvdHRvbTo4cHh9LmZvcm0tdmVydGljYWwgLmlwdHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveH0uZm9ybS12ZXJ0aWNhbCAuaW52YWxpZHttYXJnaW4tcmlnaHQ6MDttYXJnaW4tdG9wOjZweH0uZm9ybS1hbGlnbiBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttaW4td2lkdGg6NjBweDt0ZXh0LWFsaWduOnJpZ2h0fS5mb3JtLWFsaWduIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5idG57bWluLXdpZHRoOjEyMHB4O2hlaWdodDozNnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7Ym9yZGVyOm5vbmU7bWFyZ2luOjB9LmJ0bjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM5OTk7Y3Vyc29yOnBvaW50ZXJ9YS5idG57bGluZS1oZWlnaHQ6MzZweDtjb2xvcjojZmZmfS5idG4tcmVke2JhY2tncm91bmQtY29sb3I6I2U2NDM0Njtjb2xvcjojZmJmYmZifS5idG4tcmVkOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2M3MzgzYX0uYnRuLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9LmJ0bi1ibHVlOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzAwNWI5Yn0uYnRuLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifS5idG4tZ3JlZW46aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNjQ5NDYyfS5sYmx7cGFkZGluZzo0cHggMTJweDtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7Y29sb3I6IzMzMztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LmxibC1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9YS5sYmx7bGluZS1oZWlnaHQ6MjZweH1hLmxibC1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhO2NvbG9yOiNmYmZiZmJ9LmxibC1ibHVle2JhY2tncm91bmQtY29sb3I6IzAwNzliYztjb2xvcjojZmJmYmZifWEubGJsLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjliO2NvbG9yOiNmYmZiZmJ9LmxibC1ncmVlbntiYWNrZ3JvdW5kLWNvbG9yOiM3YWIyNzc7Y29sb3I6I2ZiZmJmYn1hLmxibC1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjI7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLml0ZW17cGFkZGluZzoycHggOHB4O21hcmdpbjowIDZweDtjb2xvcjojMzMzO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2xpbmUtaGVpZ2h0OjIwcHh9LnBhZ2VyIC5pdGVtIGF7Y29sb3I6IzMzM30ucGFnZXIgLml0ZW06aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLml0ZW06aG92ZXIgYXtjb2xvcjojZmZmfS5wYWdlciAuY3VycmVudHtiYWNrZ3JvdW5kLWNvbG9yOiM2NjY7Y29sb3I6I2ZiZmJmYjtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LnBhZ2VyIC5jdXJyZW50IGF7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLmN1cnJlbnQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjfS5tYXJrZG93biBoMSwubWFya2Rvd24gaDIsLm1hcmtkb3duIGgzLC5tYXJrZG93biBoNCwubWFya2Rvd24gaDUsLm1hcmtkb3duIGg2e3BhZGRpbmc6MThweCAwIDlweCAwO2ZvbnQtd2VpZ2h0OmJvbGR9Lm1hcmtkb3duIGgxe2ZvbnQtc2l6ZToyNHB4fS5tYXJrZG93biBoMntmb250LXNpemU6MjFweH0ubWFya2Rvd24gaDEsLm1hcmtkb3duIGgye21hcmdpbi1ib3R0b206MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfS5tYXJrZG93biBoM3tmb250LXNpemU6MTlweH0ubWFya2Rvd24gaDR7Zm9udC1zaXplOjE4cHh9Lm1hcmtkb3duIGg1e2ZvbnQtc2l6ZToxNnB4fS5tYXJrZG93biBoNntmb250LXNpemU6MTRweH0ubWFya2Rvd24gcHttYXJnaW4tYm90dG9tOjEwcHh9Lm1hcmtkb3duIHVse2xpc3Qtc3R5bGU6ZGlzYyBpbnNpZGV9Lm1hcmtkb3duIG9se2xpc3Qtc3R5bGU6ZGVjaW1hbCBpbnNpZGV9Lm1hcmtkb3duIGNvZGV7Zm9udC1mYW1pbHk6Q29uc29sYXMsIkNvdXJpZXIgTmV3IixBcmlhbH0ubWFya2Rvd24gcCBjb2Rle2NvbG9yOiNjNzM4M2F9Lm1hcmtkb3duIGJsb2NrcXVvdGV7cGFkZGluZzo4cHggMThweDtib3JkZXItbGVmdDo0cHggc29saWQgI2NjYztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9Lm1hcmtkb3duIGJsb2NrcXVvdGUgcHttYXJnaW4tYm90dG9tOjB9Lm1hcmtkb3duIHByZSBjb2Rle2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjE4cHggIWltcG9ydGFudDtwYWRkaW5nOjhweCAxOHB4O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjEycHggMCAxOHB4IDB9Lm1hcmtkb3duIG9sLC5tYXJrZG93biB1bHttYXJnaW46MTJweCAyNHB4fS5tYXJrZG93biBwIGltZ3ttYXgtd2lkdGg6OTklO2hlaWdodDphdXRvO21hcmdpbjowIGF1dG87ZGlzcGxheTpibG9ja30ubWFya2Rvd24gdGFibGV7bWFyZ2luOjEycHggMDt3aWR0aDo5OCV9Lm1hcmtkb3duIHRhYmxlIHRoLC5tYXJrZG93biB0YWJsZSB0ZHtib3JkZXI6MXB4IHNvbGlkICNjY2M7cGFkZGluZzo0cHggMTJweH0ubWFya2Rvd24gdGFibGUgdGhlYWR7YmFja2dyb3VuZDojZjZmNmY2fTo6LXdlYmtpdC1zY3JvbGxiYXJ7d2lkdGg6OHB4O21hcmdpbi1yaWdodDoycHh9Ojotd2Via2l0LXNjcm9sbGJhci10cmFjay1waWVjZXtiYWNrZ3JvdW5kLWNvbG9yOiNmNWY1ZjU7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkICNkMmQyZDJ9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYntiYWNrZ3JvdW5kOiM5ZmEwOWM7d2lkdGg6OHB4fTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXJ7YmFja2dyb3VuZDojYjdiOGFkfWh0bWwsYm9keXtiYWNrZ3JvdW5kOiNmM2YzZjN9I2hlYWRlcntiYWNrZ3JvdW5kOiMwMDkzYzQ7bWluLXdpZHRoOjEyMHB4O3BhZGRpbmc6NDBweCAwIDQ4cHggMDtjb2xvcjojZmJmYmZifSNoZWFkZXIgYTpob3Zlcntjb2xvcjojZmZmO3RleHQtc2hhZG93OjAgMCAzcHggIzMzMzstbW96LXRleHQtc2hhZG93OjAgMCAzcHggIzMzMzstd2Via2l0LXRleHQtc2hhZG93OjAgMCAzcHggIzMzM30jaGVhZGVyLWltZ3t3aWR0aDo5NnB4O2hlaWdodDo5NnB4O2JvcmRlci1yYWRpdXM6NTBweDstbW96LWJvcmRlci1yYWRpdXM6NTBweDstd2Via2l0LWJvcmRlci1yYWRpdXM6NTBweH0jaGVhZGVyLWh7bGluZS1oZWlnaHQ6OTRweDtjb2xvcjojZmJmYmZiO3BhZGRpbmc6MDttYXJnaW4tbGVmdDoyNHB4fSNoZWFkZXItaCBhe2NvbG9yOiNmYmZiZmJ9I2hlYWRlci1zdWJ7Y29sb3I6I2YzZjNmMzttYXJnaW4tbGVmdDoxLjJlbTtmb250LXNpemU6MTZweH0jbmF2e2xpbmUtaGVpZ2h0OjkwcHh9I25hdiBsaXtsaW5lLWhlaWdodDo1MHB4O21hcmdpbi1sZWZ0OjQ0cHh9I25hdiBsaSBhe2ZvbnQtc2l6ZToxOHB4O2NvbG9yOiNmM2YzZjM7ZGlzcGxheTpibG9ja30jbmF2IGxpIGE6aG92ZXJ7Y29sb3I6I2ZmZjt0ZXh0LXNoYWRvdzowIDAgM3B4ICMzMzM7LW1vei10ZXh0LXNoYWRvdzowIDAgM3B4ICMzMzM7LXdlYmtpdC10ZXh0LXNoYWRvdzowIDAgM3B4ICMzMzN9I2Zvb3RlcntwYWRkaW5nOjMwcHggNDBweDtjb2xvcjojOTk5fSNtYWlue21hcmdpbjozMHB4IGF1dG99I2dvLXRvcHtib3R0b206NTBweDtyaWdodDo0MHB4O3Bvc2l0aW9uOmZpeGVkO2NvbG9yOiNmZmY7cGFkZGluZy10b3A6NnB4O3BhZGRpbmctYm90dG9tOjhweDtvcGFjaXR5Oi40fSNhcnRpY2xlLWNvbnRhaW5lcntoZWlnaHQ6MTAwJX0jYXJ0aWNsZS1jb250YWluZXIgLmNvbW1lbnRzLCNhcnRpY2xlLWNvbnRhaW5lciAudmlld3N7Zm9udC1mYW1pbHk6VmVyZGFuYSxUYWhvbWEsJ+W+rui9r+mbhem7kScsJ+Wui+S9kycsc2Fucy1zZXJpZn0jYXJ0aWNsZS1jb250YWluZXIgLmNvbW1lbnRze3dpZHRoOjU2cHg7aGVpZ2h0OjU2cHg7Ym9yZGVyLXJhZGl1czozNnB4Oy1tb3otYm9yZGVyLXJhZGl1czozNnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czozNnB4O2xpbmUtaGVpZ2h0OjU2cHg7Zm9udC1zaXplOjI0cHg7cGFkZGluZzowO21hcmdpbi10b3A6NDBweDttYXJnaW4tbGVmdDo4cHg7Ym9yZGVyOjZweCBzb2xpZCAjZmZmO2JveC1zaGFkb3c6MCAwIDJweCAjOTk5Oy1tb3otYm94LXNoYWRvdzowIDAgMnB4ICM5OTk7LXdlYmtpdC1ib3gtc2hhZG93OjAgMCAycHggIzk5OX0jYXJ0aWNsZS1jb250YWluZXIgLmNvbW1lbnRzIGF7Y29sb3I6I2ZmZn0jYXJ0aWNsZS1jb250YWluZXIgLmNvbW1lbnRzOmhvdmVye2JveC1zaGFkb3c6MCAwIDRweCAjNjY2Oy1tb3otYm94LXNoYWRvdzowIDAgNHB4ICM2NjY7LXdlYmtpdC1ib3gtc2hhZG93OjAgMCA0cHggIzY2Nn0jYXJ0aWNsZS1jb250YWluZXIgLnZpZXdze3RvcDoxNHB4O2xlZnQ6MDt3aWR0aDozNnB4O2hlaWdodDozNnB4O2xpbmUtaGVpZ2h0OjM2cHg7Ym9yZGVyLXJhZGl1czozMHB4Oy1tb3otYm9yZGVyLXJhZGl1czozMHB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czozMHB4O3BhZGRpbmc6MDtib3JkZXI6NHB4IHNvbGlkICNmZmY7Ym94LXNoYWRvdzowIDAgMnB4ICM5OTk7LW1vei1ib3gtc2hhZG93OjAgMCAycHggIzk5OTstd2Via2l0LWJveC1zaGFkb3c6MCAwIDJweCAjOTk5fSNhcnRpY2xlLWNvbnRhaW5lciAubWFpbnttYXJnaW4tbGVmdDoxMTZweDtib3JkZXItcmFkaXVzOjRweDstbW96LWJvcmRlci1yYWRpdXM6NHB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czo0cHg7Ym94LXNoYWRvdzowIDFweCAycHggI2JiYjstbW96LWJveC1zaGFkb3c6MCAxcHggMnB4ICNiYmI7LXdlYmtpdC1ib3gtc2hhZG93OjAgMXB4IDJweCAjYmJiO2JhY2tncm91bmQ6I2ZmZjtwYWRkaW5nOjE4cHggMjRweH0jYXJ0aWNsZS1jb250YWluZXIgLm1haW46YmVmb3Jle2NvbnRlbnQ6IiI7ZGlzcGxheTpibG9jaztib3JkZXI6MTFweCBzb2xpZCB0cmFuc3BhcmVudDtib3JkZXItcmlnaHQtY29sb3I6I2ZmZjtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6NjNweDtsZWZ0Oi0yMnB4fSNhcnRpY2xlLWNvbnRhaW5lciAubWFpbiBoMy50aXRsZXtmb250LXNpemU6MjhweDtwYWRkaW5nLWJvdHRvbToyNHB4fSNhcnRpY2xlLWNvbnRhaW5lciAubWFpbiAudGltZS1pbmZve2NvbG9yOiM5OTk7bWFyZ2luLWJvdHRvbToyMHB4O3BhZGRpbmctYm90dG9tOjIwcHg7Ym9yZGVyLWJvdHRvbToxcHggZGFzaGVkICNkZGQ7dGV4dC1pbmRlbnQ6MWVtO2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWZ9I2FydGljbGUtY29udGFpbmVyIGFydGljbGV7bWFyZ2luLWJvdHRvbTo1MHB4fSNhcnRpY2xlLWNvbnRhaW5lciAuYXJ0aWNsZS1zaW5nbGUgLm1haW57bWFyZ2luLWxlZnQ6MH0jYXJ0aWNsZS1jb250YWluZXIgLmFydGljbGUtc2luZ2xlIC5tYWluOmJlZm9yZXtkaXNwbGF5Om5vbmV9I2FydGljbGUtY29udGFpbmVyIC5hcnRpY2xlLXNpbmdsZSAubWV0YXtyaWdodDo0NHB4O3RvcDotMzZweH0jYXJ0aWNsZS1jb250YWluZXIgLmFydGljbGUtc2luZ2xlIC52aWV3c3t3aWR0aDo1NnB4O2hlaWdodDo1NnB4O2JvcmRlci1yYWRpdXM6MzZweDstbW96LWJvcmRlci1yYWRpdXM6MzZweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MzZweDtsaW5lLWhlaWdodDo1NnB4O2ZvbnQtc2l6ZToyNHB4O3BhZGRpbmc6MDtib3JkZXI6NnB4IHNvbGlkICNmZmZ9I2FydGljbGUtY29udGFpbmVyIC50YWcgYXttYXJnaW46MCA0cHg7Y29sb3I6Izk5OX0jYXJ0aWNsZS1wYWdlcnttYXJnaW4tbGVmdDoxMTZweH0jYXJ0aWNsZS1wYWdlciAuaXRlbXttYXJnaW46MDtjb2xvcjojZmZmO2JhY2tncm91bmQ6Izk5OTtwYWRkaW5nOjEycHggMThweDtib3JkZXItcmFkaXVzOjRweDstbW96LWJvcmRlci1yYWRpdXM6NHB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czo0cHh9I2FydGljbGUtcGFnZXIgLml0ZW06aG92ZXJ7YmFja2dyb3VuZDojMDA3OWJjfSNjb21tZW50e2JvcmRlci1yYWRpdXM6NHB4Oy1tb3otYm9yZGVyLXJhZGl1czo0cHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjRweDtib3gtc2hhZG93OjAgMXB4IDJweCAjYmJiOy1tb3otYm94LXNoYWRvdzowIDFweCAycHggI2JiYjstd2Via2l0LWJveC1zaGFkb3c6MCAxcHggMnB4ICNiYmI7YmFja2dyb3VuZDojZmZmO3BhZGRpbmc6MThweCAyNHB4fSNjb21tZW50IC5tZXRhe3JpZ2h0Oi0yNHB4O3RvcDotMzBweH0jY29tbWVudCAubWV0YSAuY29tbWVudHN7bWFyZ2luLWxlZnQ6MDttYXJnaW4tdG9wOjB9I2NvbW1lbnQtbGlzdCAuY29tbWVudHttYXJnaW4tYm90dG9tOjMycHh9I2NvbW1lbnQtbGlzdCAuYy1hdmF0YXJ7bWFyZ2luLXJpZ2h0OjE4cHg7Ym9yZGVyLXJhZGl1czo0cHg7LW1vei1ib3JkZXItcmFkaXVzOjRweDstd2Via2l0LWJvcmRlci1yYWRpdXM6NHB4O21hcmdpbi10b3A6NnB4fSNjb21tZW50LWxpc3QgLmMtbWV0YSBwe21hcmdpbi1ib3R0b206MH0jY29tbWVudC1saXN0IC5jLW1ldGEgLmMtdGltZXtjb2xvcjojOTk5O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWZ9I2NvbW1lbnQtbGlzdCAuYy1tZXRhIC5jLWF1dGhvcntmb250LXNpemU6MTZweDtjb2xvcjojMzMzO2Rpc3BsYXk6YmxvY2t9I2NvbW1lbnQtbGlzdCAuYy1tZXRhIC5jLWF1dGhvcjpob3Zlcntjb2xvcjojMDA1YjlifSNjb21tZW50LWxpc3QgLmMtbWV0YSAuYy1yZXBseXtjb2xvcjojZmZmO2JhY2tncm91bmQ6I2RkZDtwYWRkaW5nOjNweCAxMHB4fSNjb21tZW50LWxpc3QgLmMtbWV0YSAuYy1yZXBseTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmN9I2NvbW1lbnQtbGlzdCAuYy1jb250ZW50e3BhZGRpbmctdG9wOjRweH0jY29tbWVudC1saXN0IC5jLWNoZWNre2ZvbnQtc2l6ZToxM3B4O2NvbG9yOiNlNjQzNDY7bWFyZ2luLWxlZnQ6MTJweH0jY29tbWVudC1saXN0IC5jLXAtbWR7bWFyZ2luLXRvcDoxMnB4O2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjIwcHg7Y29sb3I6IzY2Nn0jY29tbWVudC1zaG93e21hcmdpbi1ib3R0b206MzJweH0jY29tbWVudC10aXRsZXttYXJnaW4tYm90dG9tOjIwcHg7cGFkZGluZy1ib3R0b206MjBweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jY29tbWVudC1mb3Jte3dpZHRoOjgwJTttYXJnaW46YXV0bzttYXJnaW4tYm90dG9tOjMwcHh9I2NvbW1lbnQtZm9ybSAuYy1pbmZve3dpZHRoOjI2JX0jY29tbWVudC1mb3JtIC5jLWluZm8gLmlwdHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveDttaW4td2lkdGg6MH0jY29tbWVudC1mb3JtIC5jLWNvbnRlbnR7d2lkdGg6NzAlfSNjb21tZW50LWZvcm0gLmMtYXZhdGFye2JvcmRlci1yYWRpdXM6NHB4Oy1tb3otYm9yZGVyLXJhZGl1czo0cHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjRweDttYXJnaW4tdG9wOjZweDt3aWR0aDo1MHB4fSNjb21tZW50LWZvcm0gLnJlcGx5LW1ke21hcmdpbi1ib3R0b206MTZweDtmb250LXNpemU6MTJweDtsaW5lLWhlaWdodDoyMHB4O2NvbG9yOiM2NjZ9I2NvbW1lbnQtZm9ybSAuY2FuY2VsLXJlcGx5e2JvcmRlcjpub25lO21hcmdpbi1sZWZ0OjE4cHg7ZGlzcGxheTpub25lfSNjb21tZW50LWZvcm0gLmNhbmNlbC1yZXBseTpob3ZlcntjdXJzb3I6cG9pbnRlcn0jY29tbWVudC1jb250ZW50e3dpZHRoOjEwMCU7Ym94LXNpemluZzpib3JkZXItYm94O2hlaWdodDoxODBweDtyZXNpemU6bm9uZX1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6OTYwcHgpey5jb250YWluZXI5NjB7cGFkZGluZzowIDI0cHg7d2lkdGg6YXV0b319QG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjc2MHB4KXsuY29udGFpbmVyOTYwe3BhZGRpbmc6MCAyNHB4O3dpZHRoOmF1dG99I2FydGljbGUtY29udGFpbmVyIC5tYWlue21hcmdpbi1sZWZ0OjB9I2FydGljbGUtY29udGFpbmVyIC5tZXRhe2Rpc3BsYXk6bm9uZX0jYXJ0aWNsZS1jb250YWluZXIgLm1haW46YmVmb3Jle2Rpc3BsYXk6bm9uZX0jY29tbWVudC1mb3JtIC5jLWluZm8sI2NvbW1lbnQtZm9ybSAuYy1jb250ZW50e3dpZHRoOjEwMCU7ZmxvYXQ6bGVmdH0jY29tbWVudC1mb3JtIC5jLWluZm97dGV4dC1hbGlnbjpsZWZ0fSNuYXYsI2hlYWRlci1oe2xpbmUtaGVpZ2h0OjUwcHh9I2Zvb3RlciBzcGFue2Zsb2F0Om5vbmU7dGV4dC1hbGlnbjpjZW50ZXJ9I2FydGljbGUtcGFnZXJ7bWFyZ2luLWxlZnQ6MH19QG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjU2MHB4KXsuY29udGFpbmVyOTYwe3BhZGRpbmc6MDt3aWR0aDphdXRvfSNhcnRpY2xlLXBhZ2Vye21hcmdpbjowIDEycHh9I2hlYWRlci1oe21hcmdpbi1sZWZ0OjI0cHh9I2hlYWRlci1pbWd7ZGlzcGxheTpub25lfSNjb21tZW50LWZvcm17d2lkdGg6MTAwJX0jbmF2e2Zsb2F0OmxlZnQ7bWFyZ2luLWxlZnQ6MjRweH0jbmF2IGxpe21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjQ0cHh9I2Zvb3RlciBzcGFue2Zsb2F0Om5vbmU7ZGlzcGxheTpibG9ja319QG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjQ4MHB4KXsjaGVhZGVyLXN1YntkaXNwbGF5Om5vbmV9fVBLBwgVjEFXvCsAALwrAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABQAAABzdGF0aWNcY3NzXHNhYmVyLmNzc2JvZHksZGl2LGRsLGR0LGRkLHVsLG9sLGxpLGgxLGgyLGgzLGg0LGg1LGg2LHByZSxjb2RlLGZvcm0sZmllbGRzZXQsbGVnZW5kLGlucHV0LHRleHRhcmVhLHAsYmxvY2txdW90ZSx0aCx0ZHttYXJnaW46MDtwYWRkaW5nOjB9aGVhZGVyLGZvb3RlcixzZWN0aW9uLGFydGljbGUsYXNpZGUsbmF2LGhncm91cCxhZGRyZXNzLGZpZ3VyZSxmaWdjYXB0aW9uLG1lbnUsZGV0YWlsc3tkaXNwbGF5OmJsb2NrfWF1ZGlvLGNhbnZhcyx2aWRlb3tkaXNwbGF5OmlubGluZS1ibG9ja310YWJsZXtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Ym9yZGVyLXNwYWNpbmc6MH1maWVsZHNldCxpbWd7Ym9yZGVyOjB9YWRkcmVzcyxjYXB0aW9uLGNpdGUsY29kZSxkZm4sZW0sdGgsdmFye2ZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbH1vbCx1bHtsaXN0LXN0eWxlOm5vbmV9Y2FwdGlvbix0aHt0ZXh0LWFsaWduOmxlZnR9aDEsaDIsaDMsaDQsaDUsaDZ7Zm9udC1zaXplOjEwMCU7Zm9udC13ZWlnaHQ6bm9ybWFsfXE6YmVmb3JlLHE6YWZ0ZXJ7Y29udGVudDonJ31hYmJyLGFjcm9ueW17Ym9yZGVyOjA7Zm9udC12YXJpYW50Om5vcm1hbH1zdXB7dmVydGljYWwtYWxpZ246dGV4dC10b3B9c3Vie3ZlcnRpY2FsLWFsaWduOnRleHQtYm90dG9tfWlucHV0LHRleHRhcmVhLHNlbGVjdHtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZTppbmhlcml0O2ZvbnQtd2VpZ2h0OmluaGVyaXR9bGVnZW5ke2NvbG9yOiMwMDB9aHRtbCxib2R5e2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNHB4O2xpbmUtaGVpZ2h0OjMwcHg7Y29sb3I6IzMzMztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9YXt0ZXh0LWRlY29yYXRpb246bm9uZTtjb2xvcjojMDA3OWJjfWE6aG92ZXJ7Y29sb3I6IzAwNWI5Yn1we21hcmdpbi1ib3R0b206MThweH1oMSxoMixoMyxoNCxoNSxoNntwYWRkaW5nOjEycHggMH1oMXtmb250LXNpemU6MjhweH1oMntmb250LXNpemU6MjRweH1oM3tmb250LXNpemU6MjFweH1oNHtmb250LXNpemU6MTlweH1oNXtmb250LXNpemU6MTZweH1oNntmb250LXNpemU6MTRweH0udGV4dC1sZWZ0e3RleHQtYWxpZ246bGVmdH0udGV4dC1yaWdodHt0ZXh0LWFsaWduOnJpZ2h0fS50ZXh0LWNlbnRlcnt0ZXh0LWFsaWduOmNlbnRlcn0ubGVmdHtmbG9hdDpsZWZ0fS5yaWdodHtmbG9hdDpyaWdodH0uYWJzb2x1dGV7cG9zaXRpb246YWJzb2x1dGV9LnJlbGF0aXZle3Bvc2l0aW9uOnJlbGF0aXZlfS5jbGVhcjphZnRlcnt2aXNpYmlsaXR5OmhpZGRlbjtkaXNwbGF5OmJsb2NrO2ZvbnQtc2l6ZTowO2NvbnRlbnQ6IiAiO2NsZWFyOmJvdGg7aGVpZ2h0OjB9LnZlcnRpY2FsLW1pZGRsZXt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9LmlubGluZXtkaXNwbGF5OmlubGluZX0uaW5saW5lLWJsb2Nre2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5ibG9ja3tkaXNwbGF5OmJsb2NrfS5mYWRlLW91dHtvcGFjaXR5OjB9LmhpZGV7ZGlzcGxheTpub25lICFpbXBvcnRhbnR9LmNvbnRhaW5lcnttYXgtd2lkdGg6MTIwMHB4O21hcmdpbjphdXRvfS5jb250YWluZXI5NjB7bWF4LXdpZHRoOjk2MHB4O21hcmdpbjphdXRvfS5ncmlkLTEtMnt3aWR0aDo1MCV9LmdyaWQtMS0ze3dpZHRoOjMzLjMzMzMlfS5ncmlkLTEtNHt3aWR0aDoyNSV9LmdyaWQtMS01e3dpZHRoOjIwJX0uZ3JpZC0xLTZ7d2lkdGg6MTYuNjY2NiV9LmdyaWQtMi0ze3dpZHRoOjY2LjY2NjYlfS5ncmlkLTMtNHt3aWR0aDo3NSV9LmdyaWQtMy01e3dpZHRoOjYwJX0uZ3JpZC00LTV7d2lkdGg6ODAlfS5ncmlkLTUtNnt3aWR0aDo4My4zMzMzJX1pbnB1dCx0ZXh0YXJlYSxzZWxlY3QsYnV0dG9ue2ZvbnQtZmFtaWx5OlVidW50dSxDb25zb2xhcywiTWljcm9zb2Z0IFlhSGVpIixWZXJkYW5hLFRhaG9tYSxBcmlhbCxzYW5zLXNlcmlmfS5mb3JtIGxlZ2VuZHtmb250LXNpemU6MThweDttYXJnaW4tYm90dG9tOjE0cHh9LmZvcm0gbGFiZWx7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLmlwdHtwYWRkaW5nOjhweCAxMnB4O2JvcmRlcjoxcHggc29saWQgIzk5OTtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHg7b3V0bGluZTpub25lO21pbi13aWR0aDoxODBweH0uZm9ybSAuaXB0OmZvY3Vze2JvcmRlci1jb2xvcjojMDA3OWJjfS5mb3JtIC5jaGt7ZGlzcGxheTppbmxpbmUtYmxvY2s7bWFyZ2luOjJweCA2cHggMCAwO2xpbmUtaGVpZ2h0Om5vcm1hbH0uZm9ybSAuZmllbGR7bWFyZ2luLWJvdHRvbToyNHB4fS5mb3JtIC5pbnZhbGlke21hcmdpbi1yaWdodDoxMnB4fS5mb3JtIC50aXB7Zm9udC1zaXplOjEzcHg7Y29sb3I6Izk5OTttYXJnaW4tbGVmdDoxMnB4fS5mb3JtLXZlcnRpY2FsIGxhYmVse2Rpc3BsYXk6YmxvY2s7bWFyZ2luLWJvdHRvbTo4cHh9LmZvcm0tdmVydGljYWwgLmlwdHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveH0uZm9ybS12ZXJ0aWNhbCAuaW52YWxpZHttYXJnaW4tcmlnaHQ6MDttYXJnaW4tdG9wOjZweH0uZm9ybS1hbGlnbiBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttaW4td2lkdGg6NjBweDt0ZXh0LWFsaWduOnJpZ2h0fS5mb3JtLWFsaWduIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5idG57bWluLXdpZHRoOjEyMHB4O2hlaWdodDozNnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7Ym9yZGVyOm5vbmU7bWFyZ2luOjB9LmJ0bjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM5OTk7Y3Vyc29yOnBvaW50ZXJ9YS5idG57bGluZS1oZWlnaHQ6MzZweDtjb2xvcjojZmZmfS5idG4tcmVke2JhY2tncm91bmQtY29sb3I6I2U2NDM0Njtjb2xvcjojZmJmYmZifS5idG4tcmVkOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2M3MzgzYX0uYnRuLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9LmJ0bi1ibHVlOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzAwNWI5Yn0uYnRuLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifS5idG4tZ3JlZW46aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNjQ5NDYyfS5sYmx7cGFkZGluZzo0cHggMTJweDtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7Y29sb3I6IzMzMztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LmxibC1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9YS5sYmx7bGluZS1oZWlnaHQ6MjZweH1hLmxibC1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhO2NvbG9yOiNmYmZiZmJ9LmxibC1ibHVle2JhY2tncm91bmQtY29sb3I6IzAwNzliYztjb2xvcjojZmJmYmZifWEubGJsLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjliO2NvbG9yOiNmYmZiZmJ9LmxibC1ncmVlbntiYWNrZ3JvdW5kLWNvbG9yOiM3YWIyNzc7Y29sb3I6I2ZiZmJmYn1hLmxibC1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjI7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLml0ZW17cGFkZGluZzoycHggOHB4O21hcmdpbjowIDZweDtjb2xvcjojMzMzO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2xpbmUtaGVpZ2h0OjIwcHh9LnBhZ2VyIC5pdGVtIGF7Y29sb3I6IzMzM30ucGFnZXIgLml0ZW06aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLml0ZW06aG92ZXIgYXtjb2xvcjojZmZmfS5wYWdlciAuY3VycmVudHtiYWNrZ3JvdW5kLWNvbG9yOiM2NjY7Y29sb3I6I2ZiZmJmYjtib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9LnBhZ2VyIC5jdXJyZW50IGF7Y29sb3I6I2ZiZmJmYn0ucGFnZXIgLmN1cnJlbnQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjfS5tYXJrZG93biBoMSwubWFya2Rvd24gaDIsLm1hcmtkb3duIGgzLC5tYXJrZG93biBoNCwubWFya2Rvd24gaDUsLm1hcmtkb3duIGg2e3BhZGRpbmc6MThweCAwIDlweCAwO2ZvbnQtd2VpZ2h0OmJvbGR9Lm1hcmtkb3duIGgxe2ZvbnQtc2l6ZToyNHB4fS5tYXJrZG93biBoMntmb250LXNpemU6MjFweH0ubWFya2Rvd24gaDEsLm1hcmtkb3duIGgye21hcmdpbi1ib3R0b206MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfS5tYXJrZG93biBoM3tmb250LXNpemU6MTlweH0ubWFya2Rvd24gaDR7Zm9udC1zaXplOjE4cHh9Lm1hcmtkb3duIGg1e2ZvbnQtc2l6ZToxNnB4fS5tYXJrZG93biBoNntmb250LXNpemU6MTRweH0ubWFya2Rvd24gcHttYXJnaW4tYm90dG9tOjEwcHh9Lm1hcmtkb3duIHVse2xpc3Qtc3R5bGU6ZGlzYyBpbnNpZGV9Lm1hcmtkb3duIG9se2xpc3Qtc3R5bGU6ZGVjaW1hbCBpbnNpZGV9Lm1hcmtkb3duIGNvZGV7Zm9udC1mYW1pbHk6Q29uc29sYXMsIkNvdXJpZXIgTmV3IixBcmlhbH0ubWFya2Rvd24gcCBjb2Rle2NvbG9yOiNjNzM4M2F9Lm1hcmtkb3duIGJsb2NrcXVvdGV7cGFkZGluZzo4cHggMThweDtib3JkZXItbGVmdDo0cHggc29saWQgI2NjYztiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmJ9Lm1hcmtkb3duIGJsb2NrcXVvdGUgcHttYXJnaW4tYm90dG9tOjB9Lm1hcmtkb3duIHByZSBjb2Rle2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjE4cHggIWltcG9ydGFudDtwYWRkaW5nOjhweCAxOHB4O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjEycHggMCAxOHB4IDB9Lm1hcmtkb3duIG9sLC5tYXJrZG93biB1bHttYXJnaW46MTJweCAyNHB4fS5tYXJrZG93biBwIGltZ3ttYXgtd2lkdGg6OTklO2hlaWdodDphdXRvO21hcmdpbjowIGF1dG87ZGlzcGxheTpibG9ja30ubWFya2Rvd24gdGFibGV7bWFyZ2luOjEycHggMDt3aWR0aDo5OCV9Lm1hcmtkb3duIHRhYmxlIHRoLC5tYXJrZG93biB0YWJsZSB0ZHtib3JkZXI6MXB4IHNvbGlkICNjY2M7cGFkZGluZzo0cHggMTJweH0ubWFya2Rvd24gdGFibGUgdGhlYWR7YmFja2dyb3VuZDojZjZmNmY2fTo6LXdlYmtpdC1zY3JvbGxiYXJ7d2lkdGg6OHB4O21hcmdpbi1yaWdodDoycHh9Ojotd2Via2l0LXNjcm9sbGJhci10cmFjay1waWVjZXtiYWNrZ3JvdW5kLWNvbG9yOiNmNWY1ZjU7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkICNkMmQyZDJ9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYntiYWNrZ3JvdW5kOiM5ZmEwOWM7d2lkdGg6OHB4fTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXJ7YmFja2dyb3VuZDojYjdiOGFkfWh0bWwsYm9keXtiYWNrZ3JvdW5kOiNmOWY5Zjl9I2hlYWRlcntiYWNrZ3JvdW5kOiNmZmY7Ym94LXNoYWRvdzowIDAgNHB4ICM2NjY7bGluZS1oZWlnaHQ6NjBweDtwYWRkaW5nOjEycHggMCAxOHB4IDA7cG9zaXRpb246Zml4ZWQ7d2lkdGg6MTAwJTt0b3A6MDt6LWluZGV4Ojk5fSNoZWFkZXItaW1ne3dpZHRoOjYwcHg7aGVpZ2h0OjYwcHg7bWFyZ2luLXJpZ2h0OjI0cHg7Ym9yZGVyLXJhZGl1czozMHB4O3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0jaGVhZGVyLWgsI2hlYWRlci1zdWJ7cGFkZGluZzowIDE4cHggMCAwfSNoZWFkZXItc3Vie2ZvbnQtc2l6ZToxM3B4O2NvbG9yOiM5OTl9I25hdnttYXJnaW4tcmlnaHQ6LTE4cHh9I25hdiBsaSBhe21hcmdpbi1sZWZ0OjI0cHg7cGFkZGluZzowIDE4cHg7Zm9udC1zaXplOjE1cHh9I25hdiBsaSBhOmhvdmVye3BhZGRpbmc6NHB4IDEycHg7YmFja2dyb3VuZC1jb2xvcjojY2NjO2NvbG9yOiMzMzM7Ym9yZGVyLXJhZGl1czoycHg7LW1vei1ib3JkZXItcmFkaXVzOjJweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MnB4O2JhY2tncm91bmQtY29sb3I6IzAwNzliYztjb2xvcjojZmJmYmZiO3BhZGRpbmc6NnB4IDE4cHh9I2Zvb3RlcntwYWRkaW5nOjMwcHggNDBweDtjb2xvcjojOTk5fSNtYWlue21hcmdpbi10b3A6MTMycHg7bWFyZ2luLWJvdHRvbTo0OHB4fSNnby10b3B7Ym90dG9tOjUwcHg7cmlnaHQ6NDBweDtwb3NpdGlvbjpmaXhlZDtjb2xvcjojZmZmO3BhZGRpbmctdG9wOjZweDtwYWRkaW5nLWJvdHRvbTo4cHg7b3BhY2l0eTouNH0jYXJ0aWNsZS1jb250YWluZXIgYXJ0aWNsZXttYXJnaW4tYm90dG9tOjQwcHg7cGFkZGluZy1ib3R0b206NDBweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2JiYjttYXJnaW4tYm90dG9tOjUwcHh9I2FydGljbGUtY29udGFpbmVyIC50YWctYmFubmVye2ZvbnQtc2l6ZToxNnB4O21hcmdpbi1ib3R0b206MjBweDtwYWRkaW5nLWJvdHRvbToyMHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjYmJiO21hcmdpbi1ib3R0b206MjhweH0jYXJ0aWNsZS1jb250YWluZXIgLm1ldGEgLmNvbW1lbnRze21hcmdpbi1ib3R0b206MDttYXJnaW4tdG9wOjhweDttYXJnaW4tcmlnaHQ6MThweDtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmO3BhZGRpbmctYm90dG9tOjJweH0jYXJ0aWNsZS1jb250YWluZXIgLm1ldGEgLmNvbW1lbnRzIGF7Y29sb3I6I2ZmZjtmb250LXNpemU6MThweDtkaXNwbGF5OmJsb2NrO2N1cnNvcjpwb2ludGVyfSNhcnRpY2xlLWNvbnRhaW5lciAubWV0YSAudmlld3N7dG9wOi04cHg7bGVmdDotMTJweDtwYWRkaW5nOjJweCA2cHg7bGluZS1oZWlnaHQ6MjBweDt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXNpemU6MTJweDtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmO21hcmdpbi1ib3R0b206MH0jYXJ0aWNsZS1jb250YWluZXIgLnRpdGxle21hcmdpbi1ib3R0b206MjRweDtwYWRkaW5nLWJvdHRvbToyNHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkO2ZvbnQtc2l6ZToyNHB4fSNhcnRpY2xlLWNvbnRhaW5lciAuY29udGVudHttYXJnaW4tdG9wOi0xMnB4fSNhcnRpY2xlLWNvbnRhaW5lciAuaW5mb3ttYXJnaW4tYm90dG9tOjA7Y29sb3I6Izk5OTtmb250LXNpemU6MTJweH0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8gc3Bhbntib3JkZXItcmlnaHQ6MXB4IGRhc2hlZCAjOTk5O3BhZGRpbmctcmlnaHQ6MTJweDttYXJnaW4tcmlnaHQ6MTJweH0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8gLnRhZyBhe21hcmdpbi1sZWZ0OjRweH0jYXJ0aWNsZS1jb250YWluZXIgLmFydGljbGUtc2luZ2xlIGgzLnRpdGxle3BhZGRpbmctdG9wOjB9I2FydGljbGUtY29udGFpbmVyIC5hcnRpY2xlLXNpbmdsZSAudmlld3N7Y29sb3I6I2ZmZjtmb250LXNpemU6MThweH0jYXJ0aWNsZS1wYWdlciBhe21hcmdpbjowfSNhcnRpY2xlLXBhZ2VyIGE6aG92ZXJ7Y29sb3I6I2ZiZmJmYn0jYXJ0aWNsZS1zaWRlYmFyIC5zaWRlYmFye21hcmdpbi1ib3R0b206MjRweH0jYXJ0aWNsZS1zaWRlYmFyIC5zaWRlYmFyIC50aXRsZXtwYWRkaW5nLXRvcDowfSNwb3AtYXJ0aWNsZS1zaWRlYmFyIC5saXN0IGxpe21hcmdpbi1ib3R0b206OHB4O3BhZGRpbmctYm90dG9tOjhweDtib3JkZXItYm90dG9tOjFweCBkYXNoZWQgI2RkZH0jcG9wLWFydGljbGUtc2lkZWJhciAucG9wLW51bXtwYWRkaW5nOjRweDttYXJnaW4tbGVmdDoxMnB4O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWY7Zm9udC1zaXplOjEycHh9I3JlY2VudC1jb21tZW50LXNpZGViYXIgLmxpc3QgbGl7bWFyZ2luLWJvdHRvbTo4cHg7cGFkZGluZy1ib3R0b206OHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfSNyZWNlbnQtY29tbWVudC1zaWRlYmFyIC5hdXRob3J7cGFkZGluZzo0cHggNnB4O21hcmdpbi1yaWdodDo2cHh9I2NvbW1lbnQgaDR7cGFkZGluZy10b3A6MH0jY29tbWVudCAuY29tbWVudHMgYXtjb2xvcjojZmZmO2ZvbnQtc2l6ZToxOHB4fSNjb21tZW50LWxpc3QgLmNvbW1lbnR7bWFyZ2luLWJvdHRvbTozMnB4fSNjb21tZW50LWxpc3QgLmMtYXZhdGFye21hcmdpbi1yaWdodDoxOHB4O2JvcmRlci1yYWRpdXM6NHB4Oy1tb3otYm9yZGVyLXJhZGl1czo0cHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjRweDttYXJnaW4tdG9wOjZweH0jY29tbWVudC1saXN0IC5jLW1ldGEgcHttYXJnaW4tYm90dG9tOjB9I2NvbW1lbnQtbGlzdCAuYy1tZXRhIC5jLXRpbWV7Y29sb3I6Izk5OTtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNjb21tZW50LWxpc3QgLmMtbWV0YSAuYy1hdXRob3J7Zm9udC1zaXplOjE2cHg7Y29sb3I6IzMzMztkaXNwbGF5OmJsb2NrfSNjb21tZW50LWxpc3QgLmMtbWV0YSAuYy1hdXRob3I6aG92ZXJ7Y29sb3I6IzAwNWI5Yn0jY29tbWVudC1saXN0IC5jLW1ldGEgLmMtcmVwbHl7Y29sb3I6I2ZmZjtiYWNrZ3JvdW5kOiNkZGQ7cGFkZGluZzozcHggMTBweH0jY29tbWVudC1saXN0IC5jLW1ldGEgLmMtcmVwbHk6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjfSNjb21tZW50LWxpc3QgLmMtY29udGVudHtwYWRkaW5nLXRvcDo0cHh9I2NvbW1lbnQtbGlzdCAuYy1jaGVja3tmb250LXNpemU6MTNweDtjb2xvcjojZTY0MzQ2O21hcmdpbi1sZWZ0OjEycHh9I2NvbW1lbnQtbGlzdCAuYy1wLW1ke21hcmdpbi10b3A6MTJweDtmb250LXNpemU6MTJweDtsaW5lLWhlaWdodDoyMHB4O2NvbG9yOiM2NjZ9I2NvbW1lbnQtc2hvd3ttYXJnaW4tYm90dG9tOjMycHh9I2NvbW1lbnQtdGl0bGV7bWFyZ2luLWJvdHRvbToyMHB4O3BhZGRpbmctYm90dG9tOjIwcHg7Ym9yZGVyLWJvdHRvbToxcHggZGFzaGVkICNkZGR9I2NvbW1lbnQtZm9ybXt3aWR0aDo4MCU7bWFyZ2luOmF1dG87bWFyZ2luLWJvdHRvbTozMHB4fSNjb21tZW50LWZvcm0gLmMtaW5mb3t3aWR0aDoyNiV9I2NvbW1lbnQtZm9ybSAuYy1pbmZvIC5pcHR7d2lkdGg6MTAwJTtib3gtc2l6aW5nOmJvcmRlci1ib3g7bWluLXdpZHRoOjB9I2NvbW1lbnQtZm9ybSAuYy1jb250ZW50e3dpZHRoOjcwJX0jY29tbWVudC1mb3JtIC5jLWF2YXRhcntib3JkZXItcmFkaXVzOjRweDstbW96LWJvcmRlci1yYWRpdXM6NHB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czo0cHg7bWFyZ2luLXRvcDo2cHg7d2lkdGg6NTBweH0jY29tbWVudC1mb3JtIC5yZXBseS1tZHttYXJnaW4tYm90dG9tOjE2cHg7Zm9udC1zaXplOjEycHg7bGluZS1oZWlnaHQ6MjBweDtjb2xvcjojNjY2fSNjb21tZW50LWZvcm0gLmNhbmNlbC1yZXBseXtib3JkZXI6bm9uZTttYXJnaW4tbGVmdDoxOHB4O2Rpc3BsYXk6bm9uZX0jY29tbWVudC1mb3JtIC5jYW5jZWwtcmVwbHk6aG92ZXJ7Y3Vyc29yOnBvaW50ZXJ9I2NvbW1lbnQtY29udGVudHt3aWR0aDoxMDAlO2JveC1zaXppbmc6Ym9yZGVyLWJveDtoZWlnaHQ6MTgwcHg7cmVzaXplOm5vbmV9QG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjEyNDhweCl7LmNvbnRhaW5lcntwYWRkaW5nOjAgMjRweDt3aWR0aDphdXRvfX1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6OTYwcHgpey5jb250YWluZXI5NjB7cGFkZGluZzowIDI0cHg7d2lkdGg6YXV0b30jYXJ0aWNsZS1jb250YWluZXIubGVmdHt3aWR0aDoxMDAlfSNhcnRpY2xlLXNpZGViYXJ7ZGlzcGxheTpub25lfX1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6NzYwcHgpeyNoZWFkZXItc3Vie2Rpc3BsYXk6bm9uZX0jaGVhZGVye3BhZGRpbmc6MTJweCAwfSNhcnRpY2xlLWNvbnRhaW5lciAubWFpbnttYXJnaW4tbGVmdDowfSNhcnRpY2xlLWNvbnRhaW5lciAubWV0YXtkaXNwbGF5Om5vbmV9I2FydGljbGUtY29udGFpbmVyIC5tYWluOmJlZm9yZXtkaXNwbGF5Om5vbmV9I2NvbW1lbnQtZm9ybSAuYy1pbmZvLCNjb21tZW50LWZvcm0gLmMtY29udGVudHt3aWR0aDoxMDAlO2Zsb2F0OmxlZnR9I2NvbW1lbnQtZm9ybSAuYy1pbmZve3RleHQtYWxpZ246bGVmdH0jZm9vdGVyIHNwYW57ZGlzcGxheTpibG9jaztmbG9hdDpub25lO3RleHQtYWxpZ246Y2VudGVyfSNhcnRpY2xlLXBhZ2Vye21hcmdpbi1sZWZ0OjB9fUBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDo1NjBweCl7I2FydGljbGUtY29udGFpbmVyIC52aWV3c3tkaXNwbGF5Om5vbmV9fVBLBwhas8hZGigAABooAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABYAAABzdGF0aWNcY3NzXHNpdGVtYXAueHNsPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjx4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIyLjAiIA0KICAgICAgICAgICAgICAgIHhtbG5zOmh0bWw9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAiDQogICAgICAgICAgICAgICAgeG1sbnM6c2l0ZW1hcD0iaHR0cDovL3d3dy5zaXRlbWFwcy5vcmcvc2NoZW1hcy9zaXRlbWFwLzAuOSINCiAgICAgICAgICAgICAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSI+DQoJPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCIgaW5kZW50PSJ5ZXMiLz4NCgk8eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4NCgkJPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPg0KCQkJPGhlYWQ+DQoJCQkJPHRpdGxlPlhNTCBTaXRlbWFwPC90aXRsZT4NCgkJCQk8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIgLz4NCgkJCQk8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCQkJCQlib2R5IHsNCgkJCQkJCWZvbnQtZmFtaWx5OiJMdWNpZGEgR3JhbmRlIiwiTHVjaWRhIFNhbnMgVW5pY29kZSIsVGFob21hLFZlcmRhbmE7DQoJCQkJCQlmb250LXNpemU6MTNweDsNCgkJCQkJfQ0KCQkJCQkNCgkJCQkJI2ludHJvIHsNCgkJCQkJCWJhY2tncm91bmQtY29sb3I6I0NGRUJGNzsNCgkJCQkJCWJvcmRlcjoxcHggIzI1ODBCMiBzb2xpZDsNCgkJCQkJCXBhZGRpbmc6NXB4IDEzcHggNXB4IDEzcHg7DQoJCQkJCQltYXJnaW46MTBweDsNCgkJCQkJfQ0KCQkJCQkNCgkJCQkJI2ludHJvIHAgew0KCQkJCQkJbGluZS1oZWlnaHQ6CTE2Ljg2NjdweDsNCgkJCQkJfQ0KCQkJCQkNCgkJCQkJdGQgew0KCQkJCQkJZm9udC1zaXplOjExcHg7DQoJCQkJCX0NCgkJCQkJDQoJCQkJCXRoIHsNCgkJCQkJCXRleHQtYWxpZ246bGVmdDsNCgkJCQkJCXBhZGRpbmctcmlnaHQ6MzBweDsNCgkJCQkJCWZvbnQtc2l6ZToxMXB4Ow0KCQkJCQl9DQoJCQkJCQ0KCQkJCQl0ci5oaWdoIHsNCgkJCQkJCWJhY2tncm91bmQtY29sb3I6d2hpdGVzbW9rZTsNCgkJCQkJfQ0KCQkJCQkNCgkJCQkJI2Zvb3RlciB7DQoJCQkJCQlwYWRkaW5nOjJweDsNCgkJCQkJCW1hcmdpbjoxMHB4Ow0KCQkJCQkJZm9udC1zaXplOjhwdDsNCgkJCQkJCWNvbG9yOmdyYXk7DQoJCQkJCX0NCgkJCQkJDQoJCQkJCSNmb290ZXIgYSB7DQoJCQkJCQljb2xvcjpncmF5Ow0KCQkJCQl9DQoJCQkJCQ0KCQkJCQlhIHsNCgkJCQkJCWNvbG9yOmJsYWNrOw0KCQkJCQl9DQoJCQkJPC9zdHlsZT4NCgkJCTwvaGVhZD4NCgkJCTxib2R5Pg0KCQkJCTxoMT5YTUwgU2l0ZW1hcDwvaDE+DQoJCQkJPGRpdiBpZD0iaW50cm8iPg0KCQkJCQk8cD4NCgkJCQkJCVRoaXMgaXMgYSBYTUwgU2l0ZW1hcCB3aGljaCBpcyBzdXBwb3NlZCB0byBiZSBwcm9jZXNzZWQgYnkgc2VhcmNoIGVuZ2luZXMgbGlrZSA8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5jb20iPkdvb2dsZTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly9zZWFyY2gubXNuLmNvbSI+TVNOIFNlYXJjaDwvYT4gYW5kIDxhIGhyZWY9Imh0dHA6Ly93d3cueWFob28uY29tIj5ZQUhPTzwvYT4uPGJyIC8+DQoJCQkJCQk8IS0tSXQgd2FzIGdlbmVyYXRlZCB1c2luZyB0aGUgQmxvZ2dpbmctU29mdHdhcmUgPGEgaHJlZj0iaHR0cDovL3dvcmRwcmVzcy5vcmcvIj5Xb3JkUHJlc3M8L2E+IGFuZCB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy5hcm5lYnJhY2hob2xkLmRlL3JlZGlyL3NpdGVtYXAtaG9tZS8iIHRpdGxlPSJHb29nbGUgU2l0ZW1hcCBHZW5lcmF0b3IgUGx1Z2luIGZvciBXb3JkUHJlc3MiPkdvb2dsZSBTaXRlbWFwIEdlbmVyYXRvciBQbHVnaW48L2E+IGJ5IDxhIGhyZWY9Imh0dHA6Ly93d3cuYXJuZWJyYWNoaG9sZC5kZS8iPkFybmUgQnJhY2hob2xkPC9hPi48YnIgLz4tLT4NCgkJCQkJCVlvdSBjYW4gZmluZCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFhNTCBzaXRlbWFwcyBvbiA8YSBocmVmPSJodHRwOi8vc2l0ZW1hcHMub3JnIj5zaXRlbWFwcy5vcmc8L2E+IGFuZCBHb29nbGUncyA8YSBocmVmPSJodHRwOi8vY29kZS5nb29nbGUuY29tL3NtX3RoaXJkcGFydHkuaHRtbCI+bGlzdCBvZiBzaXRlbWFwIHByb2dyYW1zPC9hPi4NCgkJCQkJPC9wPg0KCQkJCTwvZGl2Pg0KCQkJCTxkaXYgaWQ9ImNvbnRlbnQiPg0KCQkJCQk8dGFibGUgY2VsbHBhZGRpbmc9IjUiPg0KCQkJCQkJPHRyIHN0eWxlPSJib3JkZXItYm90dG9tOjFweCBibGFjayBzb2xpZDsiPg0KCQkJCQkJCTx0aD5VUkw8L3RoPg0KCQkJCQkJCTx0aD5Qcmlvcml0eTwvdGg+DQoJCQkJCQkJPHRoPkNoYW5nZSBGcmVxdWVuY3k8L3RoPg0KCQkJCQkJCTx0aD5MYXN0Q2hhbmdlIChHTVQpPC90aD4NCgkJCQkJCTwvdHI+DQoJCQkJCQk8eHNsOnZhcmlhYmxlIG5hbWU9Imxvd2VyIiBzZWxlY3Q9IidhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiciLz4NCgkJCQkJCTx4c2w6dmFyaWFibGUgbmFtZT0idXBwZXIiIHNlbGVjdD0iJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaJyIvPg0KCQkJCQkJPHhzbDpmb3ItZWFjaCBzZWxlY3Q9InNpdGVtYXA6dXJsc2V0L3NpdGVtYXA6dXJsIj4NCgkJCQkJCQk8dHI+DQoJCQkJCQkJCTx4c2w6aWYgdGVzdD0icG9zaXRpb24oKSBtb2QgMiAhPSAxIj4NCgkJCQkJCQkJCTx4c2w6YXR0cmlidXRlICBuYW1lPSJjbGFzcyI+aGlnaDwveHNsOmF0dHJpYnV0ZT4NCgkJCQkJCQkJPC94c2w6aWY+DQoJCQkJCQkJCTx0ZD4NCgkJCQkJCQkJCTx4c2w6dmFyaWFibGUgbmFtZT0iaXRlbVVSTCI+DQoJCQkJCQkJCQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNpdGVtYXA6bG9jIi8+DQoJCQkJCQkJCQk8L3hzbDp2YXJpYWJsZT4NCgkJCQkJCQkJCTxhIGhyZWY9InskaXRlbVVSTH0iPg0KCQkJCQkJCQkJCTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzaXRlbWFwOmxvYyIvPg0KCQkJCQkJCQkJPC9hPg0KCQkJCQkJCQk8L3RkPg0KCQkJCQkJCQk8dGQ+DQoJCQkJCQkJCQk8eHNsOnZhbHVlLW9mIHNlbGVjdD0iY29uY2F0KHNpdGVtYXA6cHJpb3JpdHkqMTAwLCclJykiLz4NCgkJCQkJCQkJPC90ZD4NCgkJCQkJCQkJPHRkPg0KCQkJCQkJCQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9ImNvbmNhdCh0cmFuc2xhdGUoc3Vic3RyaW5nKHNpdGVtYXA6Y2hhbmdlZnJlcSwgMSwgMSksY29uY2F0KCRsb3dlciwgJHVwcGVyKSxjb25jYXQoJHVwcGVyLCAkbG93ZXIpKSxzdWJzdHJpbmcoc2l0ZW1hcDpjaGFuZ2VmcmVxLCAyKSkiLz4NCgkJCQkJCQkJPC90ZD4NCgkJCQkJCQkJPHRkPg0KCQkJCQkJCQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9ImNvbmNhdChzdWJzdHJpbmcoc2l0ZW1hcDpsYXN0bW9kLDAsMTEpLGNvbmNhdCgnICcsIHN1YnN0cmluZyhzaXRlbWFwOmxhc3Rtb2QsMTIsNSkpKSIvPg0KCQkJCQkJCQk8L3RkPg0KCQkJCQkJCTwvdHI+DQoJCQkJCQk8L3hzbDpmb3ItZWFjaD4NCgkJCQkJPC90YWJsZT4NCgkJCQk8L2Rpdj4NCgkJCQk8ZGl2IGlkPSJmb290ZXIiPg0KCQkJCQlHZW5lcmF0ZWQgd2l0aCA8YSBocmVmPSJodHRwOi8vd3d3LmFybmVicmFjaGhvbGQuZGUvcmVkaXIvc2l0ZW1hcC1ob21lLyIgdGl0bGU9Ikdvb2dsZSBTaXRlbWFwIEdlbmVyYXRvciBQbHVnaW4gZm9yIFdvcmRQcmVzcyI+R29vZ2xlIFNpdGVtYXAgR2VuZXJhdG9yIFBsdWdpbiBmb3IgV29yZFByZXNzPC9hPiBieSA8YSBocmVmPSJodHRwOi8vd3d3LmFybmVicmFjaGhvbGQuZGUvIj5Bcm5lIEJyYWNoaG9sZDwvYT4uIFRoaXMgWFNMVCB0ZW1wbGF0ZSBpcyByZWxlYXNlZCB1bmRlciBHUEwuDQoJCQkJPC9kaXY+DQoJCQk8L2JvZHk+DQoJCTwvaHRtbD4NCgk8L3hzbDp0ZW1wbGF0ZT4NCjwveHNsOnN0eWxlc2hlZXQ+UEsHCItTeJ5FDwAARQ8AAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAHN0YXRpY1xjc3Ncc3R5bGUuY3NzYm9keSxkaXYsZGwsZHQsZGQsdWwsb2wsbGksaDEsaDIsaDMsaDQsaDUsaDYscHJlLGNvZGUsZm9ybSxmaWVsZHNldCxsZWdlbmQsaW5wdXQsdGV4dGFyZWEscCxibG9ja3F1b3RlLHRoLHRke21hcmdpbjowO3BhZGRpbmc6MH1oZWFkZXIsZm9vdGVyLHNlY3Rpb24sYXJ0aWNsZSxhc2lkZSxuYXYsaGdyb3VwLGFkZHJlc3MsZmlndXJlLGZpZ2NhcHRpb24sbWVudSxkZXRhaWxze2Rpc3BsYXk6YmxvY2t9YXVkaW8sY2FudmFzLHZpZGVve2Rpc3BsYXk6aW5saW5lLWJsb2NrfXRhYmxle2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowfWZpZWxkc2V0LGltZ3tib3JkZXI6MH1hZGRyZXNzLGNhcHRpb24sY2l0ZSxjb2RlLGRmbixlbSx0aCx2YXJ7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsfW9sLHVse2xpc3Qtc3R5bGU6bm9uZX1jYXB0aW9uLHRoe3RleHQtYWxpZ246bGVmdH1oMSxoMixoMyxoNCxoNSxoNntmb250LXNpemU6MTAwJTtmb250LXdlaWdodDpub3JtYWx9cTpiZWZvcmUscTphZnRlcntjb250ZW50OicnfWFiYnIsYWNyb255bXtib3JkZXI6MDtmb250LXZhcmlhbnQ6bm9ybWFsfXN1cHt2ZXJ0aWNhbC1hbGlnbjp0ZXh0LXRvcH1zdWJ7dmVydGljYWwtYWxpZ246dGV4dC1ib3R0b219aW5wdXQsdGV4dGFyZWEsc2VsZWN0e2ZvbnQtZmFtaWx5OmluaGVyaXQ7Zm9udC1zaXplOmluaGVyaXQ7Zm9udC13ZWlnaHQ6aW5oZXJpdH1sZWdlbmR7Y29sb3I6IzAwMH1odG1sLGJvZHl7Zm9udC1mYW1pbHk6VWJ1bnR1LENvbnNvbGFzLCJNaWNyb3NvZnQgWWFIZWkiLFZlcmRhbmEsVGFob21hLEFyaWFsLHNhbnMtc2VyaWY7Zm9udC1zaXplOjE0cHg7bGluZS1oZWlnaHQ6MzBweDtjb2xvcjojMzMzO2JhY2tncm91bmQtY29sb3I6I2ZiZmJmYn1he3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOiMwMDc5YmN9YTpob3Zlcntjb2xvcjojMDA1YjlifXB7bWFyZ2luLWJvdHRvbToxOHB4fWgxLGgyLGgzLGg0LGg1LGg2e3BhZGRpbmc6MTJweCAwfWgxe2ZvbnQtc2l6ZToyOHB4fWgye2ZvbnQtc2l6ZToyNHB4fWgze2ZvbnQtc2l6ZToyMXB4fWg0e2ZvbnQtc2l6ZToxOXB4fWg1e2ZvbnQtc2l6ZToxNnB4fWg2e2ZvbnQtc2l6ZToxNHB4fS50ZXh0LWxlZnR7dGV4dC1hbGlnbjpsZWZ0fS50ZXh0LXJpZ2h0e3RleHQtYWxpZ246cmlnaHR9LnRleHQtY2VudGVye3RleHQtYWxpZ246Y2VudGVyfS5sZWZ0e2Zsb2F0OmxlZnR9LnJpZ2h0e2Zsb2F0OnJpZ2h0fS5hYnNvbHV0ZXtwb3NpdGlvbjphYnNvbHV0ZX0ucmVsYXRpdmV7cG9zaXRpb246cmVsYXRpdmV9LmNsZWFyOmFmdGVye3Zpc2liaWxpdHk6aGlkZGVuO2Rpc3BsYXk6YmxvY2s7Zm9udC1zaXplOjA7Y29udGVudDoiICI7Y2xlYXI6Ym90aDtoZWlnaHQ6MH0udmVydGljYWwtbWlkZGxle3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0uaW5saW5le2Rpc3BsYXk6aW5saW5lfS5pbmxpbmUtYmxvY2t7ZGlzcGxheTppbmxpbmUtYmxvY2t9LmJsb2Nre2Rpc3BsYXk6YmxvY2t9LmZhZGUtb3V0e29wYWNpdHk6MH0uaGlkZXtkaXNwbGF5Om5vbmUgIWltcG9ydGFudH0uY29udGFpbmVye21heC13aWR0aDoxMjAwcHg7bWFyZ2luOmF1dG99LmNvbnRhaW5lcjk2MHttYXgtd2lkdGg6OTYwcHg7bWFyZ2luOmF1dG99LmdyaWQtMS0ye3dpZHRoOjUwJX0uZ3JpZC0xLTN7d2lkdGg6MzMuMzMzMyV9LmdyaWQtMS00e3dpZHRoOjI1JX0uZ3JpZC0xLTV7d2lkdGg6MjAlfS5ncmlkLTEtNnt3aWR0aDoxNi42NjY2JX0uZ3JpZC0yLTN7d2lkdGg6NjYuNjY2NiV9LmdyaWQtMy00e3dpZHRoOjc1JX0uZ3JpZC0zLTV7d2lkdGg6NjAlfS5ncmlkLTQtNXt3aWR0aDo4MCV9LmdyaWQtNS02e3dpZHRoOjgzLjMzMzMlfWlucHV0LHRleHRhcmVhLHNlbGVjdCxidXR0b257Zm9udC1mYW1pbHk6VWJ1bnR1LENvbnNvbGFzLCJNaWNyb3NvZnQgWWFIZWkiLFZlcmRhbmEsVGFob21hLEFyaWFsLHNhbnMtc2VyaWZ9LmZvcm0gbGVnZW5ke2ZvbnQtc2l6ZToxOHB4O21hcmdpbi1ib3R0b206MTRweH0uZm9ybSBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW4tcmlnaHQ6MTJweH0uZm9ybSAuaXB0e3BhZGRpbmc6OHB4IDEycHg7Ym9yZGVyOjFweCBzb2xpZCAjOTk5O2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtvdXRsaW5lOm5vbmU7bWluLXdpZHRoOjE4MHB4fS5mb3JtIC5pcHQ6Zm9jdXN7Ym9yZGVyLWNvbG9yOiMwMDc5YmN9LmZvcm0gLmNoa3tkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW46MnB4IDZweCAwIDA7bGluZS1oZWlnaHQ6bm9ybWFsfS5mb3JtIC5maWVsZHttYXJnaW4tYm90dG9tOjI0cHh9LmZvcm0gLmludmFsaWR7bWFyZ2luLXJpZ2h0OjEycHh9LmZvcm0gLnRpcHtmb250LXNpemU6MTNweDtjb2xvcjojOTk5O21hcmdpbi1sZWZ0OjEycHh9LmZvcm0tdmVydGljYWwgbGFiZWx7ZGlzcGxheTpibG9jazttYXJnaW4tYm90dG9tOjhweH0uZm9ybS12ZXJ0aWNhbCAuaXB0e3dpZHRoOjEwMCU7Ym94LXNpemluZzpib3JkZXItYm94fS5mb3JtLXZlcnRpY2FsIC5pbnZhbGlke21hcmdpbi1yaWdodDowO21hcmdpbi10b3A6NnB4fS5mb3JtLWFsaWduIGxhYmVse2Rpc3BsYXk6aW5saW5lLWJsb2NrO21pbi13aWR0aDo2MHB4O3RleHQtYWxpZ246cmlnaHR9LmZvcm0tYWxpZ24gLmludmFsaWR7bWFyZ2luLXJpZ2h0OjA7bWFyZ2luLXRvcDo2cHh9LmJ0bnttaW4td2lkdGg6MTIwcHg7aGVpZ2h0OjM2cHg7YmFja2dyb3VuZC1jb2xvcjojY2NjO2NvbG9yOiMzMzM7Ym9yZGVyLXJhZGl1czoycHg7LW1vei1ib3JkZXItcmFkaXVzOjJweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MnB4O291dGxpbmU6bm9uZTtib3JkZXI6bm9uZTttYXJnaW46MH0uYnRuOmhvdmVye2JhY2tncm91bmQtY29sb3I6Izk5OTtjdXJzb3I6cG9pbnRlcn1hLmJ0bntsaW5lLWhlaWdodDozNnB4O2NvbG9yOiNmZmZ9LmJ0bi1yZWR7YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9LmJ0bi1yZWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzczODNhfS5idG4tYmx1ZXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmM7Y29sb3I6I2ZiZmJmYn0uYnRuLWJsdWU6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA1YjlifS5idG4tZ3JlZW57YmFja2dyb3VuZC1jb2xvcjojN2FiMjc3O2NvbG9yOiNmYmZiZmJ9LmJ0bi1ncmVlbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiM2NDk0NjJ9LmxibHtwYWRkaW5nOjRweCAxMnB4O2JhY2tncm91bmQtY29sb3I6I2NjYztjb2xvcjojMzMzO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ubGJsLXJlZHtiYWNrZ3JvdW5kLWNvbG9yOiNlNjQzNDY7Y29sb3I6I2ZiZmJmYn1hLmxibHtsaW5lLWhlaWdodDoyNnB4fWEubGJsLXJlZDpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiNjNzM4M2E7Y29sb3I6I2ZiZmJmYn0ubGJsLWJsdWV7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9YS5sYmwtYmx1ZTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDViOWI7Y29sb3I6I2ZiZmJmYn0ubGJsLWdyZWVue2JhY2tncm91bmQtY29sb3I6IzdhYjI3Nztjb2xvcjojZmJmYmZifWEubGJsLWdyZWVuOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzY0OTQ2Mjtjb2xvcjojZmJmYmZifS5wYWdlciAuaXRlbXtwYWRkaW5nOjJweCA4cHg7bWFyZ2luOjAgNnB4O2NvbG9yOiMzMzM7ZGlzcGxheTppbmxpbmUtYmxvY2s7bGluZS1oZWlnaHQ6MjBweH0ucGFnZXIgLml0ZW0gYXtjb2xvcjojMzMzfS5wYWdlciAuaXRlbTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmM7Ym9yZGVyLXJhZGl1czoycHg7LW1vei1ib3JkZXItcmFkaXVzOjJweDstd2Via2l0LWJvcmRlci1yYWRpdXM6MnB4fS5wYWdlciAuaXRlbTpob3ZlciBhe2NvbG9yOiNmZmZ9LnBhZ2VyIC5jdXJyZW50e2JhY2tncm91bmQtY29sb3I6IzY2Njtjb2xvcjojZmJmYmZiO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweH0ucGFnZXIgLmN1cnJlbnQgYXtjb2xvcjojZmJmYmZifS5wYWdlciAuY3VycmVudDpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiMwMDc5YmN9Lm1hcmtkb3duIGgxLC5tYXJrZG93biBoMiwubWFya2Rvd24gaDMsLm1hcmtkb3duIGg0LC5tYXJrZG93biBoNSwubWFya2Rvd24gaDZ7cGFkZGluZzoxOHB4IDAgOXB4IDA7Zm9udC13ZWlnaHQ6Ym9sZH0ubWFya2Rvd24gaDF7Zm9udC1zaXplOjI0cHh9Lm1hcmtkb3duIGgye2ZvbnQtc2l6ZToyMXB4fS5tYXJrZG93biBoMSwubWFya2Rvd24gaDJ7bWFyZ2luLWJvdHRvbToxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7Ym9yZGVyLWJvdHRvbToxcHggZGFzaGVkICNkZGR9Lm1hcmtkb3duIGgze2ZvbnQtc2l6ZToxOXB4fS5tYXJrZG93biBoNHtmb250LXNpemU6MThweH0ubWFya2Rvd24gaDV7Zm9udC1zaXplOjE2cHh9Lm1hcmtkb3duIGg2e2ZvbnQtc2l6ZToxNHB4fS5tYXJrZG93biBwe21hcmdpbi1ib3R0b206MTBweH0ubWFya2Rvd24gdWx7bGlzdC1zdHlsZTpkaXNjIGluc2lkZX0ubWFya2Rvd24gb2x7bGlzdC1zdHlsZTpkZWNpbWFsIGluc2lkZX0ubWFya2Rvd24gY29kZXtmb250LWZhbWlseTpDb25zb2xhcywiQ291cmllciBOZXciLEFyaWFsfS5tYXJrZG93biBwIGNvZGV7Y29sb3I6I2M3MzgzYX0ubWFya2Rvd24gYmxvY2txdW90ZXtwYWRkaW5nOjhweCAxOHB4O2JvcmRlci1sZWZ0OjRweCBzb2xpZCAjY2NjO2JhY2tncm91bmQtY29sb3I6I2ZiZmJmYn0ubWFya2Rvd24gYmxvY2txdW90ZSBwe21hcmdpbi1ib3R0b206MH0ubWFya2Rvd24gcHJlIGNvZGV7Zm9udC1zaXplOjEycHg7bGluZS1oZWlnaHQ6MThweCAhaW1wb3J0YW50O3BhZGRpbmc6OHB4IDE4cHg7ZGlzcGxheTpibG9jazttYXJnaW46MTJweCAwIDE4cHggMH0ubWFya2Rvd24gb2wsLm1hcmtkb3duIHVse21hcmdpbjoxMnB4IDI0cHh9Lm1hcmtkb3duIHAgaW1ne21heC13aWR0aDo5OSU7aGVpZ2h0OmF1dG87bWFyZ2luOjAgYXV0bztkaXNwbGF5OmJsb2NrfS5tYXJrZG93biB0YWJsZXttYXJnaW46MTJweCAwO3dpZHRoOjk4JX0ubWFya2Rvd24gdGFibGUgdGgsLm1hcmtkb3duIHRhYmxlIHRke2JvcmRlcjoxcHggc29saWQgI2NjYztwYWRkaW5nOjRweCAxMnB4fS5tYXJrZG93biB0YWJsZSB0aGVhZHtiYWNrZ3JvdW5kOiNmNmY2ZjZ9Ojotd2Via2l0LXNjcm9sbGJhcnt3aWR0aDo4cHg7bWFyZ2luLXJpZ2h0OjJweH06Oi13ZWJraXQtc2Nyb2xsYmFyLXRyYWNrLXBpZWNle2JhY2tncm91bmQtY29sb3I6I2Y1ZjVmNTtib3JkZXItbGVmdDoxcHggc29saWQgI2QyZDJkMn06Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1ie2JhY2tncm91bmQ6IzlmYTA5Yzt3aWR0aDo4cHh9Ojotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlcntiYWNrZ3JvdW5kOiNiN2I4YWR9aHRtbCxib2R5e2JhY2tncm91bmQ6dXJsKCIuLi9pbWcvYmcucG5nIikgcmVwZWF0fSNoZWFkZXJ7YmFja2dyb3VuZDp1cmwoIi4uL2ltZy9oZWFkZXIuZ2lmIikgcmVwZWF0ICM0YzcyOTg7bWluLXdpZHRoOjEyMHB4O3BhZGRpbmc6MzBweCAwO2NvbG9yOiNmYmZiZmJ9I2hlYWRlci1pbWd7d2lkdGg6OTZweDtoZWlnaHQ6OTZweDtiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7Ym9yZGVyOjFweCBzb2xpZCAjY2NjO2JvcmRlci1yYWRpdXM6NTBweDstbW96LWJvcmRlci1yYWRpdXM6NTBweDstd2Via2l0LWJvcmRlci1yYWRpdXM6NTBweH0jaGVhZGVyLWh7cGFkZGluZy10b3A6MjRweDtmb250LXNpemU6MzJweH0jaGVhZGVyLWggYXtjb2xvcjojZmZmO2ZvbnQtd2VpZ2h0OmJvbGR9I25hdntoZWlnaHQ6NTRweDtiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmI7Ym94LXNoYWRvdzowIDAgMnB4ICNiYmI7LW1vei1ib3gtc2hhZG93OjAgMCAycHggI2JiYjstd2Via2l0LWJveC1zaGFkb3c6MCAwIDJweCAjYmJiO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNjY2N9I25hdiBsaXtsaW5lLWhlaWdodDo1MHB4O3BhZGRpbmc6MCAxOHB4fSNuYXYgbGkgYXtmb250LXNpemU6MTZweDtjb2xvcjojMzMzO3BhZGRpbmc6MCAzMnB4O2Rpc3BsYXk6YmxvY2t9I25hdiBsaSBhOmhvdmVye2JvcmRlci1ib3R0b206NHB4IHNvbGlkICMwMDc5YmN9I25hdi5maXhlZHtwb3NpdGlvbjpmaXhlZDt3aWR0aDoxMDAlO3RvcDowfSNtYWlue21hcmdpbjozMHB4IGF1dG99I2Zvb3Rlcntjb2xvcjojY2NjO2JhY2tncm91bmQtY29sb3I6IzFjMjQyOTtwYWRkaW5nOjI0cHggMH0jZm9vdGVyIGF7Y29sb3I6I2NjY30jZm9vdGVyIHB7bWFyZ2luLWJvdHRvbTo5cHg7Zm9udC13ZWlnaHQ6Ym9sZDtsZXR0ZXItc3BhY2luZzoxcHh9I2Zvb3RlciBwIGF7bWFyZ2luOjAgMTZweH0jZm9vdGVyIHAgYTpob3Zlcntjb2xvcjojZmJmYmZifSNmb290ZXIgcCBhIC5mYXttYXJnaW4tcmlnaHQ6OHB4fSNnby10b3B7Ym90dG9tOjUwcHg7cmlnaHQ6NDBweDtwb3NpdGlvbjpmaXhlZDtjb2xvcjojZmZmO3BhZGRpbmctdG9wOjZweDtwYWRkaW5nLWJvdHRvbTo4cHg7b3BhY2l0eTouNH0jYXJ0aWNsZS1jb250YWluZXIgLm1ldGF7d2lkdGg6MTA4cHg7bGluZS1oZWlnaHQ6MjRweH0jYXJ0aWNsZS1jb250YWluZXIgLm1ldGEgLmZhe21hcmdpbi1yaWdodDo4cHh9I2FydGljbGUtY29udGFpbmVyIC5tZXRhIC5jb21tZW50cywjYXJ0aWNsZS1jb250YWluZXIgLm1ldGEgLnZpZXdzLCNhcnRpY2xlLWNvbnRhaW5lciAubWV0YSAudGltZXtmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNhcnRpY2xlLWNvbnRhaW5lciAubWV0YSAudGltZXtjb2xvcjojZmZmfSNhcnRpY2xlLWNvbnRhaW5lciAubWV0YSBhe2NvbG9yOiNmZmZ9I2FydGljbGUtY29udGFpbmVyIC5tZXRhIGE6aG92ZXJ7Y29sb3I6I2ZmZn0jYXJ0aWNsZS1jb250YWluZXIgLm1haW57bWFyZ2luLWxlZnQ6MTQwcHh9I2FydGljbGUtY29udGFpbmVyIGgzLnRpdGxle3BhZGRpbmc6OHB4IDE2cHg7YmFja2dyb3VuZC1jb2xvcjojNGM3Mjk4O2JvcmRlci10b3AtbGVmdC1yYWRpdXM6MnB4O2JvcmRlci10b3AtcmlnaHQtcmFkaXVzOjJweH0jYXJ0aWNsZS1jb250YWluZXIgaDMudGl0bGUgYXtjb2xvcjojZWVlfSNhcnRpY2xlLWNvbnRhaW5lciBoMy50aXRsZSBhOmhvdmVye2NvbG9yOiNmZmZ9I2FydGljbGUtY29udGFpbmVyIC5jb250ZW50e2JhY2tncm91bmQtY29sb3I6I2ZmZjtib3JkZXI6MXB4IHNvbGlkICNjY2M7Ym9yZGVyLXRvcDpub25lO3BhZGRpbmc6MThweCAyNHB4IDI0cHh9I2FydGljbGUtY29udGFpbmVyIC5pbmZve21hcmdpbi1ib3R0b206MDtiYWNrZ3JvdW5kLWNvbG9yOiNmYmZiZmI7Ym9yZGVyOjFweCBzb2xpZCAjY2NjO2JvcmRlci10b3A6bm9uZTtib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOjJweDtib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czoycHg7Y29sb3I6Izk5OX0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8gLmZhe21hcmdpbi1yaWdodDo4cHh9I2FydGljbGUtY29udGFpbmVyIC5pbmZvIC5zaGFyZSAuZmF7bWFyZ2luLXJpZ2h0OjB9I2FydGljbGUtY29udGFpbmVyIC5pbmZvPip7cGFkZGluZzo2cHggMThweH0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8+c3Bhbntib3JkZXItcmlnaHQ6MXB4IHNvbGlkICNjY2N9I2FydGljbGUtY29udGFpbmVyIC5pbmZvIC5yaWdodHtib3JkZXItbGVmdDoxcHggc29saWQgI2NjYztib3JkZXItcmlnaHQ6bm9uZX0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8gLnJlYWR7Y29sb3I6Izk5OX0jYXJ0aWNsZS1jb250YWluZXIgLmluZm8gLnJlYWQ6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojMDA3OWJjO2NvbG9yOiNmYmZiZmJ9I2FydGljbGUtY29udGFpbmVyIC5pbmZvIC50aW1lLCNhcnRpY2xlLWNvbnRhaW5lciAuaW5mbyAudmlld3Mgc3Bhbntmb250LWZhbWlseTpWZXJkYW5hLFRhaG9tYSwn5b6u6L2v6ZuF6buRJywn5a6L5L2TJyxzYW5zLXNlcmlmfSNhcnRpY2xlLWNvbnRhaW5lciAuaW5mbyAudGFnIGF7bWFyZ2luOjAgNHB4O2NvbG9yOiM5OTl9I2FydGljbGUtY29udGFpbmVyIC5pbmZvIC50YWcgYTpob3Zlcntjb2xvcjojMzMzfSNhcnRpY2xlLWNvbnRhaW5lciBhcnRpY2xle21hcmdpbi1ib3R0b206NDhweH0jYXJ0aWNsZS1jb250YWluZXIgLnRhZy1iYW5uZXJ7dGV4dC1hbGlnbjpjZW50ZXI7Zm9udC1zaXplOjE4cHg7bWFyZ2luLWJvdHRvbTozMHB4fSNjb21tZW50e21hcmdpbi10b3A6LTI0cHg7Ym9yZGVyOjFweCBzb2xpZCAjY2NjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDtwYWRkaW5nOjI0cHg7YmFja2dyb3VuZDojZmZmfSNjb21tZW50LWZvcm17d2lkdGg6ODAlO21hcmdpbjphdXRvfSNjb21tZW50LWZvcm0gLmMtaW5mb3t3aWR0aDoyNiV9I2NvbW1lbnQtZm9ybSAuYy1pbmZvIC5pcHR7d2lkdGg6MTAwJTtib3gtc2l6aW5nOmJvcmRlci1ib3g7bWluLXdpZHRoOjB9I2NvbW1lbnQtZm9ybSAuYy1jb250ZW50e3dpZHRoOjcwJX0jY29tbWVudC1mb3JtIC5jLWF2YXRhcnt3aWR0aDo0OHB4O2hlaWdodDo0OHB4O3BhZGRpbmc6MnB4O2JvcmRlcjoxcHggc29saWQgI2NjYztib3JkZXItcmFkaXVzOjJweDstbW96LWJvcmRlci1yYWRpdXM6MnB4Oy13ZWJraXQtYm9yZGVyLXJhZGl1czoycHh9I2NvbW1lbnQtZm9ybSAucmVwbHktbWR7bWFyZ2luLWJvdHRvbToxNnB4O2ZvbnQtc2l6ZToxMnB4O2xpbmUtaGVpZ2h0OjIwcHg7Y29sb3I6IzY2Nn0jY29tbWVudC1mb3JtIC5jYW5jZWwtcmVwbHl7Ym9yZGVyOm5vbmU7bWFyZ2luLWxlZnQ6MThweDtkaXNwbGF5Om5vbmV9I2NvbW1lbnQtZm9ybSAuY2FuY2VsLXJlcGx5OmhvdmVye2N1cnNvcjpwb2ludGVyfSNjb21tZW50LWNvbnRlbnR7d2lkdGg6MTAwJTtib3gtc2l6aW5nOmJvcmRlci1ib3g7aGVpZ2h0OjE4MHB4O3Jlc2l6ZTpub25lfSNjb21tZW50LWxpc3QgLmMtYXZhdGFye3dpZHRoOjQ4cHg7aGVpZ2h0OjQ4cHg7cGFkZGluZzoycHg7Ym9yZGVyOjFweCBzb2xpZCAjY2NjO2JvcmRlci1yYWRpdXM6MnB4Oy1tb3otYm9yZGVyLXJhZGl1czoycHg7LXdlYmtpdC1ib3JkZXItcmFkaXVzOjJweDttYXJnaW4tcmlnaHQ6MThweH0jY29tbWVudC1saXN0IC5jb21tZW50e21hcmdpbi1ib3R0b206MThweDtwYWRkaW5nLWJvdHRvbToxOHB4O2JvcmRlci1ib3R0b206MXB4IGRhc2hlZCAjZGRkfSNjb21tZW50LWxpc3QgLmMtbWV0YT4qe21hcmdpbi1yaWdodDoxNnB4fSNjb21tZW50LWxpc3QgLmMtdGltZXtjb2xvcjojOTk5O2ZvbnQtZmFtaWx5OlZlcmRhbmEsVGFob21hLCflvq7ova/pm4Xpu5EnLCflrovkvZMnLHNhbnMtc2VyaWZ9I2NvbW1lbnQtbGlzdCAuYy10aW1lIC5mYXttYXJnaW4tcmlnaHQ6NnB4fSNjb21tZW50LWxpc3QgLmMtcmVwbHl7Y29sb3I6Izk5OX0jY29tbWVudC1saXN0IC5jLXJlcGx5OmhvdmVye2NvbG9yOiMzMzN9I2NvbW1lbnQtbGlzdCAuYy1hdXRob3J7Zm9udC1zaXplOjEzcHh9I2NvbW1lbnQtbGlzdCAuYy1hdXRob3IuYWRtaW57YmFja2dyb3VuZC1jb2xvcjojZTY0MzQ2O2NvbG9yOiNmYmZiZmJ9I2NvbW1lbnQtbGlzdCAuYy1wLW1ke21hcmdpbi10b3A6MTJweDtmb250LXNpemU6MTJweDtsaW5lLWhlaWdodDoyMHB4O2NvbG9yOiM2NjZ9I2NvbW1lbnQtbGlzdCAuYy1zZWN0aW9ue21heC13aWR0aDo4MzBweH0jY29tbWVudC1saXN0IC5jLWNoZWNre2ZvbnQtc2l6ZToxM3B4O2NvbG9yOiNlNjQzNDZ9I2NvbW1lbnQtbGlzdCAuYy1jaGVjayAuZmF7bWFyZ2luLXJpZ2h0OjZweH1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6OTYwcHgpey5jb250YWluZXI5NjB7cGFkZGluZzowIDI0cHg7d2lkdGg6YXV0b319QG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjc2MHB4KXsuY29udGFpbmVyOTYwe3BhZGRpbmc6MCAyNHB4O3dpZHRoOmF1dG99I2FydGljbGUtY29udGFpbmVyIC5tYWlue21hcmdpbi1sZWZ0OjB9I2FydGljbGUtY29udGFpbmVyIC5tZXRhLmxlZnR7ZGlzcGxheTpub25lfSNjb21tZW50LWZvcm0gLmMtaW5mbywjY29tbWVudC1mb3JtIC5jLWNvbnRlbnR7d2lkdGg6MTAwJTtmbG9hdDpsZWZ0fSNjb21tZW50LWZvcm0gLmMtaW5mb3t0ZXh0LWFsaWduOmxlZnR9fUBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDo1NjBweCl7LmNvbnRhaW5lcjk2MHtwYWRkaW5nOjA7d2lkdGg6YXV0b30jbmF2IGxpe3BhZGRpbmc6MCAxMHB4fSNoZWFkZXItaW1ne2Zsb2F0OmxlZnQ7d2lkdGg6NjRweDtoZWlnaHQ6NjRweDttYXJnaW4tbGVmdDoyNHB4fSNoZWFkZXItaHtwYWRkaW5nOjE3cHg7Zm9udC1zaXplOjI0cHg7ZmxvYXQ6bGVmdH0jaGVhZGVyLXN1YntkaXNwbGF5Om5vbmV9I2FydGljbGUtY29udGFpbmVyIC50YWcsI2FydGljbGUtY29udGFpbmVyIC50aW1le2Rpc3BsYXk6bm9uZX0jY29tbWVudC1mb3Jte3dpZHRoOjEwMCV9fUBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDo0ODBweCl7LmNvbnRhaW5lcjk2MHtwYWRkaW5nOjA7d2lkdGg6YXV0b30jaGVhZGVyLWh7ZmxvYXQ6bm9uZX0jaGVhZGVyLWltZ3tkaXNwbGF5Om5vbmV9I2hlYWRlci1zdWJ7ZGlzcGxheTpub25lfSNjb21tZW50LWxpc3QgLmMtYXZhdGFye2Rpc3BsYXk6bm9uZX0jbmF2IGxpIGF7cGFkZGluZzowIDE2cHh9fVBLBwivOz4d7ykAAO8pAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABIAAABzdGF0aWNcZmF2aWNvbi5pY28AAAEAAQAgIAAAAQAgAKgQAAAWAAAAKAAAACAAAABAAAAAAQAgAAAAAAAAEAAAEgsAABILAAAAAAAAAAAAALN+B9uzfQfbs30H27N9B9uzfQfbs30H27N9B9uzfQfbs30H27N9B9uzfQfbs30H27N9B9uzfQfbs34H27N+B9uzfgfbs34H27N+B9uzfgfbs30H27N+B9uzfgfbs30H27N+B9uzfgfbs34H27N+B9uyfAfWr3oHx61+GK21k0qQuoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoII/7qCCP+6ggj/uoMN/7qGF/+5gQj/uYEI/7mBCP+5gQj/uoEI/7mBCP+5gQj/uYEI/7mBCP+5gQj/uYEI/7qBCP+5gQj/uYEI/7mBCP+5gQj/uoEI/7mBCP+6gQj/uYEI/7mBCP+5gQj/uYEI/7mBCP+5gQj/uoEI/7qBCP+5gQj/uYII/7qBCP+6ggj/uoII/7mBCP+5gQj/uYII/7mBCP+5gQj/uYEI/7mBCP+5gQj/uYEI/7mBCP+5gQj/uoII/7mBCP+5gQj/uoEI/7qBCP+6ggj/uoII/7qBCP+6ggj/uoEI/7qCCP+6gQj/uoII/7qCCP+6gQj/uoII/7qBCP+6gQj/uYEI/7mBCP+5ggf/uYIH/7mCB/+5gQf/uYEH/7mBB/+5gQf/uYEH/7mBB/+5gQf/uYEH/7mBB/+5gQf/uYEH/7mCB/+6ggf/uoIH/7qCB/+6ggf/uoIH/7qCB/+6ggf/uoIH/7qCB/+6ggf/uoIH/7qCB/+6ggf/uoIH/7qCB/+6ggf/uoIH/7qCB/+8hAX/vIQF/7uDBf+8gwX/vIMF/7yDBf+8gwX/vIMF/7yDBf+8gwX/vIMF/7yDBf+8gwX/vIMF/7yEBf+8hAX/vIQF/7yEBf+8hAX/vIQF/7yEBf+8hAX/vIQF/7yEBf+8hAX/vIQF/7yDBf+8hAX/vIQF/7yDBf+8hAb/vIQG/8CHA//AhgP/wIcD/8CHA//AhwP/wIcD/8CHA//AhwP/wIcD/8CHA//AhwP/wIcD/8CHA//AhwP/wIcD/8CGA//AhgP/wIYD/8CGA//AhgP/wIYD/8CGA//AhgP/wIYD/8CGA//AhgP/wIYD/8CGA//AhwT/wIcE/8CGA//AhgL/xYkC/8WJAf/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYkC/8WJAv/FiQL/xYoC/8WJAf/FigP/x48O/8yaJ//JjAD/yYwA/8mMAP/JjAD/yYwA/8mMAP/JjAD/yYwA/8mMAP/JjAD/yYwA/8mMAP/JjAD/yYwA/8mNAP/JjQD/yY0A/8mNAP/JjQD/yY0A/8mNAP/JjQD/yY0A/8mNAP/JjQD/yY0A/8mNAP/Jkxf/1q9T/+HAdf/p0p//8+fN/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y40A/8ugPf/y693+/v36/v/////////+yo4A/sqNAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgD/y44A/8uOAP/LjgH/y44A/8uOAP/LjQD/yo4A/8uOAP/LjgD/y44B/8uOAf/LjgD/y44A/8uOAP/LjgD/y44B/8qNAP/Ljwb/2Llz//r59f7+///+/v7+//7+/v7KjgD+yo0A/8uOAP/LjgD/yo4A/8qOAP/KjgD/yo4A/8uOAP/LjgD/yo4A/8uOAP/LjgD/yo0A/8uNAP/LjgH/yY0B/8eNCP/KjgP/yo0A/8uNAP/KjQD/yo0A/8qNAP/LjwL/0Job/9++cf/17+D//v7+/v////7+/v7//v7+/suOAfrLjgD/yo0A/8uOAP/LjgH/yo4A/8qOAP/KjgD/y44A/8qOAP/KjgD/y44A/8uOAf/KjgD/yo0A/8mMAP/HmjT/wat5/6iLSP/Npk7/xZgw/8+fMf/Wpjn/2rBP/+LCd//w37n/+/jy//7+///+/v7////////////+/v7/vJIyvruKGf/Mkgz/yo4A/8qNAP/KjQD/yo0A/8qOAP/KjgD/yo4A/8qNAP/KjQD/yo0A/8uOAf/QmRj/yaNN/9DGrf/l5eb/pqWj/+nm3//EvrH/4drJ/vnz4/779uz//fz5//////7////+/v7+//7+/v////////////7+/v+Vk42UmY95/+bOmf/gvWr/2a1I/9SjMv/Rmx//z5YT/8+VEf/PlRH/z5cX/9OfKP/Zq0P/4b9x/+3bs//QzMT/w8PD/urq6v62trb+6Ojo/rS0tf7a29v+/f39/v7///7+/v7//////v////7+/v7//v7+//////7////+/////peWlpWSkpP/9vb1//379//59Of/9u3X//Lkxf/w37j/7tyy/+/cs//x4bv/9enO//nz5P/39fL/ycnK/6+vr/+lpKT/vb29/5SUlP+5ubn/p6en/7Gxsf/R0dH//Pz8///////+/v7//v7+//7+/v/+/v7////////////+/v7/qampmJGRkf/y8vL////+//7+/v/////////////////+/v7//v7+//7+///+/////////+Hh4P+6ubn/7+/v/+zs7P/X19f/xsbG/97e3v/19fX/6urr/7i4uP/x8fH///////7+/v7//////v7+//7+/v////////////7+/v+bm5tng4OD8O3t7f///////////v///v7+/v7//v7+/v/+/v7+/v7++fn5/vb29v76+vr+5+fo/7e3t//t7e3/+Pj4/t3d3f7Y2Nj+8vLy/v7+/v7Y2Nj+vr6+/vj4+P7//////////v////7+/v7//v7+//////7////+/////jU1NSNxcXHY5ubm//////7////+//////7+/v//////7+/v/tDQ0P++vr7+urq6/r6+vv/R0dH+z8/P/qysrP9nZ2f+Kysr/yMjI/9bW1v/q6ur/729vf7k5OT+5eXl/9ra2v/f39/+8PDw/v39/f/////+/v7+/v/////////+jY2NJ3V1ddrb29v//////v////7//////v7+/+Hh4f+1tbX+ysrK/+Pj4/7n5+f+4+Pj/8nJyf6+vr7+t7e3/ywsLP4AAAD/AAAA/wYGBv+Ghob/19fX/r6+vv68vLz/wcHB/76+vv65ubn+x8fH//Hx8f7////+//////////7g4OAkhISE2cXFxf///////////v/////n5+f/tbW1/+Tk5P///////////v/////////+/v7+/uDg4P+2trb/rq6u/25ubv9ZWVn/g4OD/7u7u/++vr7/5OTk/vr6+v/9/f3//Pz8/vDw8P/Kysr/t7e3//Dw8P///////////4eHh4BdXV3xo6Oj///////////++/v7/8HBwf/BwcH/ra2t/8bGxv/6+vr///////7+/v/+/v7+/////9bW1v/ExMT/9vb2//b29v/d3d3/vr6+/+Tk5P/x8fH//v7+//7+/v/+/v7+//////39/f/Nzc3/w8PD//v7+///////hoaG+JaWlv+Li4v/9/f3///////u7u7/q6ur/1JSUv8TExP/Z2dn/9HR0f/9/f3//v7+////////////8vLy/7i4uP/v7+//+vr6/8DAwP+cnJz/VFRU/25ubv/c3Nz//v7+//////7+/v7///////T09P+3t7f/6+vr///////v7+//7Ozs/3x8fP/Y2Nj+/////ufn5/+Tk5P/FhYW/wUFBf83Nzf/mZmZ//v7+//+/v7//////v/////6+vr/w8PD/+fn5//z8/P/rKys/zk5Of8AAAD/RUVF/piYmP/19fX//////v7+/v///////f39/8TExP/e3t7////////////R0dH/MzMz/5eXl///////5+fn/7Ozs/9oaGj/FxcX/zo6Ov/IyMj//v7+//7+/v////////////j4+P+9vb3/6+vr//Dw8P+zs7P/TExM/wAAAP8ODg7+goKC//r6+v/////+/v7+///////+/v7/x8fH/9zc3P///////////7i4uP8ZGRn/Pz8//t/f3/729vb+vb29/9vb2/7ExMT+29vb//39/f7+/v7+/////v////7////+5eXl/rm5uf729vb/8/Pz/76+vv/BwcH+cnJy/n5+fv7g4OD///////7+/v7+/v7+//////j4+P68vLz+5ubm//////7////+8fHx/7Kysv+FhYX+i4uL/vT09P/U1NT/vb29//n5+f7//////v7+/v////7//////////vb29v69vb3/1tbW///////9/f3/x8fH/87Ozv/5+fn+/Pz8/v///////////////v////7/////39/f/rm5uf74+Pj/7u7u/snJyf/4+Pj+//////Ly8v6IiIj+m5ub//T09P/IyMj/vb29/ufn5//6+vr+/Pz8/vr6+v/n5+f+vb29/snJyf/6+vr////////////w8PD/t7e3/9jY2P79/f3+///////////////+/////unp6f+3t7f+4uLi//Hx8f+Ojo7+c3Nz5ZCQkP6jo6P/oKCg/n5+fvpOTk7hnJyc++Hh4f/W1tb+vb29/8DAwP/BwcH/vr6+/7m5uf7W1tb++vr6///////////////////////p6en/ubm5/sPDw/7f39//6Ojo/+Tk5P7MzMz/tra2/93d3f7q6ur/g4OD/3BwcP+rq6s/cHBwZkVFRWlKSkpnhYWFX4yMjDhtbW2bd3d3662trf/Y2Nj/5OTk/uXl5f/p6en/9vb2/v////////////////7+/v/////////////////19fX/1tbW/8LCwv+9vb3/wcHB/9HR0f/k5OT/xsbG/319ffNjY2POa2tr0hEREQD///8A////ALy8vAAAAAAAAAAAAM7Ozgt2dnZFbW1to3t7e+uZmZn/t7e3/9fX1//o6Oj/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SwcIm6PU7/MrAADzKwAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAc3RhdGljXGltZ1xoZWFkZXIuZ2lmR0lGODlhZABkALMAAE10mkltkk51nEhskElukkxzmUpvlExymEpwlUtxlgAAAAAAAAAAAAAAAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCMDE1QUFDMTUyNDQxMUUyOEYxM0EwNDlDOUFGQTk3QyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCMDE1QUFDMjUyNDQxMUUyOEYxM0EwNDlDOUFGQTk3QyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkIwMTVBQUJGNTI0NDExRTI4RjEzQTA0OUM5QUZBOTdDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkIwMTVBQUMwNTI0NDExRTI4RjEzQTA0OUM5QUZBOTdDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRh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YWRlcigpIHsNCiAgICB2YXIgJG5hdiA9ICQoJyNuYXYnKTsNCiAgICB2YXIgdG9wID0gJG5hdi5vZmZzZXQoKS50b3A7DQogICAgY29uc29sZS5sb2codG9wKTsNCiAgICAkKHdpbmRvdykuc2Nyb2xsKGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKHRvcCA8ICQodGhpcykuc2Nyb2xsVG9wKCkpIHsNCiAgICAgICAgICAgICRuYXYuYWRkQ2xhc3MoImZpeGVkIikucmVtb3ZlQ2xhc3MoInRleHQtY2VudGVyIik7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAkbmF2LnJlbW92ZUNsYXNzKCJmaXhlZCIpLmFkZENsYXNzKCJ0ZXh0LWNlbnRlciIpOw0KICAgICAgICB9DQogICAgfSk7DQp9DQoNCmZ1bmN0aW9uIHRvcEJ1dHRvbigpIHsNCiAgICB2YXIgdG9wID0gJCgnI25hdicpLm9mZnNldCgpLnRvcDsNCiAgICB2YXIgJHRvcCA9ICQoJyNnby10b3AnKTsNCiAgICAkKHdpbmRvdykuc2Nyb2xsKGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKHRvcCA8ICQodGhpcykuc2Nyb2xsVG9wKCkpIHsNCiAgICAgICAgICAgICR0b3AucmVtb3ZlQ2xhc3MoImhpZGUiKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICR0b3AuYWRkQ2xhc3MoJ2hpZGUnKTsNCiAgICAgICAgfQ0KICAgIH0pOw0KICAgICR0b3Aub24oImNsaWNrIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICAkKCdib2R5LGh0bWwnKS5hbmltYXRlKHtzY3JvbGxUb3A6IDB9LCA1MDApOw0KICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgfSkNCn0NCg0KZnVuY3Rpb24gcmVuZGVyTWFya2Rvd24oKSB7DQogICAgdmFyICRtZCA9ICQoJy5tYXJrZG93bicpOw0KICAgICRtZC5lYWNoKGZ1bmN0aW9uIChpLCBpdGVtKSB7DQogICAgICAgICQoaXRlbSkuaHRtbChtYXJrZWQoJChpdGVtKS5odG1sKCkucmVwbGFjZSgvJmd0Oy9nLCAnPicpKSk7DQogICAgfSk7DQogICAgdmFyIGNvZGUgPSAkbWQuZmluZCgncHJlIGNvZGUnKTsNCiAgICBpZiAoY29kZS5sZW5ndGgpIHsNCiAgICAgICAgJCgiPGxpbms+IikuYXR0cih7IHJlbDogInN0eWxlc2hlZXQiLCB0eXBlOiAidGV4dC9jc3MiLCBocmVmOiAiL3N0YXRpYy9jc3MvaGlnaGxpZ2h0LmNzcyJ9KS5hcHBlbmRUbygiaGVhZCIpOw0KICAgICAgICAkLmdldFNjcmlwdCgiL3N0YXRpYy9saWIvaGlnaGxpZ2h0Lm1pbi5qcyIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIGNvZGUuZWFjaChmdW5jdGlvbiAoaSwgaXRlbSkgew0KICAgICAgICAgICAgICAgIGhsanMuaGlnaGxpZ2h0QmxvY2soaXRlbSkNCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9KTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGluaXRDb21tZW50KCkgew0KICAgIHZhciAkbGlzdCA9ICQoJyNjb21tZW50LWxpc3QnKTsNCiAgICBpZiAoISRsaXN0Lmxlbmd0aCkgew0KICAgICAgICByZXR1cm47DQogICAgfQ0KICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgiY29tbWVudC1hdXRob3IiKSkgew0KICAgICAgICAkKCcjY29tbWVudC1hdXRob3InKS52YWwobG9jYWxTdG9yYWdlLmdldEl0ZW0oImNvbW1lbnQtYXV0aG9yIikpOw0KICAgICAgICAkKCcjY29tbWVudC1lbWFpbCcpLnZhbChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgiY29tbWVudC1lbWFpbCIpKTsNCiAgICAgICAgJCgnI2NvbW1lbnQtdXJsJykudmFsKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCJjb21tZW50LXVybCIpKTsNCiAgICAgICAgJCgnI2NvbW1lbnQtYXZhdGFyJykuYXR0cigic3JjIiwgbG9jYWxTdG9yYWdlLmdldEl0ZW0oImNvbW1lbnQtYXZhdGFyIikpOw0KICAgICAgICAkKCcuYy1hdmF0YXInKS5yZW1vdmVDbGFzcygibnVsbCIpOw0KICAgIH0NCiAgICAkKCcjY29tbWVudC1jb250ZW50Jykub24oImZvY3VzIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICBpZiAoJCgnLmMtYXZhdGFyJykuaGFzQ2xhc3MoIm51bGwiKSkgew0KICAgICAgICAgICAgJCgnLmMtYXZhdGFyLWZpZWxkJykucmVtb3ZlKCk7DQogICAgICAgICAgICAkKCcuYy1pbmZvLWZpZWxkcycpLnJlbW92ZUNsYXNzKCJoaWRlIik7DQogICAgICAgIH0NCiAgICB9KTsNCiAgICAkKCcubm90LW1lJykub24oImNsaWNrIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICAkKCcuYy1hdmF0YXItZmllbGQnKS5yZW1vdmUoKTsNCiAgICAgICAgJCgnLmMtaW5mby1maWVsZHMnKS5yZW1vdmVDbGFzcygiaGlkZSIpOw0KICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgfSk7DQogICAgJCgnI2NvbW1lbnQtc2hvdycpLm9uKCJjbGljayIsICIuZW5hYmxlIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICAkKCIjY29tbWVudC1zaG93IikucmVtb3ZlKCk7DQogICAgICAgICQoJyNjb21tZW50LWZvcm0nKS5yZW1vdmVDbGFzcygiaGlkZSIpOw0KICAgIH0pOw0KICAgICQoJyNjb21tZW50LWZvcm0nKS5hamF4Rm9ybShmdW5jdGlvbiAoanNvbikgew0KICAgICAgICBpZiAoanNvbi5yZXMpIHsNCiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCJjb21tZW50LWF1dGhvciIsICQoJyNjb21tZW50LWF1dGhvcicpLnZhbCgpKTsNCiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCJjb21tZW50LWVtYWlsIiwgJCgnI2NvbW1lbnQtZW1haWwnKS52YWwoKSk7DQogICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgiY29tbWVudC11cmwiLCAkKCcjY29tbWVudC11cmwnKS52YWwoKSk7DQogICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgiY29tbWVudC1hdmF0YXIiLCBqc29uLmNvbW1lbnQuYXZhdGFyKTsNCiAgICAgICAgICAgIHZhciB0cGwgPSAkKCQoJyNjb21tZW50LXRwbCcpLmh0bWwoKSk7DQogICAgICAgICAgICB0cGwuZmluZCgiLmMtYXZhdGFyIikuYXR0cigic3JjIiwganNvbi5jb21tZW50LmF2YXRhcikuYXR0cigiYWx0IiwganNvbi5jb21tZW50LmF1dGhvcik7DQogICAgICAgICAgICB0cGwuZmluZCgiLmMtYXV0aG9yIikuYXR0cigiaHJlZiIsIGpzb24uY29tbWVudC51cmwpLnRleHQoanNvbi5jb21tZW50LmF1dGhvcik7DQogICAgICAgICAgICB0cGwuZmluZCgiLmMtcmVwbHkiKS5hdHRyKCJyZWwiLCBqc29uLmNvbW1lbnQuaWQpOw0KICAgICAgICAgICAgdHBsLmZpbmQoIi5jLWNvbnRlbnQiKS5odG1sKGpzb24uY29tbWVudC5jb250ZW50KTsNCiAgICAgICAgICAgIGlmIChqc29uLmNvbW1lbnQucGFyZW50X21kKSB7DQogICAgICAgICAgICAgICAgdHBsLmZpbmQoIi5jLXAtbWQiKS5odG1sKG1hcmtlZChqc29uLmNvbW1lbnQucGFyZW50X21kKSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRwbC5maW5kKCIuYy1wLW1kIikucmVtb3ZlKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB0cGwuYXR0cigiaWQiLCAiY29tbWVudC0iICsganNvbi5jb21tZW50LmlkKTsNCiAgICAgICAgICAgIGlmIChqc29uLmNvbW1lbnQuc3RhdHVzID09ICJhcHByb3ZlZCIpIHsNCiAgICAgICAgICAgICAgICB0cGwuZmluZCgiLmMtY2hlY2siKS5yZW1vdmUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICRsaXN0LmFwcGVuZCh0cGwpOw0KICAgICAgICAgICAgJCgnLmNhbmNlbC1yZXBseScpLnRyaWdnZXIoImNsaWNrIik7DQogICAgICAgICAgICAkKCcjY29tbWVudC1jb250ZW50JykudmFsKCIiKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGFsZXJ0KCLmj5DkuqTlpLHotKUhIik7DQogICAgICAgIH0NCiAgICB9KTsNCiAgICAkbGlzdC5vbigiY2xpY2siLCAiLmMtcmVwbHkiLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICQoJy5yZXBseS1tZCcpLnJlbW92ZSgpOw0KICAgICAgICB2YXIgaWQgPSAkKHRoaXMpLmF0dHIoInJlbCIpOw0KICAgICAgICB2YXIgcGMgPSAkKCcjY29tbWVudC0nICsgaWQpOw0KICAgICAgICB2YXIgbWQgPSAiPiBAIiArIHBjLmZpbmQoIi5jLWF1dGhvciIpLnRleHQoKSArICJcblxuIjsNCiAgICAgICAgbWQgKz0gIj4gIiArIHBjLmZpbmQoIi5jLWNvbnRlbnQiKS5odG1sKCkgKyAiXG4iOw0KICAgICAgICAkKCcjY29tbWVudC1jb250ZW50JykuYmVmb3JlKCc8ZGl2IGNsYXNzPSJyZXBseS1tZCBtYXJrZG93biI+JyArIG1hcmtlZChtZCkgKyAnPC9kaXY+Jyk7DQogICAgICAgICQoJyNjb21tZW50LXBhcmVudCcpLnZhbChpZCk7DQogICAgICAgIGlmICgkKCcjY29tbWVudC1zaG93JykubGVuZ3RoKSB7DQogICAgICAgICAgICAkKCcjY29tbWVudC1zaG93IC5lbmFibGUnKS50cmlnZ2VyKCJjbGljayIpOw0KICAgICAgICB9DQogICAgICAgICQoJy5jYW5jZWwtcmVwbHknKS5zaG93KCk7DQogICAgICAgIHZhciB0b3AgPSAkKCcjY29tbWVudC1mb3JtJykub2Zmc2V0KCkudG9wOw0KICAgICAgICAkKCdib2R5LGh0bWwnKS5hbmltYXRlKHtzY3JvbGxUb3A6IHRvcH0sIDUwMCk7DQogICAgICAgIHJldHVybiBmYWxzZTsNCiAgICB9KTsNCiAgICAkKCcuY2FuY2VsLXJlcGx5Jykub24oImNsaWNrIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICAkKCcucmVwbHktbWQnKS5yZW1vdmUoKTsNCiAgICAgICAgJCgnI2NvbW1lbnQtcGFyZW50JykudmFsKDApOw0KICAgICAgICAkKHRoaXMpLmhpZGUoKTsNCiAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgIH0pOw0KfQ0KUEsHCB7hHnJ1EgAAdRIAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFQAAAHN0YXRpY1xqc1xob21lLm1pbi5qc2Z1bmN0aW9uIGZpeEhlYWRlcigpe3ZhciB0PSQoIiNuYXYiKSxlPXQub2Zmc2V0KCkudG9wO2NvbnNvbGUubG9nKGUpLCQod2luZG93KS5zY3JvbGwoZnVuY3Rpb24oKXtlPCQodGhpcykuc2Nyb2xsVG9wKCk/dC5hZGRDbGFzcygiZml4ZWQiKS5yZW1vdmVDbGFzcygidGV4dC1jZW50ZXIiKTp0LnJlbW92ZUNsYXNzKCJmaXhlZCIpLmFkZENsYXNzKCJ0ZXh0LWNlbnRlciIpfSl9ZnVuY3Rpb24gdG9wQnV0dG9uKCl7dmFyIHQ9JCgiI25hdiIpLm9mZnNldCgpLnRvcCxlPSQoIiNnby10b3AiKTskKHdpbmRvdykuc2Nyb2xsKGZ1bmN0aW9uKCl7dDwkKHRoaXMpLnNjcm9sbFRvcCgpP2UucmVtb3ZlQ2xhc3MoImhpZGUiKTplLmFkZENsYXNzKCJoaWRlIil9KSxlLm9uKCJjbGljayIsZnVuY3Rpb24oKXtyZXR1cm4gJCgiYm9keSxodG1sIikuYW5pbWF0ZSh7c2Nyb2xsVG9wOjB9LDUwMCksITF9KX1mdW5jdGlvbiByZW5kZXJNYXJrZG93bigpe3ZhciB0PSQoIi5tYXJrZG93biIpO3QuZWFjaChmdW5jdGlvbih0LGUpeyQoZSkuaHRtbChtYXJrZWQoJChlKS5odG1sKCkucmVwbGFjZSgvJmd0Oy9nLCI+IikpKX0pO3ZhciBlPXQuZmluZCgicHJlIGNvZGUiKTtlLmxlbmd0aCYmKCQoIjxsaW5rPiIpLmF0dHIoe3JlbDoic3R5bGVzaGVldCIsdHlwZToidGV4dC9jc3MiLGhyZWY6Ii9zdGF0aWMvY3NzL2hpZ2hsaWdodC5jc3MifSkuYXBwZW5kVG8oImhlYWQiKSwkLmdldFNjcmlwdCgiL3N0YXRpYy9saWIvaGlnaGxpZ2h0Lm1pbi5qcyIsZnVuY3Rpb24oKXtlLmVhY2goZnVuY3Rpb24odCxlKXtobGpzLmhpZ2hsaWdodEJsb2NrKGUpfSl9KSl9ZnVuY3Rpb24gaW5pdENvbW1lbnQoKXt2YXIgdD0kKCIjY29tbWVudC1saXN0Iik7dC5sZW5ndGgmJihsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgiY29tbWVudC1hdXRob3IiKSYmKCQoIiNjb21tZW50LWF1dGhvciIpLnZhbChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgiY29tbWVudC1hdXRob3IiKSksJCgiI2NvbW1lbnQtZW1haWwiKS52YWwobG9jYWxTdG9yYWdlLmdldEl0ZW0oImNvbW1lbnQtZW1haWwiKSksJCgiI2NvbW1lbnQtdXJsIikudmFsKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCJjb21tZW50LXVybCIpKSwkKCIjY29tbWVudC1hdmF0YXIiKS5hdHRyKCJzcmMiLGxvY2FsU3RvcmFnZS5nZXRJdGVtKCJjb21tZW50LWF2YXRhciIpKSwkKCIuYy1hdmF0YXIiKS5yZW1vdmVDbGFzcygibnVsbCIpKSwkKCIjY29tbWVudC1jb250ZW50Iikub24oImZvY3VzIixmdW5jdGlvbigpeyQoIi5jLWF2YXRhciIpLmhhc0NsYXNzKCJudWxsIikmJigkKCIuYy1hdmF0YXItZmllbGQiKS5yZW1vdmUoKSwkKCIuYy1pbmZvLWZpZWxkcyIpLnJlbW92ZUNsYXNzKCJoaWRlIikpfSksJCgiLm5vdC1tZSIpLm9uKCJjbGljayIsZnVuY3Rpb24oKXtyZXR1cm4gJCgiLmMtYXZhdGFyLWZpZWxkIikucmVtb3ZlKCksJCgiLmMtaW5mby1maWVsZHMiKS5yZW1vdmVDbGFzcygiaGlkZSIpLCExfSksJCgiI2NvbW1lbnQtc2hvdyIpLm9uKCJjbGljayIsIi5lbmFibGUiLGZ1bmN0aW9uKCl7JCgiI2NvbW1lbnQtc2hvdyIpLnJlbW92ZSgpLCQoIiNjb21tZW50LWZvcm0iKS5yZW1vdmVDbGFzcygiaGlkZSIpfSksJCgiI2NvbW1lbnQtZm9ybSIpLmFqYXhGb3JtKGZ1bmN0aW9uKGUpe2lmKGUucmVzKXtsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgiY29tbWVudC1hdXRob3IiLCQoIiNjb21tZW50LWF1dGhvciIpLnZhbCgpKSxsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgiY29tbWVudC1lbWFpbCIsJCgiI2NvbW1lbnQtZW1haWwiKS52YWwoKSksbG9jYWxTdG9yYWdlLnNldEl0ZW0oImNvbW1lbnQtdXJsIiwkKCIjY29tbWVudC11cmwiKS52YWwoKSksbG9jYWxTdG9yYWdlLnNldEl0ZW0oImNvbW1lbnQtYXZhdGFyIixlLmNvbW1lbnQuYXZhdGFyKTt2YXIgbz0kKCQoIiNjb21tZW50LXRwbCIpLmh0bWwoKSk7by5maW5kKCIuYy1hdmF0YXIiKS5hdHRyKCJzcmMiLGUuY29tbWVudC5hdmF0YXIpLmF0dHIoImFsdCIsZS5jb21tZW50LmF1dGhvciksby5maW5kKCIuYy1hdXRob3IiKS5hdHRyKCJocmVmIixlLmNvbW1lbnQudXJsKS50ZXh0KGUuY29tbWVudC5hdXRob3IpLG8uZmluZCgiLmMtcmVwbHkiKS5hdHRyKCJyZWwiLGUuY29tbWVudC5pZCksby5maW5kKCIuYy1jb250ZW50IikuaHRtbChlLmNvbW1lbnQuY29udGVudCksZS5jb21tZW50LnBhcmVudF9tZD9vLmZpbmQoIi5jLXAtbWQiKS5odG1sKG1hcmtlZChlLmNvbW1lbnQucGFyZW50X21kKSk6by5maW5kKCIuYy1wLW1kIikucmVtb3ZlKCksby5hdHRyKCJpZCIsImNvbW1lbnQtIitlLmNvbW1lbnQuaWQpLCJhcHByb3ZlZCI9PWUuY29tbWVudC5zdGF0dXMmJm8uZmluZCgiLmMtY2hlY2siKS5yZW1vdmUoKSx0LmFwcGVuZChvKSwkKCIuY2FuY2VsLXJlcGx5IikudHJpZ2dlcigiY2xpY2siKSwkKCIjY29tbWVudC1jb250ZW50IikudmFsKCIiKX1lbHNlIGFsZXJ0KCLmj5DkuqTlpLHotKUhIil9KSx0Lm9uKCJjbGljayIsIi5jLXJlcGx5IixmdW5jdGlvbigpeyQoIi5yZXBseS1tZCIpLnJlbW92ZSgpO3ZhciB0PSQodGhpcykuYXR0cigicmVsIiksZT0kKCIjY29tbWVudC0iK3QpLG89Ij4gQCIrZS5maW5kKCIuYy1hdXRob3IiKS50ZXh0KCkrIlxuXG4iO28rPSI+ICIrZS5maW5kKCIuYy1jb250ZW50IikuaHRtbCgpKyJcbiIsJCgiI2NvbW1lbnQtY29udGVudCIpLmJlZm9yZSgnPGRpdiBjbGFzcz0icmVwbHktbWQgbWFya2Rvd24iPicrbWFya2VkKG8pKyI8L2Rpdj4iKSwkKCIjY29tbWVudC1wYXJlbnQiKS52YWwodCksJCgiI2NvbW1lbnQtc2hvdyIpLmxlbmd0aCYmJCgiI2NvbW1lbnQtc2hvdyAuZW5hYmxlIikudHJpZ2dlcigiY2xpY2siKSwkKCIuY2FuY2VsLXJlcGx5Iikuc2hvdygpO3ZhciBuPSQoIiNjb21tZW50LWZvcm0iKS5vZmZzZXQoKS50b3A7cmV0dXJuICQoImJvZHksaHRtbCIpLmFuaW1hdGUoe3Njcm9sbFRvcDpufSw1MDApLCExfSksJCgiLmNhbmNlbC1yZXBseSIpLm9uKCJjbGljayIsZnVuY3Rpb24oKXtyZXR1cm4gJCgiLnJlcGx5LW1kIikucmVtb3ZlKCksJCgiI2NvbW1lbnQtcGFyZW50IikudmFsKDApLCQodGhpcykuaGlkZSgpLCExfSkpfSQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7dG9wQnV0dG9uKCkscmVuZGVyTWFya2Rvd24oKSxpbml0Q29tbWVudCgpfSk7UEsHCIHF9j9NDAAATQwAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAEwAAAHN0YXRpY1xqc1x1cGxvYWQuanNmdW5jdGlvbiBpbml0VXBsb2FkKHApIHsNCiAgICAkKCcjYXR0YWNoLXNob3cnKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICQoJyNhdHRhY2gtdXBsb2FkJykudHJpZ2dlcigiY2xpY2siKTsNCiAgICB9KTsNCiAgICAkKCcjYXR0YWNoLXVwbG9hZCcpLm9uKCJjaGFuZ2UiLCBmdW5jdGlvbiAoKSB7DQogICAgICAgIGlmIChjb25maXJtKCLnq4vljbPkuIrkvKA/IikpIHsNCiAgICAgICAgICAgIHZhciBiYXIgPSAkKCc8cCBjbGFzcz0iZmlsZS1wcm9ncmVzcyBpbmxpbmUtYmxvY2siPjAlPC9wPicpOw0KICAgICAgICAgICAgJCgnI2F0dGFjaC1mb3JtJykuYWpheFN1Ym1pdCh7DQogICAgICAgICAgICAgICAgImJlZm9yZVN1Ym1pdCI6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgICAgICAgICAgJChwKS5iZWZvcmUoYmFyKTsNCiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgICJ1cGxvYWRQcm9ncmVzcyI6IGZ1bmN0aW9uIChldmVudCwgcG9zaXRpb24sIHRvdGFsLCBwZXJjZW50Q29tcGxldGUpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHBlcmNlbnRWYWwgPSBwZXJjZW50Q29tcGxldGUgKyAnJSc7DQogICAgICAgICAgICAgICAgICAgIGJhci5jc3MoIndpZHRoIiwgcGVyY2VudFZhbCkuaHRtbChwZXJjZW50VmFsKTsNCiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgICJzdWNjZXNzIjogZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKCFqc29uLnJlcykgew0KICAgICAgICAgICAgICAgICAgICAgICAgYmFyLmh0bWwoanNvbi5tc2cpLmFkZENsYXNzKCJlcnIiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhci5yZW1vdmUoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwMDApOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgYmFyLmh0bWwoIi8iICsganNvbi5maWxlLlVybCArICImbmJzcDsmbmJzcDsmbmJzcDsoQCIgKyBqc29uLmZpbGUuTmFtZSArICIpIik7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgJCgnI2F0dGFjaC11cGxvYWQnKS52YWwoIiIpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgJCh0aGlzKS52YWwoIiIpOw0KICAgICAgICB9DQogICAgfSk7DQp9UEsHCIiJF/v2BAAA9gQAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFwAAAHN0YXRpY1xqc1x1cGxvYWQubWluLmpzZnVuY3Rpb24gaW5pdFVwbG9hZCh0KXskKCIjYXR0YWNoLXNob3ciKS5vbigiY2xpY2siLGZ1bmN0aW9uKCl7JCgiI2F0dGFjaC11cGxvYWQiKS50cmlnZ2VyKCJjbGljayIpfSksJCgiI2F0dGFjaC11cGxvYWQiKS5vbigiY2hhbmdlIixmdW5jdGlvbigpe2lmKGNvbmZpcm0oIueri+WNs+S4iuS8oD8iKSl7dmFyIGE9JCgnPHAgY2xhc3M9ImZpbGUtcHJvZ3Jlc3MgaW5saW5lLWJsb2NrIj4wJTwvcD4nKTskKCIjYXR0YWNoLWZvcm0iKS5hamF4U3VibWl0KHtiZWZvcmVTdWJtaXQ6ZnVuY3Rpb24oKXskKHQpLmJlZm9yZShhKX0sdXBsb2FkUHJvZ3Jlc3M6ZnVuY3Rpb24odCxpLG4sbyl7dmFyIGM9bysiJSI7YS5jc3MoIndpZHRoIixjKS5odG1sKGMpfSxzdWNjZXNzOmZ1bmN0aW9uKHQpe3QucmVzP2EuaHRtbCgiLyIrdC5maWxlLlVybCsiJm5ic3A7Jm5ic3A7Jm5ic3A7KEAiK3QuZmlsZS5OYW1lKyIpIik6KGEuaHRtbCh0Lm1zZykuYWRkQ2xhc3MoImVyciIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXthLnJlbW92ZSgpfSw1ZTMpKSwkKCIjYXR0YWNoLXVwbG9hZCIpLnZhbCgiIil9fSl9ZWxzZSAkKHRoaXMpLnZhbCgiIil9KX1QSwcIp2KpZUgCAABIAgAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAc3RhdGljXGxpYi9QSwcIAAAAAAAAAAAAAAAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAhAAAAc3RhdGljXGxpYlxjb2RlbWlycm9yLW1vZGUubWluLmpzIWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO3ZhciB0PS9eKFxzKikoWyorLV18KFxkKylcLikoXHMqKS8sZT0iKistIjtDb2RlTWlycm9yLmNvbW1hbmRzLm5ld2xpbmVBbmRJbmRlbnRDb250aW51ZU1hcmtkb3duTGlzdD1mdW5jdGlvbihyKXt2YXIgbixpPXIuZ2V0Q3Vyc29yKCksbz1yLmdldFN0YXRlQWZ0ZXIoaS5saW5lKS5saXN0IT09ITE7aWYoIW98fCEobj1yLmdldExpbmUoaS5saW5lKS5tYXRjaCh0KSkpcmV0dXJuIHIuZXhlY0NvbW1hbmQoIm5ld2xpbmVBbmRJbmRlbnQiKSx2b2lkIDA7dmFyIGw9blsxXSxhPW5bNF0scz1lLmluZGV4T2YoblsyXSk+PTA/blsyXTpwYXJzZUludChuWzNdLDEwKSsxKyIuIjtyLnJlcGxhY2VTZWxlY3Rpb24oIlxuIitsK3MrYSwiZW5kIil9fSgpLENvZGVNaXJyb3IuZGVmaW5lTW9kZSgibWFya2Rvd24iLGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gcih0LGUscil7cmV0dXJuIGUuZj1lLmlubGluZT1yLHIodCxlKX1mdW5jdGlvbiBuKHQsZSxyKXtyZXR1cm4gZS5mPWUuYmxvY2s9cixyKHQsZSl9ZnVuY3Rpb24gaSh0KXtyZXR1cm4gdC5saW5rVGl0bGU9ITEsdC5lbT0hMSx0LnN0cm9uZz0hMSx0LnF1b3RlPTAsZ3x8dC5mIT1sfHwodC5mPWMsdC5ibG9jaz1vKSx0LnRyYWlsaW5nU3BhY2U9MCx0LnRyYWlsaW5nU3BhY2VOZXdMaW5lPSExLHQudGhpc0xpbmVIYXNDb250ZW50PSExLG51bGx9ZnVuY3Rpb24gbyh0LGkpe3ZhciBvPWkubGlzdCE9PSExO2kubGlzdCE9PSExJiZpLmluZGVudGF0aW9uRGlmZj49MD8oaS5pbmRlbnRhdGlvbkRpZmY8NCYmKGkuaW5kZW50YXRpb24tPWkuaW5kZW50YXRpb25EaWZmKSxpLmxpc3Q9bnVsbCk6aS5saXN0IT09ITEmJmkuaW5kZW50YXRpb24+MD8oaS5saXN0PW51bGwsaS5saXN0RGVwdGg9TWF0aC5mbG9vcihpLmluZGVudGF0aW9uLzQpKTppLmxpc3QhPT0hMSYmKGkubGlzdD0hMSxpLmxpc3REZXB0aD0wKTt2YXIgbD1udWxsO2lmKGkuaW5kZW50YXRpb25EaWZmPj00KXJldHVybiBpLmluZGVudGF0aW9uLT00LHQuc2tpcFRvRW5kKCksaztpZih0LmVhdFNwYWNlKCkpcmV0dXJuIG51bGw7aWYobD10Lm1hdGNoKFIpKWkuaGVhZGVyPWxbMF0ubGVuZ3RoPD02P2xbMF0ubGVuZ3RoOjY7ZWxzZSBpZihpLnByZXZMaW5lSGFzQ29udGVudCYmKGw9dC5tYXRjaChHKSkpaS5oZWFkZXI9Ij0iPT1sWzBdLmNoYXJBdCgwKT8xOjI7ZWxzZSBpZih0LmVhdCgiPiIpKWZvcihpLmluZGVudGF0aW9uKyssaS5xdW90ZT0xLHQuZWF0U3BhY2UoKTt0LmVhdCgiPiIpOyl0LmVhdFNwYWNlKCksaS5xdW90ZSsrO2Vsc2V7aWYoIlsiPT09dC5wZWVrKCkpcmV0dXJuIHIodCxpLGgpO2lmKHQubWF0Y2goSSwhMCkpcmV0dXJuIEE7aWYoaS5wcmV2TGluZUhhc0NvbnRlbnQmJiFvfHwhdC5tYXRjaChQLCEwKSYmIXQubWF0Y2goRiwhMCkpe2lmKGUuZmVuY2VkQ29kZUJsb2NrcyYmdC5tYXRjaCgvXmBgYChbXHcrI10qKS8sITApKXJldHVybiBpLmxvY2FsTW9kZT14KFJlZ0V4cC4kMSksaS5sb2NhbE1vZGUmJihpLmxvY2FsU3RhdGU9aS5sb2NhbE1vZGUuc3RhcnRTdGF0ZSgpKSxuKHQsaSxhKSxrfWVsc2UgaS5pbmRlbnRhdGlvbis9NCxpLmxpc3Q9ITAsaS5saXN0RGVwdGgrKyxlLnRhc2tMaXN0cyYmdC5tYXRjaChCLCExKSYmKGkudGFza0xpc3Q9ITApfXJldHVybiByKHQsaSxpLmlubGluZSl9ZnVuY3Rpb24gbCh0LGUpe3ZhciByPXYudG9rZW4odCxlLmh0bWxTdGF0ZSk7cmV0dXJuIGcmJiJ0YWciPT09ciYmIm9wZW5UYWciIT09ZS5odG1sU3RhdGUudHlwZSYmIWUuaHRtbFN0YXRlLmNvbnRleHQmJihlLmY9YyxlLmJsb2NrPW8pLGUubWRfaW5zaWRlJiYtMSE9dC5jdXJyZW50KCkuaW5kZXhPZigiPiIpJiYoZS5mPWMsZS5ibG9jaz1vLGUuaHRtbFN0YXRlLmNvbnRleHQ9dm9pZCAwKSxyfWZ1bmN0aW9uIGEodCxlKXtyZXR1cm4gdC5zb2woKSYmdC5tYXRjaCgvXmBgYC8sITApPyhlLmxvY2FsTW9kZT1lLmxvY2FsU3RhdGU9bnVsbCxlLmY9YyxlLmJsb2NrPW8sayk6ZS5sb2NhbE1vZGU/ZS5sb2NhbE1vZGUudG9rZW4odCxlLmxvY2FsU3RhdGUpOih0LnNraXBUb0VuZCgpLGspfWZ1bmN0aW9uIHModCl7dmFyIGU9W107aWYodC50YXNrT3BlbilyZXR1cm4ibWV0YSI7aWYodC50YXNrQ2xvc2VkKXJldHVybiJwcm9wZXJ0eSI7aWYodC5zdHJvbmcmJmUucHVzaCh6KSx0LmVtJiZlLnB1c2goRSksdC5saW5rVGV4dCYmZS5wdXNoKE8pLHQuY29kZSYmZS5wdXNoKGspLHQuaGVhZGVyJiYoZS5wdXNoKEMpLGUucHVzaChDK3QuaGVhZGVyKSksdC5xdW90ZSYmZS5wdXNoKHQucXVvdGUlMj93OkwpLHQubGlzdCE9PSExKXt2YXIgcj0odC5saXN0RGVwdGgtMSklMztyPzE9PT1yP2UucHVzaChNKTplLnB1c2goVCk6ZS5wdXNoKFMpfXJldHVybiB0LnRyYWlsaW5nU3BhY2VOZXdMaW5lP2UucHVzaCgidHJhaWxpbmctc3BhY2UtbmV3LWxpbmUiKTp0LnRyYWlsaW5nU3BhY2UmJmUucHVzaCgidHJhaWxpbmctc3BhY2UtIisodC50cmFpbGluZ1NwYWNlJTI/ImEiOiJiIikpLGUubGVuZ3RoP2Uuam9pbigiICIpOm51bGx9ZnVuY3Rpb24gdSh0LGUpe3JldHVybiB0Lm1hdGNoKF8sITApP3MoZSk6dm9pZCAwfWZ1bmN0aW9uIGModCxpKXt2YXIgbz1pLnRleHQodCxpKTtpZigidW5kZWZpbmVkIiE9dHlwZW9mIG8pcmV0dXJuIG87aWYoaS5saXN0KXJldHVybiBpLmxpc3Q9bnVsbCxzKGkpO2lmKGkudGFza0xpc3Qpe3ZhciBhPSJ4IiE9PXQubWF0Y2goQiwhMClbMV07cmV0dXJuIGE/aS50YXNrT3Blbj0hMDppLnRhc2tDbG9zZWQ9ITAsaS50YXNrTGlzdD0hMSxzKGkpfWkudGFza09wZW49ITEsaS50YXNrQ2xvc2VkPSExO3ZhciB1PXQuc29sKCksYz10Lm5leHQoKTtpZigiXFwiPT09YylyZXR1cm4gdC5uZXh0KCkscyhpKTtpZihpLmxpbmtUaXRsZSl7aS5saW5rVGl0bGU9ITE7dmFyIGg9YzsiKCI9PT1jJiYoaD0iKSIpLGg9KGgrIiIpLnJlcGxhY2UoLyhbLj8qK14kW1xdXFwoKXt9fC1dKS9nLCJcXCQxIik7dmFyIGQ9Il5cXHMqKD86W14iK2grIlxcXFxdK3xcXFxcXFxcXHxcXFxcLikiK2g7aWYodC5tYXRjaChuZXcgUmVnRXhwKGQpLCEwKSlyZXR1cm4gV31pZigiYCI9PT1jKXt2YXIgcD1zKGkpLGc9dC5wb3M7dC5lYXRXaGlsZSgiYCIpO3ZhciB2PTErdC5wb3MtZztyZXR1cm4gaS5jb2RlP3Y9PT1iPyhpLmNvZGU9ITEscCk6cyhpKTooYj12LGkuY29kZT0hMCxzKGkpKX1pZihpLmNvZGUpcmV0dXJuIHMoaSk7aWYoIiEiPT09YyYmdC5tYXRjaCgvXFtbXlxdXSpcXSA/KD86XCh8XFspLywhMSkpcmV0dXJuIHQubWF0Y2goL1xbW15cXV0qXF0vKSxpLmlubGluZT1pLmY9ZixOO2lmKCJbIj09PWMmJnQubWF0Y2goLy4qXF0oXCh8ID9cWykvLCExKSlyZXR1cm4gaS5saW5rVGV4dD0hMCxzKGkpO2lmKCJdIj09PWMmJmkubGlua1RleHQpe3ZhciB5PXMoaSk7cmV0dXJuIGkubGlua1RleHQ9ITEsaS5pbmxpbmU9aS5mPWYseX1pZigiPCI9PT1jJiZ0Lm1hdGNoKC9eKGh0dHBzP3xmdHBzPyk6XC9cLyg/OlteXFw+XXxcXC4pKz4vLCExKSlyZXR1cm4gcih0LGksbShILCI+IikpO2lmKCI8Ij09PWMmJnQubWF0Y2goL15bXj4gXFxdK0AoPzpbXlxcPl18XFwuKSs+LywhMSkpcmV0dXJuIHIodCxpLG0oRCwiPiIpKTtpZigiPCI9PT1jJiZ0Lm1hdGNoKC9eXHcvLCExKSl7aWYoLTEhPXQuc3RyaW5nLmluZGV4T2YoIj4iKSl7dmFyIHg9dC5zdHJpbmcuc3Vic3RyaW5nKDEsdC5zdHJpbmcuaW5kZXhPZigiPiIpKTsvbWFya2Rvd25ccyo9XHMqKCd8Iil7MCwxfTEoJ3wiKXswLDF9Ly50ZXN0KHgpJiYoaS5tZF9pbnNpZGU9ITApfXJldHVybiB0LmJhY2tVcCgxKSxuKHQsaSxsKX1pZigiPCI9PT1jJiZ0Lm1hdGNoKC9eXC9cdyo/Pi8pKXJldHVybiBpLm1kX2luc2lkZT0hMSwidGFnIjt2YXIgQz0hMTtpZighZS51bmRlcnNjb3Jlc0JyZWFrV29yZHMmJiJfIj09PWMmJiJfIiE9PXQucGVlaygpJiZ0Lm1hdGNoKC8oXHcpLywhMSkpe3ZhciBrPXQucG9zLTI7aWYoaz49MCl7dmFyIHc9dC5zdHJpbmcuY2hhckF0KGspOyJfIiE9PXcmJncubWF0Y2goLyhcdykvLCExKSYmKEM9ITApfX12YXIgcD1zKGkpO2lmKCIqIj09PWN8fCJfIj09PWMmJiFDKWlmKHUmJiIgIj09PXQucGVlaygpKTtlbHNle2lmKGkuc3Ryb25nPT09YyYmdC5lYXQoYykpcmV0dXJuIGkuc3Ryb25nPSExLHA7aWYoIWkuc3Ryb25nJiZ0LmVhdChjKSlyZXR1cm4gaS5zdHJvbmc9YyxzKGkpO2lmKGkuZW09PT1jKXJldHVybiBpLmVtPSExLHA7aWYoIWkuZW0pcmV0dXJuIGkuZW09YyxzKGkpfWVsc2UgaWYoIiAiPT09YyYmKHQuZWF0KCIqIil8fHQuZWF0KCJfIikpKXtpZigiICI9PT10LnBlZWsoKSlyZXR1cm4gcyhpKTt0LmJhY2tVcCgxKX1yZXR1cm4iICI9PT1jJiYodC5tYXRjaCgvICskLywhMSk/aS50cmFpbGluZ1NwYWNlKys6aS50cmFpbGluZ1NwYWNlJiYoaS50cmFpbGluZ1NwYWNlTmV3TGluZT0hMCkpLHMoaSl9ZnVuY3Rpb24gZih0LGUpe2lmKHQuZWF0U3BhY2UoKSlyZXR1cm4gbnVsbDt2YXIgbj10Lm5leHQoKTtyZXR1cm4iKCI9PT1ufHwiWyI9PT1uP3IodCxlLG0oVywiKCI9PT1uPyIpIjoiXSIpKToiZXJyb3IifWZ1bmN0aW9uIGgodCxlKXtyZXR1cm4gdC5tYXRjaCgvXlteXF1dKlxdOi8sITApPyhlLmY9ZCxPKTpyKHQsZSxjKX1mdW5jdGlvbiBkKHQsZSl7cmV0dXJuIHQuZWF0U3BhY2UoKT9udWxsOih0Lm1hdGNoKC9eW15cc10rLywhMCksdm9pZCAwPT09dC5wZWVrKCk/ZS5saW5rVGl0bGU9ITA6dC5tYXRjaCgvXig/OlxzKyg/OiIoPzpbXiJcXF18XFxcXHxcXC4pKyJ8Jyg/OlteJ1xcXXxcXFxcfFxcLikrJ3xcKCg/OlteKVxcXXxcXFxcfFxcLikrXCkpKT8vLCEwKSxlLmY9ZS5pbmxpbmU9YyxXKX1mdW5jdGlvbiBwKHQpe3JldHVybiBWW3RdfHwodD0odCsiIikucmVwbGFjZSgvKFsuPyorXiRbXF1cXCgpe318LV0pL2csIlxcJDEiKSxWW3RdPW5ldyBSZWdFeHAoIl4oPzpbXlxcXFxdfFxcXFwuKSo/KCIrdCsiKSIpKSxWW3RdfWZ1bmN0aW9uIG0odCxlLHIpe3JldHVybiByPXJ8fGMsZnVuY3Rpb24obixpKXtyZXR1cm4gbi5tYXRjaChwKGUpKSxpLmlubGluZT1pLmY9cix0fX12YXIgZz1Db2RlTWlycm9yLm1vZGVzLmhhc093blByb3BlcnR5KCJ4bWwiKSx2PUNvZGVNaXJyb3IuZ2V0TW9kZSh0LGc/e25hbWU6InhtbCIsaHRtbE1vZGU6ITB9OiJ0ZXh0L3BsYWluIikseT17aHRtbDoiaHRtbG1peGVkIixqczoiamF2YXNjcmlwdCIsanNvbjoiYXBwbGljYXRpb24vanNvbiIsYzoidGV4dC94LWNzcmMiLCJjKysiOiJ0ZXh0L3gtYysrc3JjIixqYXZhOiJ0ZXh0L3gtamF2YSIsY3NoYXJwOiJ0ZXh0L3gtY3NoYXJwIiwiYyMiOiJ0ZXh0L3gtY3NoYXJwIixzY2FsYToidGV4dC94LXNjYWxhIn0seD1mdW5jdGlvbigpe3ZhciBlLHIsbj17fSxpPXt9LG89W107Zm9yKHZhciBsIGluIENvZGVNaXJyb3IubW9kZXMpQ29kZU1pcnJvci5tb2Rlcy5wcm9wZXJ0eUlzRW51bWVyYWJsZShsKSYmby5wdXNoKGwpO2ZvcihlPTA7ZTxvLmxlbmd0aDtlKyspbltvW2VdXT1vW2VdO3ZhciBhPVtdO2Zvcih2YXIgbCBpbiBDb2RlTWlycm9yLm1pbWVNb2RlcylDb2RlTWlycm9yLm1pbWVNb2Rlcy5wcm9wZXJ0eUlzRW51bWVyYWJsZShsKSYmYS5wdXNoKHttaW1lOmwsbW9kZTpDb2RlTWlycm9yLm1pbWVNb2Rlc1tsXX0pO2ZvcihlPTA7ZTxhLmxlbmd0aDtlKyspcj1hW2VdLm1pbWUsaVtyXT1hW2VdLm1pbWU7Zm9yKHZhciBzIGluIHkpKHlbc11pbiBufHx5W3NdaW4gaSkmJihuW3NdPXlbc10pO3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gbltlXT9Db2RlTWlycm9yLmdldE1vZGUodCxuW2VdKTpudWxsfX0oKTt2b2lkIDA9PT1lLnVuZGVyc2NvcmVzQnJlYWtXb3JkcyYmKGUudW5kZXJzY29yZXNCcmVha1dvcmRzPSEwKSx2b2lkIDA9PT1lLmZlbmNlZENvZGVCbG9ja3MmJihlLmZlbmNlZENvZGVCbG9ja3M9ITEpLHZvaWQgMD09PWUudGFza0xpc3RzJiYoZS50YXNrTGlzdHM9ITEpO3ZhciBiPTAsQz0iaGVhZGVyIixrPSJjb21tZW50Iix3PSJhdG9tIixMPSJudW1iZXIiLFM9InZhcmlhYmxlLTIiLE09InZhcmlhYmxlLTMiLFQ9ImtleXdvcmQiLEE9ImhyIixOPSJ0YWciLEg9ImxpbmsiLEQ9ImxpbmsiLE89ImxpbmsiLFc9InN0cmluZyIsRT0iZW0iLHo9InN0cm9uZyIsST0vXihbKlwtPV9dKSg/OlxzKlwxKXsyLH1ccyokLyxQPS9eWypcLStdXHMrLyxGPS9eWzAtOV0rXC5ccysvLEI9L15cWyh4fCApXF0oPz1ccykvLFI9L14jKy8sRz0vXig/Olw9ezEsfXwtezEsfSkkLyxfPS9eW14hXFtcXSpfXFw8PmAgIicoXSsvLFY9W107cmV0dXJue3N0YXJ0U3RhdGU6ZnVuY3Rpb24oKXtyZXR1cm57ZjpvLHByZXZMaW5lSGFzQ29udGVudDohMSx0aGlzTGluZUhhc0NvbnRlbnQ6ITEsYmxvY2s6byxodG1sU3RhdGU6Q29kZU1pcnJvci5zdGFydFN0YXRlKHYpLGluZGVudGF0aW9uOjAsaW5saW5lOmMsdGV4dDp1LGxpbmtUZXh0OiExLGxpbmtUaXRsZTohMSxlbTohMSxzdHJvbmc6ITEsaGVhZGVyOjAsdGFza0xpc3Q6ITEsbGlzdDohMSxsaXN0RGVwdGg6MCxxdW90ZTowLHRyYWlsaW5nU3BhY2U6MCx0cmFpbGluZ1NwYWNlTmV3TGluZTohMX19LGNvcHlTdGF0ZTpmdW5jdGlvbih0KXtyZXR1cm57Zjp0LmYscHJldkxpbmVIYXNDb250ZW50OnQucHJldkxpbmVIYXNDb250ZW50LHRoaXNMaW5lSGFzQ29udGVudDp0LnRoaXNMaW5lSGFzQ29udGVudCxibG9jazp0LmJsb2NrLGh0bWxTdGF0ZTpDb2RlTWlycm9yLmNvcHlTdGF0ZSh2LHQuaHRtbFN0YXRlKSxpbmRlbnRhdGlvbjp0LmluZGVudGF0aW9uLGxvY2FsTW9kZTp0LmxvY2FsTW9kZSxsb2NhbFN0YXRlOnQubG9jYWxNb2RlP0NvZGVNaXJyb3IuY29weVN0YXRlKHQubG9jYWxNb2RlLHQubG9jYWxTdGF0ZSk6bnVsbCxpbmxpbmU6dC5pbmxpbmUsdGV4dDp0LnRleHQsbGlua1RpdGxlOnQubGlua1RpdGxlLGVtOnQuZW0sc3Ryb25nOnQuc3Ryb25nLGhlYWRlcjp0LmhlYWRlcix0YXNrTGlzdDp0LnRhc2tMaXN0LGxpc3Q6dC5saXN0LGxpc3REZXB0aDp0Lmxpc3REZXB0aCxxdW90ZTp0LnF1b3RlLHRyYWlsaW5nU3BhY2U6dC50cmFpbGluZ1NwYWNlLHRyYWlsaW5nU3BhY2VOZXdMaW5lOnQudHJhaWxpbmdTcGFjZU5ld0xpbmUsbWRfaW5zaWRlOnQubWRfaW5zaWRlfX0sdG9rZW46ZnVuY3Rpb24odCxlKXtpZih0LnNvbCgpKXtpZih0Lm1hdGNoKC9eXHMqJC8sITApKXJldHVybiBlLnByZXZMaW5lSGFzQ29udGVudD0hMSxpKGUpO2UucHJldkxpbmVIYXNDb250ZW50PWUudGhpc0xpbmVIYXNDb250ZW50LGUudGhpc0xpbmVIYXNDb250ZW50PSEwLGUuaGVhZGVyPTAsZS50YXNrTGlzdD0hMSxlLmNvZGU9ITEsZS50cmFpbGluZ1NwYWNlPTAsZS50cmFpbGluZ1NwYWNlTmV3TGluZT0hMSxlLmY9ZS5ibG9jazt2YXIgcj10Lm1hdGNoKC9eXHMqLywhMClbMF0ucmVwbGFjZSgvXHQvZywiICAgICIpLmxlbmd0aCxuPTQqTWF0aC5mbG9vcigoci1lLmluZGVudGF0aW9uKS80KTtuPjQmJihuPTQpO3ZhciBvPWUuaW5kZW50YXRpb24rbjtpZihlLmluZGVudGF0aW9uRGlmZj1vLWUuaW5kZW50YXRpb24sZS5pbmRlbnRhdGlvbj1vLHI+MClyZXR1cm4gbnVsbH1yZXR1cm4gZS5mKHQsZSl9LGJsYW5rTGluZTppLGdldFR5cGU6c319LCJ4bWwiKSxDb2RlTWlycm9yLmRlZmluZU1JTUUoInRleHQveC1tYXJrZG93biIsIm1hcmtkb3duIiksQ29kZU1pcnJvci5kZWZpbmVNb2RlKCJ4bWwiLGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gcih0LGUpe2Z1bmN0aW9uIHIocil7cmV0dXJuIGUudG9rZW5pemU9cixyKHQsZSl9dmFyIGk9dC5uZXh0KCk7aWYoIjwiPT1pKXtpZih0LmVhdCgiISIpKXJldHVybiB0LmVhdCgiWyIpP3QubWF0Y2goIkNEQVRBWyIpP3IobygiYXRvbSIsIl1dPiIpKTpudWxsOnQubWF0Y2goIi0tIik/cihvKCJjb21tZW50IiwiLS0+IikpOnQubWF0Y2goIkRPQ1RZUEUiLCEwLCEwKT8odC5lYXRXaGlsZSgvW1x3XC5fXC1dLykscihsKDEpKSk6bnVsbDtpZih0LmVhdCgiPyIpKXJldHVybiB0LmVhdFdoaWxlKC9bXHdcLl9cLV0vKSxlLnRva2VuaXplPW8oIm1ldGEiLCI/PiIpLCJtZXRhIjt2YXIgYT10LmVhdCgiLyIpO3g9IiI7Zm9yKHZhciBzO3M9dC5lYXQoL1teXHNcdTAwYTA9PD5cIlwnXC8/XS8pOyl4Kz1zO3JldHVybiB4PyhiPWE/ImNsb3NlVGFnIjoib3BlblRhZyIsZS50b2tlbml6ZT1uLCJ0YWciKToidGFnIGVycm9yIn1pZigiJiI9PWkpe3ZhciB1O3JldHVybiB1PXQuZWF0KCIjIik/dC5lYXQoIngiKT90LmVhdFdoaWxlKC9bYS1mQS1GXGRdLykmJnQuZWF0KCI7Iik6dC5lYXRXaGlsZSgvW1xkXS8pJiZ0LmVhdCgiOyIpOnQuZWF0V2hpbGUoL1tcd1wuXC06XS8pJiZ0LmVhdCgiOyIpLHU/ImF0b20iOiJlcnJvciJ9cmV0dXJuIHQuZWF0V2hpbGUoL1teJjxdLyksbnVsbH1mdW5jdGlvbiBuKHQsZSl7dmFyIG49dC5uZXh0KCk7aWYoIj4iPT1ufHwiLyI9PW4mJnQuZWF0KCI+IikpcmV0dXJuIGUudG9rZW5pemU9cixiPSI+Ij09bj8iZW5kVGFnIjoic2VsZmNsb3NlVGFnIiwidGFnIjtpZigiPSI9PW4pcmV0dXJuIGI9ImVxdWFscyIsbnVsbDtpZigiPCI9PW4pe2UudG9rZW5pemU9cjt2YXIgbz1lLnRva2VuaXplKHQsZSk7cmV0dXJuIG8/bysiIGVycm9yIjoiZXJyb3IifXJldHVybi9bXCdcIl0vLnRlc3Qobik/KGUudG9rZW5pemU9aShuKSxlLnN0cmluZ1N0YXJ0Q29sPXQuY29sdW1uKCksZS50b2tlbml6ZSh0LGUpKToodC5lYXRXaGlsZSgvW15cc1x1MDBhMD08PlwiXCddLyksIndvcmQiKX1mdW5jdGlvbiBpKHQpe3ZhciBlPWZ1bmN0aW9uKGUscil7Zm9yKDshZS5lb2woKTspaWYoZS5uZXh0KCk9PXQpe3IudG9rZW5pemU9bjticmVha31yZXR1cm4ic3RyaW5nIn07cmV0dXJuIGUuaXNJbkF0dHJpYnV0ZT0hMCxlfWZ1bmN0aW9uIG8odCxlKXtyZXR1cm4gZnVuY3Rpb24obixpKXtmb3IoOyFuLmVvbCgpOyl7aWYobi5tYXRjaChlKSl7aS50b2tlbml6ZT1yO2JyZWFrfW4ubmV4dCgpfXJldHVybiB0fX1mdW5jdGlvbiBsKHQpe3JldHVybiBmdW5jdGlvbihlLG4pe2Zvcih2YXIgaTtudWxsIT0oaT1lLm5leHQoKSk7KXtpZigiPCI9PWkpcmV0dXJuIG4udG9rZW5pemU9bCh0KzEpLG4udG9rZW5pemUoZSxuKTtpZigiPiI9PWkpe2lmKDE9PXQpe24udG9rZW5pemU9cjticmVha31yZXR1cm4gbi50b2tlbml6ZT1sKHQtMSksbi50b2tlbml6ZShlLG4pfX1yZXR1cm4ibWV0YSJ9fWZ1bmN0aW9uIGEoKXtmb3IodmFyIHQ9YXJndW1lbnRzLmxlbmd0aC0xO3Q+PTA7dC0tKUMuY2MucHVzaChhcmd1bWVudHNbdF0pfWZ1bmN0aW9uIHMoKXtyZXR1cm4gYS5hcHBseShudWxsLGFyZ3VtZW50cyksITB9ZnVuY3Rpb24gdSh0LGUpe3ZhciByPVQuZG9Ob3RJbmRlbnQuaGFzT3duUHJvcGVydHkodCl8fEMuY29udGV4dCYmQy5jb250ZXh0Lm5vSW5kZW50O0MuY29udGV4dD17cHJldjpDLmNvbnRleHQsdGFnTmFtZTp0LGluZGVudDpDLmluZGVudGVkLHN0YXJ0T2ZMaW5lOmUsbm9JbmRlbnQ6cn19ZnVuY3Rpb24gYygpe0MuY29udGV4dCYmKEMuY29udGV4dD1DLmNvbnRleHQucHJldil9ZnVuY3Rpb24gZih0KXtpZigib3BlblRhZyI9PXQpcmV0dXJuIEMudGFnTmFtZT14LEMudGFnU3RhcnQ9ay5jb2x1bW4oKSxzKG0saChDLnN0YXJ0T2ZMaW5lKSk7aWYoImNsb3NlVGFnIj09dCl7dmFyIGU9ITE7cmV0dXJuIEMuY29udGV4dD9DLmNvbnRleHQudGFnTmFtZSE9eCYmKFQuaW1wbGljaXRseUNsb3NlZC5oYXNPd25Qcm9wZXJ0eShDLmNvbnRleHQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSYmYygpLGU9IUMuY29udGV4dHx8Qy5jb250ZXh0LnRhZ05hbWUhPXgpOmU9ITAsZSYmKHc9ImVycm9yIikscyhkKGUpKX1yZXR1cm4gcygpfWZ1bmN0aW9uIGgodCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3ZhciByPUMudGFnTmFtZTtyZXR1cm4gQy50YWdOYW1lPUMudGFnU3RhcnQ9bnVsbCwic2VsZmNsb3NlVGFnIj09ZXx8ImVuZFRhZyI9PWUmJlQuYXV0b1NlbGZDbG9zZXJzLmhhc093blByb3BlcnR5KHIudG9Mb3dlckNhc2UoKSk/KHAoci50b0xvd2VyQ2FzZSgpKSxzKCkpOiJlbmRUYWciPT1lPyhwKHIudG9Mb3dlckNhc2UoKSksdShyLHQpLHMoKSk6cygpfX1mdW5jdGlvbiBkKHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gdCYmKHc9ImVycm9yIiksImVuZFRhZyI9PWU/KGMoKSxzKCkpOih3PSJlcnJvciIscyhhcmd1bWVudHMuY2FsbGVlKSl9fWZ1bmN0aW9uIHAodCl7Zm9yKHZhciBlOzspe2lmKCFDLmNvbnRleHQpcmV0dXJuO2lmKGU9Qy5jb250ZXh0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSwhVC5jb250ZXh0R3JhYmJlcnMuaGFzT3duUHJvcGVydHkoZSl8fCFULmNvbnRleHRHcmFiYmVyc1tlXS5oYXNPd25Qcm9wZXJ0eSh0KSlyZXR1cm47YygpfX1mdW5jdGlvbiBtKHQpe3JldHVybiJ3b3JkIj09dD8odz0iYXR0cmlidXRlIixzKGcsbSkpOiJlbmRUYWciPT10fHwic2VsZmNsb3NlVGFnIj09dD9hKCk6KHc9ImVycm9yIixzKG0pKX1mdW5jdGlvbiBnKHQpe2lmKCJlcXVhbHMiPT10KXJldHVybiBzKHYsbSk7aWYoVC5hbGxvd01pc3Npbmcpe2lmKCJ3b3JkIj09dClyZXR1cm4gdz0iYXR0cmlidXRlIixzKGcsbSl9ZWxzZSB3PSJlcnJvciI7cmV0dXJuImVuZFRhZyI9PXR8fCJzZWxmY2xvc2VUYWciPT10P2EoKTpzKCl9ZnVuY3Rpb24gdih0KXtyZXR1cm4ic3RyaW5nIj09dD9zKHkpOiJ3b3JkIj09dCYmVC5hbGxvd1VucXVvdGVkPyh3PSJzdHJpbmciLHMoKSk6KHc9ImVycm9yIiwiZW5kVGFnIj09dHx8InNlbGZDbG9zZVRhZyI9PXQ/YSgpOnMoKSl9ZnVuY3Rpb24geSh0KXtyZXR1cm4ic3RyaW5nIj09dD9zKHkpOmEoKX12YXIgeCxiLEMsayx3LEw9dC5pbmRlbnRVbml0LFM9ZS5tdWx0aWxpbmVUYWdJbmRlbnRGYWN0b3J8fDEsTT1lLm11bHRpbGluZVRhZ0luZGVudFBhc3RUYWd8fCEwLFQ9ZS5odG1sTW9kZT97YXV0b1NlbGZDbG9zZXJzOnthcmVhOiEwLGJhc2U6ITAsYnI6ITAsY29sOiEwLGNvbW1hbmQ6ITAsZW1iZWQ6ITAsZnJhbWU6ITAsaHI6ITAsaW1nOiEwLGlucHV0OiEwLGtleWdlbjohMCxsaW5rOiEwLG1ldGE6ITAscGFyYW06ITAsc291cmNlOiEwLHRyYWNrOiEwLHdicjohMH0saW1wbGljaXRseUNsb3NlZDp7ZGQ6ITAsbGk6ITAsb3B0Z3JvdXA6ITAsb3B0aW9uOiEwLHA6ITAscnA6ITAscnQ6ITAsdGJvZHk6ITAsdGQ6ITAsdGZvb3Q6ITAsdGg6ITAsdHI6ITB9LGNvbnRleHRHcmFiYmVyczp7ZGQ6e2RkOiEwLGR0OiEwfSxkdDp7ZGQ6ITAsZHQ6ITB9LGxpOntsaTohMH0sb3B0aW9uOntvcHRpb246ITAsb3B0Z3JvdXA6ITB9LG9wdGdyb3VwOntvcHRncm91cDohMH0scDp7YWRkcmVzczohMCxhcnRpY2xlOiEwLGFzaWRlOiEwLGJsb2NrcXVvdGU6ITAsZGlyOiEwLGRpdjohMCxkbDohMCxmaWVsZHNldDohMCxmb290ZXI6ITAsZm9ybTohMCxoMTohMCxoMjohMCxoMzohMCxoNDohMCxoNTohMCxoNjohMCxoZWFkZXI6ITAsaGdyb3VwOiEwLGhyOiEwLG1lbnU6ITAsbmF2OiEwLG9sOiEwLHA6ITAscHJlOiEwLHNlY3Rpb246ITAsdGFibGU6ITAsdWw6ITB9LHJwOntycDohMCxydDohMH0scnQ6e3JwOiEwLHJ0OiEwfSx0Ym9keTp7dGJvZHk6ITAsdGZvb3Q6ITB9LHRkOnt0ZDohMCx0aDohMH0sdGZvb3Q6e3Rib2R5OiEwfSx0aDp7dGQ6ITAsdGg6ITB9LHRoZWFkOnt0Ym9keTohMCx0Zm9vdDohMH0sdHI6e3RyOiEwfX0sZG9Ob3RJbmRlbnQ6e3ByZTohMH0sYWxsb3dVbnF1b3RlZDohMCxhbGxvd01pc3Npbmc6ITB9OnthdXRvU2VsZkNsb3NlcnM6e30saW1wbGljaXRseUNsb3NlZDp7fSxjb250ZXh0R3JhYmJlcnM6e30sZG9Ob3RJbmRlbnQ6e30sYWxsb3dVbnF1b3RlZDohMSxhbGxvd01pc3Npbmc6ITF9LEE9ZS5hbGlnbkNEQVRBO3JldHVybntzdGFydFN0YXRlOmZ1bmN0aW9uKCl7cmV0dXJue3Rva2VuaXplOnIsY2M6W10saW5kZW50ZWQ6MCxzdGFydE9mTGluZTohMCx0YWdOYW1lOm51bGwsdGFnU3RhcnQ6bnVsbCxjb250ZXh0Om51bGx9fSx0b2tlbjpmdW5jdGlvbih0LGUpe2lmKCFlLnRhZ05hbWUmJnQuc29sKCkmJihlLnN0YXJ0T2ZMaW5lPSEwLGUuaW5kZW50ZWQ9dC5pbmRlbnRhdGlvbigpKSx0LmVhdFNwYWNlKCkpcmV0dXJuIG51bGw7dz1iPXg9bnVsbDt2YXIgcj1lLnRva2VuaXplKHQsZSk7aWYoZS50eXBlPWIsKHJ8fGIpJiYiY29tbWVudCIhPXIpZm9yKEM9ZSxrPXQ7Oyl7dmFyIG49ZS5jYy5wb3AoKXx8ZjtpZihuKGJ8fHIpKWJyZWFrfXJldHVybiBlLnN0YXJ0T2ZMaW5lPSExLHcmJihyPSJlcnJvciI9PXc/cisiIGVycm9yIjp3KSxyfSxpbmRlbnQ6ZnVuY3Rpb24odCxlLGkpe3ZhciBvPXQuY29udGV4dDtpZih0LnRva2VuaXplLmlzSW5BdHRyaWJ1dGUpcmV0dXJuIHQuc3RyaW5nU3RhcnRDb2wrMTtpZih0LnRva2VuaXplIT1uJiZ0LnRva2VuaXplIT1yfHxvJiZvLm5vSW5kZW50KXJldHVybiBpP2kubWF0Y2goL14oXHMqKS8pWzBdLmxlbmd0aDowO2lmKHQudGFnTmFtZSlyZXR1cm4gTT90LnRhZ1N0YXJ0K3QudGFnTmFtZS5sZW5ndGgrMjp0LnRhZ1N0YXJ0K0wqUztpZihBJiYvPCFcW0NEQVRBXFsvLnRlc3QoZSkpcmV0dXJuIDA7Zm9yKG8mJi9ePFwvLy50ZXN0KGUpJiYobz1vLnByZXYpO28mJiFvLnN0YXJ0T2ZMaW5lOylvPW8ucHJldjtyZXR1cm4gbz9vLmluZGVudCtMOjB9LGVsZWN0cmljQ2hhcnM6Ii8iLGJsb2NrQ29tbWVudFN0YXJ0OiI8IS0tIixibG9ja0NvbW1lbnRFbmQ6Ii0tPiIsY29uZmlndXJhdGlvbjplLmh0bWxNb2RlPyJodG1sIjoieG1sIixoZWxwZXJUeXBlOmUuaHRtbE1vZGU/Imh0bWwiOiJ4bWwifX0pLENvZGVNaXJyb3IuZGVmaW5lTUlNRSgidGV4dC94bWwiLCJ4bWwiKSxDb2RlTWlycm9yLmRlZmluZU1JTUUoImFwcGxpY2F0aW9uL3htbCIsInhtbCIpLENvZGVNaXJyb3IubWltZU1vZGVzLmhhc093blByb3BlcnR5KCJ0ZXh0L2h0bWwiKXx8Q29kZU1pcnJvci5kZWZpbmVNSU1FKCJ0ZXh0L2h0bWwiLHtuYW1lOiJ4bWwiLGh0bWxNb2RlOiEwfSk7UEsHCJPWD12IMgAAiDIAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAHN0YXRpY1xsaWJcY29kZW1pcnJvci5taW4uanN3aW5kb3cuQ29kZU1pcnJvcj1mdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiB0KHIsbil7aWYoISh0aGlzIGluc3RhbmNlb2YgdCkpcmV0dXJuIG5ldyB0KHIsbik7dGhpcy5vcHRpb25zPW49bnx8e307Zm9yKHZhciBpIGluIGFvKSFuLmhhc093blByb3BlcnR5KGkpJiZhby5oYXNPd25Qcm9wZXJ0eShpKSYmKG5baV09YW9baV0pO2gobik7dmFyIG89InN0cmluZyI9PXR5cGVvZiBuLnZhbHVlPzA6bi52YWx1ZS5maXJzdCxsPXRoaXMuZGlzcGxheT1lKHIsbyk7bC53cmFwcGVyLkNvZGVNaXJyb3I9dGhpcyx1KHRoaXMpLG4uYXV0b2ZvY3VzJiYhVmkmJnBlKHRoaXMpLHRoaXMuc3RhdGU9e2tleU1hcHM6W10sb3ZlcmxheXM6W10sbW9kZUdlbjowLG92ZXJ3cml0ZTohMSxmb2N1c2VkOiExLHN1cHByZXNzRWRpdHM6ITEscGFzdGVJbmNvbWluZzohMSxkcmFnZ2luZ1RleHQ6ITEsaGlnaGxpZ2h0Om5ldyAkbn0scyh0aGlzKSxuLmxpbmVXcmFwcGluZyYmKHRoaXMuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZSs9IiBDb2RlTWlycm9yLXdyYXAiKTt2YXIgYT1uLnZhbHVlOyJzdHJpbmciPT10eXBlb2YgYSYmKGE9bmV3IHdvKG4udmFsdWUsbi5tb2RlKSksbGUodGhpcyxwbikodGhpcyxhKSxBaSYmc2V0VGltZW91dChpaShkZSx0aGlzLCEwKSwyMCksbWUodGhpcyk7dmFyIGM7dHJ5e2M9ZG9jdW1lbnQuYWN0aXZlRWxlbWVudD09bC5pbnB1dH1jYXRjaChmKXt9Y3x8bi5hdXRvZm9jdXMmJiFWaT9zZXRUaW1lb3V0KGlpKEVlLHRoaXMpLDIwKTp6ZSh0aGlzKSxsZSh0aGlzLGZ1bmN0aW9uKCl7Zm9yKHZhciB0IGluIHNvKXNvLnByb3BlcnR5SXNFbnVtZXJhYmxlKHQpJiZzb1t0XSh0aGlzLG5bdF0sdW8pO2Zvcih2YXIgZT0wO2U8cG8ubGVuZ3RoOysrZSlwb1tlXSh0aGlzKX0pKCl9ZnVuY3Rpb24gZSh0LGUpe3ZhciByPXt9LG49ci5pbnB1dD1zaSgidGV4dGFyZWEiLG51bGwsbnVsbCwicG9zaXRpb246IGFic29sdXRlOyBwYWRkaW5nOiAwOyB3aWR0aDogMXB4OyBoZWlnaHQ6IDFlbTsgb3V0bGluZTogbm9uZTsgZm9udC1zaXplOiA0cHg7Iik7cmV0dXJuIFdpP24uc3R5bGUud2lkdGg9IjEwMDBweCI6bi5zZXRBdHRyaWJ1dGUoIndyYXAiLCJvZmYiKSxHaSYmKG4uc3R5bGUuYm9yZGVyPSIxcHggc29saWQgYmxhY2siKSxuLnNldEF0dHJpYnV0ZSgiYXV0b2NvcnJlY3QiLCJvZmYiKSxuLnNldEF0dHJpYnV0ZSgiYXV0b2NhcGl0YWxpemUiLCJvZmYiKSxuLnNldEF0dHJpYnV0ZSgic3BlbGxjaGVjayIsImZhbHNlIiksci5pbnB1dERpdj1zaSgiZGl2Iixbbl0sbnVsbCwib3ZlcmZsb3c6IGhpZGRlbjsgcG9zaXRpb246IHJlbGF0aXZlOyB3aWR0aDogM3B4OyBoZWlnaHQ6IDBweDsiKSxyLnNjcm9sbGJhckg9c2koImRpdiIsW3NpKCJkaXYiLG51bGwsbnVsbCwiaGVpZ2h0OiAxcHgiKV0sIkNvZGVNaXJyb3ItaHNjcm9sbGJhciIpLHIuc2Nyb2xsYmFyVj1zaSgiZGl2Iixbc2koImRpdiIsbnVsbCxudWxsLCJ3aWR0aDogMXB4IildLCJDb2RlTWlycm9yLXZzY3JvbGxiYXIiKSxyLnNjcm9sbGJhckZpbGxlcj1zaSgiZGl2IixudWxsLCJDb2RlTWlycm9yLXNjcm9sbGJhci1maWxsZXIiKSxyLmd1dHRlckZpbGxlcj1zaSgiZGl2IixudWxsLCJDb2RlTWlycm9yLWd1dHRlci1maWxsZXIiKSxyLmxpbmVEaXY9c2koImRpdiIsbnVsbCwiQ29kZU1pcnJvci1jb2RlIiksci5zZWxlY3Rpb25EaXY9c2koImRpdiIsbnVsbCxudWxsLCJwb3NpdGlvbjogcmVsYXRpdmU7IHotaW5kZXg6IDEiKSxyLmN1cnNvcj1zaSgiZGl2IiwiwqAiLCJDb2RlTWlycm9yLWN1cnNvciIpLHIub3RoZXJDdXJzb3I9c2koImRpdiIsIsKgIiwiQ29kZU1pcnJvci1jdXJzb3IgQ29kZU1pcnJvci1zZWNvbmRhcnljdXJzb3IiKSxyLm1lYXN1cmU9c2koImRpdiIsbnVsbCwiQ29kZU1pcnJvci1tZWFzdXJlIiksci5saW5lU3BhY2U9c2koImRpdiIsW3IubWVhc3VyZSxyLnNlbGVjdGlvbkRpdixyLmxpbmVEaXYsci5jdXJzb3Isci5vdGhlckN1cnNvcl0sbnVsbCwicG9zaXRpb246IHJlbGF0aXZlOyBvdXRsaW5lOiBub25lIiksci5tb3Zlcj1zaSgiZGl2Iixbc2koImRpdiIsW3IubGluZVNwYWNlXSwiQ29kZU1pcnJvci1saW5lcyIpXSxudWxsLCJwb3NpdGlvbjogcmVsYXRpdmUiKSxyLnNpemVyPXNpKCJkaXYiLFtyLm1vdmVyXSwiQ29kZU1pcnJvci1zaXplciIpLHIuaGVpZ2h0Rm9yY2VyPXNpKCJkaXYiLG51bGwsbnVsbCwicG9zaXRpb246IGFic29sdXRlOyBoZWlnaHQ6ICIrVG8rInB4OyB3aWR0aDogMXB4OyIpLHIuZ3V0dGVycz1zaSgiZGl2IixudWxsLCJDb2RlTWlycm9yLWd1dHRlcnMiKSxyLmxpbmVHdXR0ZXI9bnVsbCxyLnNjcm9sbGVyPXNpKCJkaXYiLFtyLnNpemVyLHIuaGVpZ2h0Rm9yY2VyLHIuZ3V0dGVyc10sIkNvZGVNaXJyb3Itc2Nyb2xsIiksci5zY3JvbGxlci5zZXRBdHRyaWJ1dGUoInRhYkluZGV4IiwiLTEiKSxyLndyYXBwZXI9c2koImRpdiIsW3IuaW5wdXREaXYsci5zY3JvbGxiYXJILHIuc2Nyb2xsYmFyVixyLnNjcm9sbGJhckZpbGxlcixyLmd1dHRlckZpbGxlcixyLnNjcm9sbGVyXSwiQ29kZU1pcnJvciIpLEhpJiYoci5ndXR0ZXJzLnN0eWxlLnpJbmRleD0tMSxyLnNjcm9sbGVyLnN0eWxlLnBhZGRpbmdSaWdodD0wKSx0LmFwcGVuZENoaWxkP3QuYXBwZW5kQ2hpbGQoci53cmFwcGVyKTp0KHIud3JhcHBlciksR2kmJihuLnN0eWxlLndpZHRoPSIwcHgiKSxXaXx8KHIuc2Nyb2xsZXIuZHJhZ2dhYmxlPSEwKSxGaT8oci5pbnB1dERpdi5zdHlsZS5oZWlnaHQ9IjFweCIsci5pbnB1dERpdi5zdHlsZS5wb3NpdGlvbj0iYWJzb2x1dGUiKTpIaSYmKHIuc2Nyb2xsYmFySC5zdHlsZS5taW5XaWR0aD1yLnNjcm9sbGJhclYuc3R5bGUubWluV2lkdGg9IjE4cHgiKSxyLnZpZXdPZmZzZXQ9ci5sYXN0U2l6ZUM9MCxyLnNob3dpbmdGcm9tPXIuc2hvd2luZ1RvPWUsci5saW5lTnVtV2lkdGg9ci5saW5lTnVtSW5uZXJXaWR0aD1yLmxpbmVOdW1DaGFycz1udWxsLHIucHJldklucHV0PSIiLHIuYWxpZ25XaWRnZXRzPSExLHIucG9sbGluZ0Zhc3Q9ITEsci5wb2xsPW5ldyAkbixyLmNhY2hlZENoYXJXaWR0aD1yLmNhY2hlZFRleHRIZWlnaHQ9bnVsbCxyLm1lYXN1cmVMaW5lQ2FjaGU9W10sci5tZWFzdXJlTGluZUNhY2hlUG9zPTAsci5pbmFjY3VyYXRlU2VsZWN0aW9uPSExLHIubWF4TGluZT1udWxsLHIubWF4TGluZUxlbmd0aD0wLHIubWF4TGluZUNoYW5nZWQ9ITEsci53aGVlbERYPXIud2hlZWxEWT1yLndoZWVsU3RhcnRYPXIud2hlZWxTdGFydFk9bnVsbCxyfWZ1bmN0aW9uIHIoZSl7ZS5kb2MubW9kZT10LmdldE1vZGUoZS5vcHRpb25zLGUuZG9jLm1vZGVPcHRpb24pLGUuZG9jLml0ZXIoZnVuY3Rpb24odCl7dC5zdGF0ZUFmdGVyJiYodC5zdGF0ZUFmdGVyPW51bGwpLHQuc3R5bGVzJiYodC5zdHlsZXM9bnVsbCl9KSxlLmRvYy5mcm9udGllcj1lLmRvYy5maXJzdCxXKGUsMTAwKSxlLnN0YXRlLm1vZGVHZW4rKyxlLmN1ck9wJiZ1ZShlKX1mdW5jdGlvbiBuKHQpe3Qub3B0aW9ucy5saW5lV3JhcHBpbmc/KHQuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZSs9IiBDb2RlTWlycm9yLXdyYXAiLHQuZGlzcGxheS5zaXplci5zdHlsZS5taW5XaWR0aD0iIik6KHQuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZT10LmRpc3BsYXkud3JhcHBlci5jbGFzc05hbWUucmVwbGFjZSgiIENvZGVNaXJyb3Itd3JhcCIsIiIpLGYodCkpLG8odCksdWUodCksXyh0KSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZCh0KX0sMTAwKX1mdW5jdGlvbiBpKHQpe3ZhciBlPXJlKHQuZGlzcGxheSkscj10Lm9wdGlvbnMubGluZVdyYXBwaW5nLG49ciYmTWF0aC5tYXgoNSx0LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGgvbmUodC5kaXNwbGF5KS0zKTtyZXR1cm4gZnVuY3Rpb24oaSl7cmV0dXJuIFZyKHQuZG9jLGkpPzA6cj8oTWF0aC5jZWlsKGkudGV4dC5sZW5ndGgvbil8fDEpKmU6ZX19ZnVuY3Rpb24gbyh0KXt2YXIgZT10LmRvYyxyPWkodCk7ZS5pdGVyKGZ1bmN0aW9uKHQpe3ZhciBlPXIodCk7ZSE9dC5oZWlnaHQmJnluKHQsZSl9KX1mdW5jdGlvbiBsKHQpe3ZhciBlPXZvW3Qub3B0aW9ucy5rZXlNYXBdLHI9ZS5zdHlsZTt0LmRpc3BsYXkud3JhcHBlci5jbGFzc05hbWU9dC5kaXNwbGF5LndyYXBwZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xzKmNtLWtleW1hcC1cUysvZywiIikrKHI/IiBjbS1rZXltYXAtIityOiIiKSx0LnN0YXRlLmRpc2FibGVJbnB1dD1lLmRpc2FibGVJbnB1dH1mdW5jdGlvbiBzKHQpe3QuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZT10LmRpc3BsYXkud3JhcHBlci5jbGFzc05hbWUucmVwbGFjZSgvXHMqY20tcy1cUysvZywiIikrdC5vcHRpb25zLnRoZW1lLnJlcGxhY2UoLyhefFxzKVxzKi9nLCIgY20tcy0iKSxfKHQpfWZ1bmN0aW9uIGEodCl7dSh0KSx1ZSh0KSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Zyh0KX0sMjApfWZ1bmN0aW9uIHUodCl7dmFyIGU9dC5kaXNwbGF5Lmd1dHRlcnMscj10Lm9wdGlvbnMuZ3V0dGVyczthaShlKTtmb3IodmFyIG49MDtuPHIubGVuZ3RoOysrbil7dmFyIGk9cltuXSxvPWUuYXBwZW5kQ2hpbGQoc2koImRpdiIsbnVsbCwiQ29kZU1pcnJvci1ndXR0ZXIgIitpKSk7IkNvZGVNaXJyb3ItbGluZW51bWJlcnMiPT1pJiYodC5kaXNwbGF5LmxpbmVHdXR0ZXI9byxvLnN0eWxlLndpZHRoPSh0LmRpc3BsYXkubGluZU51bVdpZHRofHwxKSsicHgiKX1lLnN0eWxlLmRpc3BsYXk9bj8iIjoibm9uZSJ9ZnVuY3Rpb24gYyh0LGUpe2lmKDA9PWUuaGVpZ2h0KXJldHVybiAwO2Zvcih2YXIgcixuPWUudGV4dC5sZW5ndGgsaT1lO3I9UnIoaSk7KXt2YXIgbz1yLmZpbmQoKTtpPWduKHQsby5mcm9tLmxpbmUpLG4rPW8uZnJvbS5jaC1vLnRvLmNofWZvcihpPWU7cj1CcihpKTspe3ZhciBvPXIuZmluZCgpO24tPWkudGV4dC5sZW5ndGgtby5mcm9tLmNoLGk9Z24odCxvLnRvLmxpbmUpLG4rPWkudGV4dC5sZW5ndGgtby50by5jaH1yZXR1cm4gbn1mdW5jdGlvbiBmKHQpe3ZhciBlPXQuZGlzcGxheSxyPXQuZG9jO2UubWF4TGluZT1nbihyLHIuZmlyc3QpLGUubWF4TGluZUxlbmd0aD1jKHIsZS5tYXhMaW5lKSxlLm1heExpbmVDaGFuZ2VkPSEwLHIuaXRlcihmdW5jdGlvbih0KXt2YXIgbj1jKHIsdCk7bj5lLm1heExpbmVMZW5ndGgmJihlLm1heExpbmVMZW5ndGg9bixlLm1heExpbmU9dCl9KX1mdW5jdGlvbiBoKHQpe3ZhciBlPXRpKHQuZ3V0dGVycywiQ29kZU1pcnJvci1saW5lbnVtYmVycyIpOy0xPT1lJiZ0LmxpbmVOdW1iZXJzP3QuZ3V0dGVycz10Lmd1dHRlcnMuY29uY2F0KFsiQ29kZU1pcnJvci1saW5lbnVtYmVycyJdKTplPi0xJiYhdC5saW5lTnVtYmVycyYmKHQuZ3V0dGVycz10Lmd1dHRlcnMuc2xpY2UoMCksdC5ndXR0ZXJzLnNwbGljZShlLDEpKX1mdW5jdGlvbiBkKHQpe3ZhciBlPXQuZGlzcGxheSxyPXQuZG9jLmhlaWdodCxuPXIrRihlKTtlLnNpemVyLnN0eWxlLm1pbkhlaWdodD1lLmhlaWdodEZvcmNlci5zdHlsZS50b3A9bisicHgiLGUuZ3V0dGVycy5zdHlsZS5oZWlnaHQ9TWF0aC5tYXgobixlLnNjcm9sbGVyLmNsaWVudEhlaWdodC1UbykrInB4Ijt2YXIgaT1NYXRoLm1heChuLGUuc2Nyb2xsZXIuc2Nyb2xsSGVpZ2h0KSxvPWUuc2Nyb2xsZXIuc2Nyb2xsV2lkdGg+ZS5zY3JvbGxlci5jbGllbnRXaWR0aCsxLGw9aT5lLnNjcm9sbGVyLmNsaWVudEhlaWdodCsxO2w/KGUuc2Nyb2xsYmFyVi5zdHlsZS5kaXNwbGF5PSJibG9jayIsZS5zY3JvbGxiYXJWLnN0eWxlLmJvdHRvbT1vP2RpKGUubWVhc3VyZSkrInB4IjoiMCIsZS5zY3JvbGxiYXJWLmZpcnN0Q2hpbGQuc3R5bGUuaGVpZ2h0PWktZS5zY3JvbGxlci5jbGllbnRIZWlnaHQrZS5zY3JvbGxiYXJWLmNsaWVudEhlaWdodCsicHgiKTooZS5zY3JvbGxiYXJWLnN0eWxlLmRpc3BsYXk9IiIsZS5zY3JvbGxiYXJWLmZpcnN0Q2hpbGQuc3R5bGUuaGVpZ2h0PSIwIiksbz8oZS5zY3JvbGxiYXJILnN0eWxlLmRpc3BsYXk9ImJsb2NrIixlLnNjcm9sbGJhckguc3R5bGUucmlnaHQ9bD9kaShlLm1lYXN1cmUpKyJweCI6IjAiLGUuc2Nyb2xsYmFySC5maXJzdENoaWxkLnN0eWxlLndpZHRoPWUuc2Nyb2xsZXIuc2Nyb2xsV2lkdGgtZS5zY3JvbGxlci5jbGllbnRXaWR0aCtlLnNjcm9sbGJhckguY2xpZW50V2lkdGgrInB4Iik6KGUuc2Nyb2xsYmFySC5zdHlsZS5kaXNwbGF5PSIiLGUuc2Nyb2xsYmFySC5maXJzdENoaWxkLnN0eWxlLndpZHRoPSIwIiksbyYmbD8oZS5zY3JvbGxiYXJGaWxsZXIuc3R5bGUuZGlzcGxheT0iYmxvY2siLGUuc2Nyb2xsYmFyRmlsbGVyLnN0eWxlLmhlaWdodD1lLnNjcm9sbGJhckZpbGxlci5zdHlsZS53aWR0aD1kaShlLm1lYXN1cmUpKyJweCIpOmUuc2Nyb2xsYmFyRmlsbGVyLnN0eWxlLmRpc3BsYXk9IiIsbyYmdC5vcHRpb25zLmNvdmVyR3V0dGVyTmV4dFRvU2Nyb2xsYmFyJiZ0Lm9wdGlvbnMuZml4ZWRHdXR0ZXI/KGUuZ3V0dGVyRmlsbGVyLnN0eWxlLmRpc3BsYXk9ImJsb2NrIixlLmd1dHRlckZpbGxlci5zdHlsZS5oZWlnaHQ9ZGkoZS5tZWFzdXJlKSsicHgiLGUuZ3V0dGVyRmlsbGVyLnN0eWxlLndpZHRoPWUuZ3V0dGVycy5vZmZzZXRXaWR0aCsicHgiKTplLmd1dHRlckZpbGxlci5zdHlsZS5kaXNwbGF5PSIiLFBpJiYwPT09ZGkoZS5tZWFzdXJlKSYmKGUuc2Nyb2xsYmFyVi5zdHlsZS5taW5XaWR0aD1lLnNjcm9sbGJhckguc3R5bGUubWluSGVpZ2h0PVJpPyIxOHB4IjoiMTJweCIsZS5zY3JvbGxiYXJWLnN0eWxlLnBvaW50ZXJFdmVudHM9ZS5zY3JvbGxiYXJILnN0eWxlLnBvaW50ZXJFdmVudHM9Im5vbmUiKX1mdW5jdGlvbiBwKHQsZSxyKXt2YXIgbj10LnNjcm9sbGVyLnNjcm9sbFRvcCxpPXQud3JhcHBlci5jbGllbnRIZWlnaHQ7Im51bWJlciI9PXR5cGVvZiByP249cjpyJiYobj1yLnRvcCxpPXIuYm90dG9tLXIudG9wKSxuPU1hdGguZmxvb3Iobi1JKHQpKTt2YXIgbz1NYXRoLmNlaWwobitpKTtyZXR1cm57ZnJvbTp4bihlLG4pLHRvOnhuKGUsbyl9fWZ1bmN0aW9uIGcodCl7dmFyIGU9dC5kaXNwbGF5O2lmKGUuYWxpZ25XaWRnZXRzfHxlLmd1dHRlcnMuZmlyc3RDaGlsZCYmdC5vcHRpb25zLmZpeGVkR3V0dGVyKXtmb3IodmFyIHI9eShlKS1lLnNjcm9sbGVyLnNjcm9sbExlZnQrdC5kb2Muc2Nyb2xsTGVmdCxuPWUuZ3V0dGVycy5vZmZzZXRXaWR0aCxpPXIrInB4IixvPWUubGluZURpdi5maXJzdENoaWxkO287bz1vLm5leHRTaWJsaW5nKWlmKG8uYWxpZ25hYmxlKWZvcih2YXIgbD0wLHM9by5hbGlnbmFibGU7bDxzLmxlbmd0aDsrK2wpc1tsXS5zdHlsZS5sZWZ0PWk7dC5vcHRpb25zLmZpeGVkR3V0dGVyJiYoZS5ndXR0ZXJzLnN0eWxlLmxlZnQ9cituKyJweCIpfX1mdW5jdGlvbiBtKHQpe2lmKCF0Lm9wdGlvbnMubGluZU51bWJlcnMpcmV0dXJuITE7dmFyIGU9dC5kb2Mscj12KHQub3B0aW9ucyxlLmZpcnN0K2Uuc2l6ZS0xKSxuPXQuZGlzcGxheTtpZihyLmxlbmd0aCE9bi5saW5lTnVtQ2hhcnMpe3ZhciBpPW4ubWVhc3VyZS5hcHBlbmRDaGlsZChzaSgiZGl2Iixbc2koImRpdiIscildLCJDb2RlTWlycm9yLWxpbmVudW1iZXIgQ29kZU1pcnJvci1ndXR0ZXItZWx0IikpLG89aS5maXJzdENoaWxkLm9mZnNldFdpZHRoLGw9aS5vZmZzZXRXaWR0aC1vO3JldHVybiBuLmxpbmVHdXR0ZXIuc3R5bGUud2lkdGg9IiIsbi5saW5lTnVtSW5uZXJXaWR0aD1NYXRoLm1heChvLG4ubGluZUd1dHRlci5vZmZzZXRXaWR0aC1sKSxuLmxpbmVOdW1XaWR0aD1uLmxpbmVOdW1Jbm5lcldpZHRoK2wsbi5saW5lTnVtQ2hhcnM9bi5saW5lTnVtSW5uZXJXaWR0aD9yLmxlbmd0aDotMSxuLmxpbmVHdXR0ZXIuc3R5bGUud2lkdGg9bi5saW5lTnVtV2lkdGgrInB4IiwhMH1yZXR1cm4hMX1mdW5jdGlvbiB2KHQsZSl7cmV0dXJuIFN0cmluZyh0LmxpbmVOdW1iZXJGb3JtYXR0ZXIoZSt0LmZpcnN0TGluZU51bWJlcikpfWZ1bmN0aW9uIHkodCl7cmV0dXJuIGZpKHQuc2Nyb2xsZXIpLmxlZnQtZmkodC5zaXplcikubGVmdH1mdW5jdGlvbiBiKHQsZSxyLG4pe2Zvcih2YXIgaSxvPXQuZGlzcGxheS5zaG93aW5nRnJvbSxsPXQuZGlzcGxheS5zaG93aW5nVG8scz1wKHQuZGlzcGxheSx0LmRvYyxyKSxhPSEwOzthPSExKXt2YXIgdT10LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGg7aWYoIXgodCxlLHMsbikpYnJlYWs7aWYoaT0hMCxlPVtdLEEodCksZCh0KSxhJiZ0Lm9wdGlvbnMubGluZVdyYXBwaW5nJiZ1IT10LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGgpbj0hMDtlbHNlIGlmKG49ITEsciYmKHI9TWF0aC5taW4odC5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbEhlaWdodC10LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LCJudW1iZXIiPT10eXBlb2Ygcj9yOnIudG9wKSkscz1wKHQuZGlzcGxheSx0LmRvYyxyKSxzLmZyb20+PXQuZGlzcGxheS5zaG93aW5nRnJvbSYmcy50bzw9dC5kaXNwbGF5LnNob3dpbmdUbylicmVha31yZXR1cm4gaSYmKFVuKHQsInVwZGF0ZSIsdCksKHQuZGlzcGxheS5zaG93aW5nRnJvbSE9b3x8dC5kaXNwbGF5LnNob3dpbmdUbyE9bCkmJlVuKHQsInZpZXdwb3J0Q2hhbmdlIix0LHQuZGlzcGxheS5zaG93aW5nRnJvbSx0LmRpc3BsYXkuc2hvd2luZ1RvKSksaX1mdW5jdGlvbiB4KHQsZSxyLG4pe3ZhciBpPXQuZGlzcGxheSxvPXQuZG9jO2lmKCFpLndyYXBwZXIuY2xpZW50V2lkdGgpcmV0dXJuIGkuc2hvd2luZ0Zyb209aS5zaG93aW5nVG89by5maXJzdCxpLnZpZXdPZmZzZXQ9MCx2b2lkIDA7aWYoISghbiYmMD09ZS5sZW5ndGgmJnIuZnJvbT5pLnNob3dpbmdGcm9tJiZyLnRvPGkuc2hvd2luZ1RvKSl7bSh0KSYmKGU9W3tmcm9tOm8uZmlyc3QsdG86by5maXJzdCtvLnNpemV9XSk7dmFyIGw9aS5zaXplci5zdHlsZS5tYXJnaW5MZWZ0PWkuZ3V0dGVycy5vZmZzZXRXaWR0aCsicHgiO2kuc2Nyb2xsYmFySC5zdHlsZS5sZWZ0PXQub3B0aW9ucy5maXhlZEd1dHRlcj9sOiIwIjt2YXIgcz0xLzA7aWYodC5vcHRpb25zLmxpbmVOdW1iZXJzKWZvcih2YXIgYT0wO2E8ZS5sZW5ndGg7KythKWVbYV0uZGlmZiYmZVthXS5mcm9tPHMmJihzPWVbYV0uZnJvbSk7dmFyIHU9by5maXJzdCtvLnNpemUsYz1NYXRoLm1heChyLmZyb20tdC5vcHRpb25zLnZpZXdwb3J0TWFyZ2luLG8uZmlyc3QpLGY9TWF0aC5taW4odSxyLnRvK3Qub3B0aW9ucy52aWV3cG9ydE1hcmdpbik7aWYoaS5zaG93aW5nRnJvbTxjJiZjLWkuc2hvd2luZ0Zyb208MjAmJihjPU1hdGgubWF4KG8uZmlyc3QsaS5zaG93aW5nRnJvbSkpLGkuc2hvd2luZ1RvPmYmJmkuc2hvd2luZ1RvLWY8MjAmJihmPU1hdGgubWluKHUsaS5zaG93aW5nVG8pKSxRaSlmb3IoYz1ibihHcihvLGduKG8sYykpKTt1PmYmJlZyKG8sZ24obyxmKSk7KSsrZjt2YXIgaD1be2Zyb206TWF0aC5tYXgoaS5zaG93aW5nRnJvbSxvLmZpcnN0KSx0bzpNYXRoLm1pbihpLnNob3dpbmdUbyx1KX1dO2lmKGg9aFswXS5mcm9tPj1oWzBdLnRvP1tdOkwoaCxlKSxRaSlmb3IodmFyIGE9MDthPGgubGVuZ3RoOysrYSlmb3IodmFyIGQscD1oW2FdO2Q9QnIoZ24obyxwLnRvLTEpKTspe3ZhciBnPWQuZmluZCgpLmZyb20ubGluZTtpZighKGc+cC5mcm9tKSl7aC5zcGxpY2UoYS0tLDEpO2JyZWFrfXAudG89Z31mb3IodmFyIHY9MCxhPTA7YTxoLmxlbmd0aDsrK2Epe3ZhciBwPWhbYV07cC5mcm9tPGMmJihwLmZyb209YykscC50bz5mJiYocC50bz1mKSxwLmZyb20+PXAudG8/aC5zcGxpY2UoYS0tLDEpOnYrPXAudG8tcC5mcm9tfWlmKCFuJiZ2PT1mLWMmJmM9PWkuc2hvd2luZ0Zyb20mJmY9PWkuc2hvd2luZ1RvKXJldHVybiB3KHQpLHZvaWQgMDtoLnNvcnQoZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5mcm9tLWUuZnJvbX0pO3RyeXt2YXIgeT1kb2N1bWVudC5hY3RpdmVFbGVtZW50fWNhdGNoKGIpe30uNyooZi1jKT52JiYoaS5saW5lRGl2LnN0eWxlLmRpc3BsYXk9Im5vbmUiKSxTKHQsYyxmLGgscyksaS5saW5lRGl2LnN0eWxlLmRpc3BsYXk9IiIseSYmZG9jdW1lbnQuYWN0aXZlRWxlbWVudCE9eSYmeS5vZmZzZXRIZWlnaHQmJnkuZm9jdXMoKTt2YXIgeD1jIT1pLnNob3dpbmdGcm9tfHxmIT1pLnNob3dpbmdUb3x8aS5sYXN0U2l6ZUMhPWkud3JhcHBlci5jbGllbnRIZWlnaHQ7cmV0dXJuIHgmJihpLmxhc3RTaXplQz1pLndyYXBwZXIuY2xpZW50SGVpZ2h0LFcodCw0MDApKSxpLnNob3dpbmdGcm9tPWMsaS5zaG93aW5nVG89ZixDKHQpLHcodCksITB9fWZ1bmN0aW9uIEModCl7Zm9yKHZhciBlLHI9dC5kaXNwbGF5LG49ci5saW5lRGl2Lm9mZnNldFRvcCxpPXIubGluZURpdi5maXJzdENoaWxkO2k7aT1pLm5leHRTaWJsaW5nKWlmKGkubGluZU9iail7aWYoSGkpe3ZhciBvPWkub2Zmc2V0VG9wK2kub2Zmc2V0SGVpZ2h0O2U9by1uLG49b31lbHNle3ZhciBsPWZpKGkpO2U9bC5ib3R0b20tbC50b3B9dmFyIHM9aS5saW5lT2JqLmhlaWdodC1lO2lmKDI+ZSYmKGU9cmUocikpLHM+LjAwMXx8LS4wMDE+cyl7eW4oaS5saW5lT2JqLGUpO3ZhciBhPWkubGluZU9iai53aWRnZXRzO2lmKGEpZm9yKHZhciB1PTA7dTxhLmxlbmd0aDsrK3UpYVt1XS5oZWlnaHQ9YVt1XS5ub2RlLm9mZnNldEhlaWdodH19fWZ1bmN0aW9uIHcodCl7dmFyIGU9dC5kaXNwbGF5LnZpZXdPZmZzZXQ9Q24odCxnbih0LmRvYyx0LmRpc3BsYXkuc2hvd2luZ0Zyb20pKTt0LmRpc3BsYXkubW92ZXIuc3R5bGUudG9wPWUrInB4In1mdW5jdGlvbiBMKHQsZSl7Zm9yKHZhciByPTAsbj1lLmxlbmd0aHx8MDtuPnI7KytyKXtmb3IodmFyIGk9ZVtyXSxvPVtdLGw9aS5kaWZmfHwwLHM9MCxhPXQubGVuZ3RoO2E+czsrK3Mpe3ZhciB1PXRbc107aS50bzw9dS5mcm9tJiZpLmRpZmY/by5wdXNoKHtmcm9tOnUuZnJvbStsLHRvOnUudG8rbH0pOmkudG88PXUuZnJvbXx8aS5mcm9tPj11LnRvP28ucHVzaCh1KTooaS5mcm9tPnUuZnJvbSYmby5wdXNoKHtmcm9tOnUuZnJvbSx0bzppLmZyb219KSxpLnRvPHUudG8mJm8ucHVzaCh7ZnJvbTppLnRvK2wsdG86dS50bytsfSkpfXQ9b31yZXR1cm4gdH1mdW5jdGlvbiBrKHQpe2Zvcih2YXIgZT10LmRpc3BsYXkscj17fSxuPXt9LGk9ZS5ndXR0ZXJzLmZpcnN0Q2hpbGQsbz0wO2k7aT1pLm5leHRTaWJsaW5nLCsrbylyW3Qub3B0aW9ucy5ndXR0ZXJzW29dXT1pLm9mZnNldExlZnQsblt0Lm9wdGlvbnMuZ3V0dGVyc1tvXV09aS5vZmZzZXRXaWR0aDtyZXR1cm57Zml4ZWRQb3M6eShlKSxndXR0ZXJUb3RhbFdpZHRoOmUuZ3V0dGVycy5vZmZzZXRXaWR0aCxndXR0ZXJMZWZ0OnIsZ3V0dGVyV2lkdGg6bix3cmFwcGVyV2lkdGg6ZS53cmFwcGVyLmNsaWVudFdpZHRofX1mdW5jdGlvbiBTKHQsZSxyLG4saSl7ZnVuY3Rpb24gbyhlKXt2YXIgcj1lLm5leHRTaWJsaW5nO3JldHVybiBXaSYmS2kmJnQuZGlzcGxheS5jdXJyZW50V2hlZWxUYXJnZXQ9PWU/KGUuc3R5bGUuZGlzcGxheT0ibm9uZSIsZS5saW5lT2JqPW51bGwpOmUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlKSxyfXZhciBsPWsodCkscz10LmRpc3BsYXksYT10Lm9wdGlvbnMubGluZU51bWJlcnM7bi5sZW5ndGh8fFdpJiZ0LmRpc3BsYXkuY3VycmVudFdoZWVsVGFyZ2V0fHxhaShzLmxpbmVEaXYpO3ZhciB1PXMubGluZURpdixjPXUuZmlyc3RDaGlsZCxmPW4uc2hpZnQoKSxoPWU7Zm9yKHQuZG9jLml0ZXIoZSxyLGZ1bmN0aW9uKGUpe2lmKGYmJmYudG89PWgmJihmPW4uc2hpZnQoKSksVnIodC5kb2MsZSkpe2lmKDAhPWUuaGVpZ2h0JiZ5bihlLDApLGUud2lkZ2V0cyYmYyYmYy5wcmV2aW91c1NpYmxpbmcpZm9yKHZhciByPTA7cjxlLndpZGdldHMubGVuZ3RoOysrcil7dmFyIHM9ZS53aWRnZXRzW3JdO2lmKHMuc2hvd0lmSGlkZGVuKXt2YXIgZD1jLnByZXZpb3VzU2libGluZztpZigvcHJlL2kudGVzdChkLm5vZGVOYW1lKSl7dmFyIHA9c2koImRpdiIsbnVsbCxudWxsLCJwb3NpdGlvbjogcmVsYXRpdmUiKTtkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHAsZCkscC5hcHBlbmRDaGlsZChkKSxkPXB9dmFyIGc9ZC5hcHBlbmRDaGlsZChzaSgiZGl2Iixbcy5ub2RlXSwiQ29kZU1pcnJvci1saW5ld2lkZ2V0IikpO3MuaGFuZGxlTW91c2VFdmVudHN8fChnLmlnbm9yZUV2ZW50cz0hMCksVChzLGcsZCxsKX19fWVsc2UgaWYoZiYmZi5mcm9tPD1oJiZmLnRvPmgpe2Zvcig7Yy5saW5lT2JqIT1lOyljPW8oYyk7YSYmaD49aSYmYy5saW5lTnVtYmVyJiZjaShjLmxpbmVOdW1iZXIsdih0Lm9wdGlvbnMsaCkpLGM9Yy5uZXh0U2libGluZ31lbHNle2lmKGUud2lkZ2V0cylmb3IodmFyIG0seT0wLGI9YztiJiYyMD55OysreSxiPWIubmV4dFNpYmxpbmcpaWYoYi5saW5lT2JqPT1lJiYvZGl2L2kudGVzdChiLm5vZGVOYW1lKSl7bT1iO2JyZWFrfXZhciB4PU0odCxlLGgsbCxtKTtpZih4IT1tKXUuaW5zZXJ0QmVmb3JlKHgsYyk7ZWxzZXtmb3IoO2MhPW07KWM9byhjKTtjPWMubmV4dFNpYmxpbmd9eC5saW5lT2JqPWV9KytofSk7YzspYz1vKGMpfWZ1bmN0aW9uIE0odCxlLHIsbixpKXt2YXIgbyxsPXJuKHQsZSkscz1sLnByZSxhPWUuZ3V0dGVyTWFya2Vycyx1PXQuZGlzcGxheSxjPWwuYmdDbGFzcz9sLmJnQ2xhc3MrIiAiKyhlLmJnQ2xhc3N8fCIiKTplLmJnQ2xhc3M7aWYoISh0Lm9wdGlvbnMubGluZU51bWJlcnN8fGF8fGN8fGUud3JhcENsYXNzfHxlLndpZGdldHMpKXJldHVybiBzO2lmKGkpe2kuYWxpZ25hYmxlPW51bGw7Zm9yKHZhciBmLGg9ITAsZD0wLHA9bnVsbCxnPWkuZmlyc3RDaGlsZDtnO2c9ZilpZihmPWcubmV4dFNpYmxpbmcsL1xiQ29kZU1pcnJvci1saW5ld2lkZ2V0XGIvLnRlc3QoZy5jbGFzc05hbWUpKXtmb3IodmFyIG09MDttPGUud2lkZ2V0cy5sZW5ndGg7KyttKXt2YXIgeT1lLndpZGdldHNbbV07aWYoeS5ub2RlPT1nLmZpcnN0Q2hpbGQpe3kuYWJvdmV8fHB8fChwPWcpLFQoeSxnLGksbiksKytkO2JyZWFrfX1pZihtPT1lLndpZGdldHMubGVuZ3RoKXtoPSExO2JyZWFrfX1lbHNlIGkucmVtb3ZlQ2hpbGQoZyk7aS5pbnNlcnRCZWZvcmUocyxwKSxoJiZkPT1lLndpZGdldHMubGVuZ3RoJiYobz1pLGkuY2xhc3NOYW1lPWUud3JhcENsYXNzfHwiIil9aWYob3x8KG89c2koImRpdiIsbnVsbCxlLndyYXBDbGFzcywicG9zaXRpb246IHJlbGF0aXZlIiksby5hcHBlbmRDaGlsZChzKSksYyYmby5pbnNlcnRCZWZvcmUoc2koImRpdiIsbnVsbCxjKyIgQ29kZU1pcnJvci1saW5lYmFja2dyb3VuZCIpLG8uZmlyc3RDaGlsZCksdC5vcHRpb25zLmxpbmVOdW1iZXJzfHxhKXt2YXIgYj1vLmluc2VydEJlZm9yZShzaSgiZGl2IixudWxsLG51bGwsInBvc2l0aW9uOiBhYnNvbHV0ZTsgbGVmdDogIisodC5vcHRpb25zLmZpeGVkR3V0dGVyP24uZml4ZWRQb3M6LW4uZ3V0dGVyVG90YWxXaWR0aCkrInB4Iiksby5maXJzdENoaWxkKTtpZih0Lm9wdGlvbnMuZml4ZWRHdXR0ZXImJihvLmFsaWduYWJsZXx8KG8uYWxpZ25hYmxlPVtdKSkucHVzaChiKSwhdC5vcHRpb25zLmxpbmVOdW1iZXJzfHxhJiZhWyJDb2RlTWlycm9yLWxpbmVudW1iZXJzIl18fChvLmxpbmVOdW1iZXI9Yi5hcHBlbmRDaGlsZChzaSgiZGl2Iix2KHQub3B0aW9ucyxyKSwiQ29kZU1pcnJvci1saW5lbnVtYmVyIENvZGVNaXJyb3ItZ3V0dGVyLWVsdCIsImxlZnQ6ICIrbi5ndXR0ZXJMZWZ0WyJDb2RlTWlycm9yLWxpbmVudW1iZXJzIl0rInB4OyB3aWR0aDogIit1LmxpbmVOdW1Jbm5lcldpZHRoKyJweCIpKSksYSlmb3IodmFyIHg9MDt4PHQub3B0aW9ucy5ndXR0ZXJzLmxlbmd0aDsrK3gpe3ZhciBDPXQub3B0aW9ucy5ndXR0ZXJzW3hdLHc9YS5oYXNPd25Qcm9wZXJ0eShDKSYmYVtDXTt3JiZiLmFwcGVuZENoaWxkKHNpKCJkaXYiLFt3XSwiQ29kZU1pcnJvci1ndXR0ZXItZWx0IiwibGVmdDogIituLmd1dHRlckxlZnRbQ10rInB4OyB3aWR0aDogIituLmd1dHRlcldpZHRoW0NdKyJweCIpKX19aWYoSGkmJihvLnN0eWxlLnpJbmRleD0yKSxlLndpZGdldHMmJm8hPWkpZm9yKHZhciBtPTAsTD1lLndpZGdldHM7bTxMLmxlbmd0aDsrK20pe3ZhciB5PUxbbV0saz1zaSgiZGl2IixbeS5ub2RlXSwiQ29kZU1pcnJvci1saW5ld2lkZ2V0Iik7eS5oYW5kbGVNb3VzZUV2ZW50c3x8KGsuaWdub3JlRXZlbnRzPSEwKSxUKHksayxvLG4pLHkuYWJvdmU/by5pbnNlcnRCZWZvcmUoayx0Lm9wdGlvbnMubGluZU51bWJlcnMmJjAhPWUuaGVpZ2h0P2I6cyk6by5hcHBlbmRDaGlsZChrKSxVbih5LCJyZWRyYXciKX1yZXR1cm4gb31mdW5jdGlvbiBUKHQsZSxyLG4pe2lmKHQubm9IU2Nyb2xsKXsoci5hbGlnbmFibGV8fChyLmFsaWduYWJsZT1bXSkpLnB1c2goZSk7dmFyIGk9bi53cmFwcGVyV2lkdGg7ZS5zdHlsZS5sZWZ0PW4uZml4ZWRQb3MrInB4Iix0LmNvdmVyR3V0dGVyfHwoaS09bi5ndXR0ZXJUb3RhbFdpZHRoLGUuc3R5bGUucGFkZGluZ0xlZnQ9bi5ndXR0ZXJUb3RhbFdpZHRoKyJweCIpLGUuc3R5bGUud2lkdGg9aSsicHgifXQuY292ZXJHdXR0ZXImJihlLnN0eWxlLnpJbmRleD01LGUuc3R5bGUucG9zaXRpb249InJlbGF0aXZlIix0Lm5vSFNjcm9sbHx8KGUuc3R5bGUubWFyZ2luTGVmdD0tbi5ndXR0ZXJUb3RhbFdpZHRoKyJweCIpKX1mdW5jdGlvbiBBKHQpe3ZhciBlPXQuZGlzcGxheSxyPWplKHQuZG9jLnNlbC5mcm9tLHQuZG9jLnNlbC50byk7aWYocnx8dC5vcHRpb25zLnNob3dDdXJzb3JXaGVuU2VsZWN0aW5nP0godCk6ZS5jdXJzb3Iuc3R5bGUuZGlzcGxheT1lLm90aGVyQ3Vyc29yLnN0eWxlLmRpc3BsYXk9Im5vbmUiLHI/ZS5zZWxlY3Rpb25EaXYuc3R5bGUuZGlzcGxheT0ibm9uZSI6Tih0KSx0Lm9wdGlvbnMubW92ZUlucHV0V2l0aEN1cnNvcil7dmFyIG49USh0LHQuZG9jLnNlbC5oZWFkLCJkaXYiKSxpPWZpKGUud3JhcHBlciksbz1maShlLmxpbmVEaXYpO2UuaW5wdXREaXYuc3R5bGUudG9wPU1hdGgubWF4KDAsTWF0aC5taW4oZS53cmFwcGVyLmNsaWVudEhlaWdodC0xMCxuLnRvcCtvLnRvcC1pLnRvcCkpKyJweCIsZS5pbnB1dERpdi5zdHlsZS5sZWZ0PU1hdGgubWF4KDAsTWF0aC5taW4oZS53cmFwcGVyLmNsaWVudFdpZHRoLTEwLG4ubGVmdCtvLmxlZnQtaS5sZWZ0KSkrInB4In19ZnVuY3Rpb24gSCh0KXt2YXIgZT10LmRpc3BsYXkscj1RKHQsdC5kb2Muc2VsLmhlYWQsImRpdiIpO2UuY3Vyc29yLnN0eWxlLmxlZnQ9ci5sZWZ0KyJweCIsZS5jdXJzb3Iuc3R5bGUudG9wPXIudG9wKyJweCIsZS5jdXJzb3Iuc3R5bGUuaGVpZ2h0PU1hdGgubWF4KDAsci5ib3R0b20tci50b3ApKnQub3B0aW9ucy5jdXJzb3JIZWlnaHQrInB4IixlLmN1cnNvci5zdHlsZS5kaXNwbGF5PSIiLHIub3RoZXI/KGUub3RoZXJDdXJzb3Iuc3R5bGUuZGlzcGxheT0iIixlLm90aGVyQ3Vyc29yLnN0eWxlLmxlZnQ9ci5vdGhlci5sZWZ0KyJweCIsZS5vdGhlckN1cnNvci5zdHlsZS50b3A9ci5vdGhlci50b3ArInB4IixlLm90aGVyQ3Vyc29yLnN0eWxlLmhlaWdodD0uODUqKHIub3RoZXIuYm90dG9tLXIub3RoZXIudG9wKSsicHgiKTplLm90aGVyQ3Vyc29yLnN0eWxlLmRpc3BsYXk9Im5vbmUifWZ1bmN0aW9uIE4odCl7ZnVuY3Rpb24gZSh0LGUscixuKXswPmUmJihlPTApLGwuYXBwZW5kQ2hpbGQoc2koImRpdiIsbnVsbCwiQ29kZU1pcnJvci1zZWxlY3RlZCIsInBvc2l0aW9uOiBhYnNvbHV0ZTsgbGVmdDogIit0KyJweDsgdG9wOiAiK2UrInB4OyB3aWR0aDogIisobnVsbD09cj9zLXQ6cikrInB4OyBoZWlnaHQ6ICIrKG4tZSkrInB4IikpfWZ1bmN0aW9uIHIocixuLG8pe2Z1bmN0aW9uIGwoZSxuKXtyZXR1cm4gcSh0LFllKHIsZSksImRpdiIsZixuKX12YXIgdSxjLGY9Z24oaSxyKSxoPWYudGV4dC5sZW5ndGg7cmV0dXJuIGdpKHduKGYpLG58fDAsbnVsbD09bz9oOm8sZnVuY3Rpb24odCxyLGkpe3ZhciBmLGQscCxnPWwodCwibGVmdCIpO2lmKHQ9PXIpZj1nLGQ9cD1nLmxlZnQ7ZWxzZXtpZihmPWwoci0xLCJyaWdodCIpLCJydGwiPT1pKXt2YXIgbT1nO2c9ZixmPW19ZD1nLmxlZnQscD1mLnJpZ2h0fW51bGw9PW4mJjA9PXQmJihkPWEpLGYudG9wLWcudG9wPjMmJihlKGQsZy50b3AsbnVsbCxnLmJvdHRvbSksZD1hLGcuYm90dG9tPGYudG9wJiZlKGQsZy5ib3R0b20sbnVsbCxmLnRvcCkpLG51bGw9PW8mJnI9PWgmJihwPXMpLCghdXx8Zy50b3A8dS50b3B8fGcudG9wPT11LnRvcCYmZy5sZWZ0PHUubGVmdCkmJih1PWcpLCghY3x8Zi5ib3R0b20+Yy5ib3R0b218fGYuYm90dG9tPT1jLmJvdHRvbSYmZi5yaWdodD5jLnJpZ2h0KSYmKGM9ZiksYSsxPmQmJihkPWEpLGUoZCxmLnRvcCxwLWQsZi5ib3R0b20pfSkse3N0YXJ0OnUsZW5kOmN9fXZhciBuPXQuZGlzcGxheSxpPXQuZG9jLG89dC5kb2Muc2VsLGw9ZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLHM9bi5saW5lU3BhY2Uub2Zmc2V0V2lkdGgsYT1QKHQuZGlzcGxheSk7aWYoby5mcm9tLmxpbmU9PW8udG8ubGluZSlyKG8uZnJvbS5saW5lLG8uZnJvbS5jaCxvLnRvLmNoKTtlbHNle3ZhciB1PWduKGksby5mcm9tLmxpbmUpLGM9Z24oaSxvLnRvLmxpbmUpLGY9R3IoaSx1KT09R3IoaSxjKSxoPXIoby5mcm9tLmxpbmUsby5mcm9tLmNoLGY/dS50ZXh0Lmxlbmd0aDpudWxsKS5lbmQsZD1yKG8udG8ubGluZSxmPzA6bnVsbCxvLnRvLmNoKS5zdGFydDtmJiYoaC50b3A8ZC50b3AtMj8oZShoLnJpZ2h0LGgudG9wLG51bGwsaC5ib3R0b20pLGUoYSxkLnRvcCxkLmxlZnQsZC5ib3R0b20pKTplKGgucmlnaHQsaC50b3AsZC5sZWZ0LWgucmlnaHQsaC5ib3R0b20pKSxoLmJvdHRvbTxkLnRvcCYmZShhLGguYm90dG9tLG51bGwsZC50b3ApfXVpKG4uc2VsZWN0aW9uRGl2LGwpLG4uc2VsZWN0aW9uRGl2LnN0eWxlLmRpc3BsYXk9IiJ9ZnVuY3Rpb24gRCh0KXtpZih0LnN0YXRlLmZvY3VzZWQpe3ZhciBlPXQuZGlzcGxheTtjbGVhckludGVydmFsKGUuYmxpbmtlcik7dmFyIHI9ITA7ZS5jdXJzb3Iuc3R5bGUudmlzaWJpbGl0eT1lLm90aGVyQ3Vyc29yLnN0eWxlLnZpc2liaWxpdHk9IiIsdC5vcHRpb25zLmN1cnNvckJsaW5rUmF0ZT4wJiYoZS5ibGlua2VyPXNldEludGVydmFsKGZ1bmN0aW9uKCl7ZS5jdXJzb3Iuc3R5bGUudmlzaWJpbGl0eT1lLm90aGVyQ3Vyc29yLnN0eWxlLnZpc2liaWxpdHk9KHI9IXIpPyIiOiJoaWRkZW4ifSx0Lm9wdGlvbnMuY3Vyc29yQmxpbmtSYXRlKSl9fWZ1bmN0aW9uIFcodCxlKXt0LmRvYy5tb2RlLnN0YXJ0U3RhdGUmJnQuZG9jLmZyb250aWVyPHQuZGlzcGxheS5zaG93aW5nVG8mJnQuc3RhdGUuaGlnaGxpZ2h0LnNldChlLGlpKE8sdCkpfWZ1bmN0aW9uIE8odCl7dmFyIGU9dC5kb2M7aWYoZS5mcm9udGllcjxlLmZpcnN0JiYoZS5mcm9udGllcj1lLmZpcnN0KSwhKGUuZnJvbnRpZXI+PXQuZGlzcGxheS5zaG93aW5nVG8pKXt2YXIgcixuPStuZXcgRGF0ZSt0Lm9wdGlvbnMud29ya1RpbWUsaT1icihlLm1vZGUseih0LGUuZnJvbnRpZXIpKSxvPVtdO2UuaXRlcihlLmZyb250aWVyLE1hdGgubWluKGUuZmlyc3QrZS5zaXplLHQuZGlzcGxheS5zaG93aW5nVG8rNTAwKSxmdW5jdGlvbihsKXtpZihlLmZyb250aWVyPj10LmRpc3BsYXkuc2hvd2luZ0Zyb20pe3ZhciBzPWwuc3R5bGVzO2wuc3R5bGVzPVFyKHQsbCxpLCEwKTtmb3IodmFyIGE9IXN8fHMubGVuZ3RoIT1sLnN0eWxlcy5sZW5ndGgsdT0wOyFhJiZ1PHMubGVuZ3RoOysrdSlhPXNbdV0hPWwuc3R5bGVzW3VdO2EmJihyJiZyLmVuZD09ZS5mcm9udGllcj9yLmVuZCsrOm8ucHVzaChyPXtzdGFydDplLmZyb250aWVyLGVuZDplLmZyb250aWVyKzF9KSksbC5zdGF0ZUFmdGVyPWJyKGUubW9kZSxpKX1lbHNlIHRuKHQsbC50ZXh0LGkpLGwuc3RhdGVBZnRlcj0wPT1lLmZyb250aWVyJTU/YnIoZS5tb2RlLGkpOm51bGw7cmV0dXJuKytlLmZyb250aWVyLCtuZXcgRGF0ZT5uPyhXKHQsdC5vcHRpb25zLndvcmtEZWxheSksITApOnZvaWQgMH0pLG8ubGVuZ3RoJiZsZSh0LGZ1bmN0aW9uKCl7Zm9yKHZhciB0PTA7dDxvLmxlbmd0aDsrK3QpdWUodGhpcyxvW3RdLnN0YXJ0LG9bdF0uZW5kKX0pKCl9fWZ1bmN0aW9uIEUodCxlLHIpe2Zvcih2YXIgbixpLG89dC5kb2MsbD1yPy0xOmUtKHQuZG9jLm1vZGUuaW5uZXJNb2RlPzFlMzoxMDApLHM9ZTtzPmw7LS1zKXtpZihzPD1vLmZpcnN0KXJldHVybiBvLmZpcnN0O3ZhciBhPWduKG8scy0xKTtpZihhLnN0YXRlQWZ0ZXImJighcnx8czw9by5mcm9udGllcikpcmV0dXJuIHM7dmFyIHU9Wm4oYS50ZXh0LG51bGwsdC5vcHRpb25zLnRhYlNpemUpOyhudWxsPT1pfHxuPnUpJiYoaT1zLTEsbj11KX1yZXR1cm4gaX1mdW5jdGlvbiB6KHQsZSxyKXt2YXIgbj10LmRvYyxpPXQuZGlzcGxheTtpZighbi5tb2RlLnN0YXJ0U3RhdGUpcmV0dXJuITA7dmFyIG89RSh0LGUsciksbD1vPm4uZmlyc3QmJmduKG4sby0xKS5zdGF0ZUFmdGVyO3JldHVybiBsPWw/YnIobi5tb2RlLGwpOnhyKG4ubW9kZSksbi5pdGVyKG8sZSxmdW5jdGlvbihyKXt0bih0LHIudGV4dCxsKTt2YXIgcz1vPT1lLTF8fDA9PW8lNXx8bz49aS5zaG93aW5nRnJvbSYmbzxpLnNob3dpbmdUbztyLnN0YXRlQWZ0ZXI9cz9icihuLm1vZGUsbCk6bnVsbCwrK299KSxyJiYobi5mcm9udGllcj1vKSxsfWZ1bmN0aW9uIEkodCl7cmV0dXJuIHQubGluZVNwYWNlLm9mZnNldFRvcH1mdW5jdGlvbiBGKHQpe3JldHVybiB0Lm1vdmVyLm9mZnNldEhlaWdodC10LmxpbmVTcGFjZS5vZmZzZXRIZWlnaHR9ZnVuY3Rpb24gUCh0KXt2YXIgZT11aSh0Lm1lYXN1cmUsc2koInByZSIsbnVsbCxudWxsLCJ0ZXh0LWFsaWduOiBsZWZ0IikpLmFwcGVuZENoaWxkKHNpKCJzcGFuIiwieCIpKTtyZXR1cm4gZS5vZmZzZXRMZWZ0fWZ1bmN0aW9uIFIodCxlLHIsbixpKXt2YXIgbz0tMTtpZihuPW58fFYodCxlKSxuLmNydWRlKXt2YXIgbD1uLmxlZnQrcipuLndpZHRoO3JldHVybntsZWZ0OmwscmlnaHQ6bCtuLndpZHRoLHRvcDpuLnRvcCxib3R0b206bi5ib3R0b219fWZvcih2YXIgcz1yOztzKz1vKXt2YXIgYT1uW3NdO2lmKGEpYnJlYWs7MD5vJiYwPT1zJiYobz0xKX1yZXR1cm4gaT1zPnI/ImxlZnQiOnI+cz8icmlnaHQiOmksImxlZnQiPT1pJiZhLmxlZnRTaWRlP2E9YS5sZWZ0U2lkZToicmlnaHQiPT1pJiZhLnJpZ2h0U2lkZSYmKGE9YS5yaWdodFNpZGUpLHtsZWZ0OnI+cz9hLnJpZ2h0OmEubGVmdCxyaWdodDpzPnI/YS5sZWZ0OmEucmlnaHQsdG9wOmEudG9wLGJvdHRvbTphLmJvdHRvbX19ZnVuY3Rpb24gQih0LGUpe2Zvcih2YXIgcj10LmRpc3BsYXkubWVhc3VyZUxpbmVDYWNoZSxuPTA7bjxyLmxlbmd0aDsrK24pe3ZhciBpPXJbbl07aWYoaS50ZXh0PT1lLnRleHQmJmkubWFya2VkU3BhbnM9PWUubWFya2VkU3BhbnMmJnQuZGlzcGxheS5zY3JvbGxlci5jbGllbnRXaWR0aD09aS53aWR0aCYmaS5jbGFzc2VzPT1lLnRleHRDbGFzcysifCIrZS53cmFwQ2xhc3MpcmV0dXJuIGl9fWZ1bmN0aW9uIEcodCxlKXt2YXIgcj1CKHQsZSk7ciYmKHIudGV4dD1yLm1lYXN1cmU9ci5tYXJrZWRTcGFucz1udWxsKX1mdW5jdGlvbiBWKHQsZSl7dmFyIHI9Qih0LGUpO2lmKHIpcmV0dXJuIHIubWVhc3VyZTt2YXIgbj1LKHQsZSksaT10LmRpc3BsYXkubWVhc3VyZUxpbmVDYWNoZSxvPXt0ZXh0OmUudGV4dCx3aWR0aDp0LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGgsbWFya2VkU3BhbnM6ZS5tYXJrZWRTcGFucyxtZWFzdXJlOm4sY2xhc3NlczplLnRleHRDbGFzcysifCIrZS53cmFwQ2xhc3N9O3JldHVybiAxNj09aS5sZW5ndGg/aVsrK3QuZGlzcGxheS5tZWFzdXJlTGluZUNhY2hlUG9zJTE2XT1vOmkucHVzaChvKSxufWZ1bmN0aW9uIEsodCxlKXtmdW5jdGlvbiByKHQpe3ZhciBlPXQudG9wLXAudG9wLHI9dC5ib3R0b20tcC50b3A7cj52JiYocj12KSwwPmUmJihlPTApO2Zvcih2YXIgbj1nLmxlbmd0aC0yO24+PTA7bi09Mil7dmFyIGk9Z1tuXSxvPWdbbisxXTtpZighKGk+cnx8ZT5vKSYmKGU+PWkmJm8+PXJ8fGk+PWUmJnI+PW98fE1hdGgubWluKHIsbyktTWF0aC5tYXgoZSxpKT49ci1lPj4xKSl7Z1tuXT1NYXRoLm1pbihlLGkpLGdbbisxXT1NYXRoLm1heChyLG8pO2JyZWFrfX1yZXR1cm4gMD5uJiYobj1nLmxlbmd0aCxnLnB1c2goZSxyKSkse2xlZnQ6dC5sZWZ0LXAubGVmdCxyaWdodDp0LnJpZ2h0LXAubGVmdCx0b3A6bixib3R0b206bnVsbH19ZnVuY3Rpb24gbih0KXt0LmJvdHRvbT1nW3QudG9wKzFdLHQudG9wPWdbdC50b3BdfWlmKCF0Lm9wdGlvbnMubGluZVdyYXBwaW5nJiZlLnRleHQubGVuZ3RoPj10Lm9wdGlvbnMuY3J1ZGVNZWFzdXJpbmdGcm9tKXJldHVybiBVKHQsZSk7dmFyIGk9dC5kaXNwbGF5LG89bmkoZS50ZXh0Lmxlbmd0aCksbD1ybih0LGUsbywhMCkucHJlO2lmKEFpJiYhSGkmJiF0Lm9wdGlvbnMubGluZVdyYXBwaW5nJiZsLmNoaWxkTm9kZXMubGVuZ3RoPjEwMCl7Zm9yKHZhciBzPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxhPTEwLHU9bC5jaGlsZE5vZGVzLmxlbmd0aCxjPTAsZj1NYXRoLmNlaWwodS9hKTtmPmM7KytjKXtmb3IodmFyIGg9c2koImRpdiIsbnVsbCxudWxsLCJkaXNwbGF5OiBpbmxpbmUtYmxvY2siKSxkPTA7YT5kJiZ1OysrZCloLmFwcGVuZENoaWxkKGwuZmlyc3RDaGlsZCksLS11O3MuYXBwZW5kQ2hpbGQoaCl9bC5hcHBlbmRDaGlsZChzKX11aShpLm1lYXN1cmUsbCk7dmFyIHA9ZmkoaS5saW5lRGl2KSxnPVtdLG09bmkoZS50ZXh0Lmxlbmd0aCksdj1sLm9mZnNldEhlaWdodDtOaSYmaS5tZWFzdXJlLmZpcnN0IT1sJiZ1aShpLm1lYXN1cmUsbCk7Zm9yKHZhciB5LGM9MDtjPG8ubGVuZ3RoOysrYylpZih5PW9bY10pe3ZhciBiPXkseD1udWxsO2lmKC9cYkNvZGVNaXJyb3Itd2lkZ2V0XGIvLnRlc3QoeS5jbGFzc05hbWUpJiZ5LmdldENsaWVudFJlY3RzKXsxPT15LmZpcnN0Q2hpbGQubm9kZVR5cGUmJihiPXkuZmlyc3RDaGlsZCk7dmFyIEM9Yi5nZXRDbGllbnRSZWN0cygpO0MubGVuZ3RoPjEmJih4PW1bY109cihDWzBdKSx4LnJpZ2h0U2lkZT1yKENbQy5sZW5ndGgtMV0pKX14fHwoeD1tW2NdPXIoZmkoYikpKSx5Lm1lYXN1cmVSaWdodCYmKHgucmlnaHQ9ZmkoeS5tZWFzdXJlUmlnaHQpLmxlZnQpLHkubGVmdFNpZGUmJih4LmxlZnRTaWRlPXIoZmkoeS5sZWZ0U2lkZSkpKX1haSh0LmRpc3BsYXkubWVhc3VyZSk7Zm9yKHZhciB5LGM9MDtjPG0ubGVuZ3RoOysrYykoeT1tW2NdKSYmKG4oeSkseS5sZWZ0U2lkZSYmbih5LmxlZnRTaWRlKSx5LnJpZ2h0U2lkZSYmbih5LnJpZ2h0U2lkZSkpO3JldHVybiBtfWZ1bmN0aW9uIFUodCxlKXt2YXIgcj1uZXcgYm8oZS50ZXh0LnNsaWNlKDAsMTAwKSxudWxsKTtlLnRleHRDbGFzcyYmKHIudGV4dENsYXNzPWUudGV4dENsYXNzKTt2YXIgbj1LKHQsciksaT1SKHQsciwwLG4sImxlZnQiKSxvPVIodCxyLDk5LG4sInJpZ2h0Iik7cmV0dXJue2NydWRlOiEwLHRvcDppLnRvcCxsZWZ0OmkubGVmdCxib3R0b206aS5ib3R0b20sd2lkdGg6KG8ucmlnaHQtaS5sZWZ0KS8xMDB9fWZ1bmN0aW9uIFgodCxlKXt2YXIgcj0hMTtpZihlLm1hcmtlZFNwYW5zKWZvcih2YXIgbj0wO248ZS5tYXJrZWRTcGFuczsrK24pe3ZhciBpPWUubWFya2VkU3BhbnNbbl07IWkuY29sbGFwc2VkfHxudWxsIT1pLnRvJiZpLnRvIT1lLnRleHQubGVuZ3RofHwocj0hMCl9dmFyIG89IXImJkIodCxlKTtpZihvfHxlLnRleHQubGVuZ3RoPj10Lm9wdGlvbnMuY3J1ZGVNZWFzdXJpbmdGcm9tKXJldHVybiBSKHQsZSxlLnRleHQubGVuZ3RoLG8mJm8ubWVhc3VyZSwicmlnaHQiKS5yaWdodDt2YXIgbD1ybih0LGUsbnVsbCwhMCkucHJlLHM9bC5hcHBlbmRDaGlsZChwaSh0LmRpc3BsYXkubWVhc3VyZSkpO3JldHVybiB1aSh0LmRpc3BsYXkubWVhc3VyZSxsKSxmaShzKS5yaWdodC1maSh0LmRpc3BsYXkubGluZURpdikubGVmdH1mdW5jdGlvbiBfKHQpe3QuZGlzcGxheS5tZWFzdXJlTGluZUNhY2hlLmxlbmd0aD10LmRpc3BsYXkubWVhc3VyZUxpbmVDYWNoZVBvcz0wLHQuZGlzcGxheS5jYWNoZWRDaGFyV2lkdGg9dC5kaXNwbGF5LmNhY2hlZFRleHRIZWlnaHQ9bnVsbCx0Lm9wdGlvbnMubGluZVdyYXBwaW5nfHwodC5kaXNwbGF5Lm1heExpbmVDaGFuZ2VkPSEwKSx0LmRpc3BsYXkubGluZU51bUNoYXJzPW51bGx9ZnVuY3Rpb24gWSgpe3JldHVybiB3aW5kb3cucGFnZVhPZmZzZXR8fChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnR8fGRvY3VtZW50LmJvZHkpLnNjcm9sbExlZnR9ZnVuY3Rpb24gaigpe3JldHVybiB3aW5kb3cucGFnZVlPZmZzZXR8fChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnR8fGRvY3VtZW50LmJvZHkpLnNjcm9sbFRvcH1mdW5jdGlvbiAkKHQsZSxyLG4pe2lmKGUud2lkZ2V0cylmb3IodmFyIGk9MDtpPGUud2lkZ2V0cy5sZW5ndGg7KytpKWlmKGUud2lkZ2V0c1tpXS5hYm92ZSl7dmFyIG89WXIoZS53aWRnZXRzW2ldKTtyLnRvcCs9byxyLmJvdHRvbSs9b31pZigibGluZSI9PW4pcmV0dXJuIHI7bnx8KG49ImxvY2FsIik7dmFyIGw9Q24odCxlKTtpZigibG9jYWwiPT1uP2wrPUkodC5kaXNwbGF5KTpsLT10LmRpc3BsYXkudmlld09mZnNldCwicGFnZSI9PW58fCJ3aW5kb3ciPT1uKXt2YXIgcz1maSh0LmRpc3BsYXkubGluZVNwYWNlKTtsKz1zLnRvcCsoIndpbmRvdyI9PW4/MDpqKCkpO3ZhciBhPXMubGVmdCsoIndpbmRvdyI9PW4/MDpZKCkpO3IubGVmdCs9YSxyLnJpZ2h0Kz1hfXJldHVybiByLnRvcCs9bCxyLmJvdHRvbSs9bCxyfWZ1bmN0aW9uIFoodCxlLHIpe2lmKCJkaXYiPT1yKXJldHVybiBlO3ZhciBuPWUubGVmdCxpPWUudG9wO2lmKCJwYWdlIj09ciluLT1ZKCksaS09aigpO2Vsc2UgaWYoImxvY2FsIj09cnx8IXIpe3ZhciBvPWZpKHQuZGlzcGxheS5zaXplcik7bis9by5sZWZ0LGkrPW8udG9wfXZhciBsPWZpKHQuZGlzcGxheS5saW5lU3BhY2UpO3JldHVybntsZWZ0Om4tbC5sZWZ0LHRvcDppLWwudG9wfX1mdW5jdGlvbiBxKHQsZSxyLG4saSl7cmV0dXJuIG58fChuPWduKHQuZG9jLGUubGluZSkpLCQodCxuLFIodCxuLGUuY2gsbnVsbCxpKSxyKX1mdW5jdGlvbiBRKHQsZSxyLG4saSl7ZnVuY3Rpb24gbyhlLG8pe3ZhciBsPVIodCxuLGUsaSxvPyJyaWdodCI6ImxlZnQiKTtyZXR1cm4gbz9sLmxlZnQ9bC5yaWdodDpsLnJpZ2h0PWwubGVmdCwkKHQsbixsLHIpfWZ1bmN0aW9uIGwodCxlKXt2YXIgcj1zW2VdLG49ci5sZXZlbCUyO3JldHVybiB0PT1taShyKSYmZSYmci5sZXZlbDxzW2UtMV0ubGV2ZWw/KHI9c1stLWVdLHQ9dmkociktKHIubGV2ZWwlMj8wOjEpLG49ITApOnQ9PXZpKHIpJiZlPHMubGVuZ3RoLTEmJnIubGV2ZWw8c1tlKzFdLmxldmVsJiYocj1zWysrZV0sdD1taShyKS1yLmxldmVsJTIsbj0hMSksbiYmdD09ci50byYmdD5yLmZyb20/byh0LTEpOm8odCxuKX1uPW58fGduKHQuZG9jLGUubGluZSksaXx8KGk9Vih0LG4pKTt2YXIgcz13bihuKSxhPWUuY2g7aWYoIXMpcmV0dXJuIG8oYSk7dmFyIHU9TGkocyxhKSxjPWwoYSx1KTtyZXR1cm4gbnVsbCE9Um8mJihjLm90aGVyPWwoYSxSbykpLGN9ZnVuY3Rpb24gSih0LGUscixuKXt2YXIgaT1uZXcgWWUodCxlKTtyZXR1cm4gaS54UmVsPW4sciYmKGkub3V0c2lkZT0hMCksaX1mdW5jdGlvbiB0ZSh0LGUscil7dmFyIG49dC5kb2M7aWYocis9dC5kaXNwbGF5LnZpZXdPZmZzZXQsMD5yKXJldHVybiBKKG4uZmlyc3QsMCwhMCwtMSk7dmFyIGk9eG4obixyKSxvPW4uZmlyc3Qrbi5zaXplLTE7aWYoaT5vKXJldHVybiBKKG4uZmlyc3Qrbi5zaXplLTEsZ24obixvKS50ZXh0Lmxlbmd0aCwhMCwxKTtmb3IoMD5lJiYoZT0wKTs7KXt2YXIgbD1nbihuLGkpLHM9ZWUodCxsLGksZSxyKSxhPUJyKGwpLHU9YSYmYS5maW5kKCk7aWYoIWF8fCEocy5jaD51LmZyb20uY2h8fHMuY2g9PXUuZnJvbS5jaCYmcy54UmVsPjApKXJldHVybiBzO2k9dS50by5saW5lfX1mdW5jdGlvbiBlZSh0LGUscixuLGkpe2Z1bmN0aW9uIG8obil7dmFyIGk9USh0LFllKHIsbiksImxpbmUiLGUsdSk7cmV0dXJuIHM9ITAsbD5pLmJvdHRvbT9pLmxlZnQtYTpsPGkudG9wP2kubGVmdCthOihzPSExLGkubGVmdCl9dmFyIGw9aS1Dbih0LGUpLHM9ITEsYT0yKnQuZGlzcGxheS53cmFwcGVyLmNsaWVudFdpZHRoLHU9Vih0LGUpLGM9d24oZSksZj1lLnRleHQubGVuZ3RoLGg9eWkoZSksZD1iaShlKSxwPW8oaCksZz1zLG09byhkKSx2PXM7aWYobj5tKXJldHVybiBKKHIsZCx2LDEpO2Zvcig7Oyl7aWYoYz9kPT1ofHxkPT1TaShlLGgsMSk6MT49ZC1oKXtmb3IodmFyIHk9cD5ufHxtLW4+PW4tcD9oOmQsYj1uLSh5PT1oP3A6bSk7RG8udGVzdChlLnRleHQuY2hhckF0KHkpKTspKyt5O3ZhciB4PUoocix5LHk9PWg/Zzp2LDA+Yj8tMTpiPzE6MCk7cmV0dXJuIHh9dmFyIEM9TWF0aC5jZWlsKGYvMiksdz1oK0M7aWYoYyl7dz1oO2Zvcih2YXIgTD0wO0M+TDsrK0wpdz1TaShlLHcsMSl9dmFyIGs9byh3KTtrPm4/KGQ9dyxtPWssKHY9cykmJihtKz0xZTMpLGY9Qyk6KGg9dyxwPWssZz1zLGYtPUMpfX1mdW5jdGlvbiByZSh0KXtpZihudWxsIT10LmNhY2hlZFRleHRIZWlnaHQpcmV0dXJuIHQuY2FjaGVkVGV4dEhlaWdodDtpZihudWxsPT1faSl7X2k9c2koInByZSIpO2Zvcih2YXIgZT0wOzQ5PmU7KytlKV9pLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJ4IikpLF9pLmFwcGVuZENoaWxkKHNpKCJiciIpKTtfaS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgieCIpKX11aSh0Lm1lYXN1cmUsX2kpO3ZhciByPV9pLm9mZnNldEhlaWdodC81MDtyZXR1cm4gcj4zJiYodC5jYWNoZWRUZXh0SGVpZ2h0PXIpLGFpKHQubWVhc3VyZSkscnx8MX1mdW5jdGlvbiBuZSh0KXtpZihudWxsIT10LmNhY2hlZENoYXJXaWR0aClyZXR1cm4gdC5jYWNoZWRDaGFyV2lkdGg7dmFyIGU9c2koInNwYW4iLCJ4Iikscj1zaSgicHJlIixbZV0pO3VpKHQubWVhc3VyZSxyKTt2YXIgbj1lLm9mZnNldFdpZHRoO3JldHVybiBuPjImJih0LmNhY2hlZENoYXJXaWR0aD1uKSxufHwxMH1mdW5jdGlvbiBpZSh0KXt0LmN1ck9wPXtjaGFuZ2VzOltdLGZvcmNlVXBkYXRlOiExLHVwZGF0ZUlucHV0Om51bGwsdXNlclNlbENoYW5nZTpudWxsLHRleHRDaGFuZ2VkOm51bGwsc2VsZWN0aW9uQ2hhbmdlZDohMSxjdXJzb3JBY3Rpdml0eTohMSx1cGRhdGVNYXhMaW5lOiExLHVwZGF0ZVNjcm9sbFBvczohMSxpZDorK0ppfSxNbysrfHwoU289W10pfWZ1bmN0aW9uIG9lKHQpe3ZhciBlPXQuY3VyT3Ascj10LmRvYyxuPXQuZGlzcGxheTtpZih0LmN1ck9wPW51bGwsZS51cGRhdGVNYXhMaW5lJiZmKHQpLG4ubWF4TGluZUNoYW5nZWQmJiF0Lm9wdGlvbnMubGluZVdyYXBwaW5nJiZuLm1heExpbmUpe3ZhciBpPVgodCxuLm1heExpbmUpO24uc2l6ZXIuc3R5bGUubWluV2lkdGg9TWF0aC5tYXgoMCxpKzMrVG8pKyJweCIsbi5tYXhMaW5lQ2hhbmdlZD0hMTt2YXIgbz1NYXRoLm1heCgwLG4uc2l6ZXIub2Zmc2V0TGVmdCtuLnNpemVyLm9mZnNldFdpZHRoLW4uc2Nyb2xsZXIuY2xpZW50V2lkdGgpO288ci5zY3JvbGxMZWZ0JiYhZS51cGRhdGVTY3JvbGxQb3MmJk1lKHQsTWF0aC5taW4obi5zY3JvbGxlci5zY3JvbGxMZWZ0LG8pLCEwKX12YXIgbCxzO2lmKGUudXBkYXRlU2Nyb2xsUG9zKWw9ZS51cGRhdGVTY3JvbGxQb3M7ZWxzZSBpZihlLnNlbGVjdGlvbkNoYW5nZWQmJm4uc2Nyb2xsZXIuY2xpZW50SGVpZ2h0KXt2YXIgYT1RKHQsci5zZWwuaGVhZCk7bD11cih0LGEubGVmdCxhLnRvcCxhLmxlZnQsYS5ib3R0b20pfWlmKChlLmNoYW5nZXMubGVuZ3RofHxlLmZvcmNlVXBkYXRlfHxsJiZudWxsIT1sLnNjcm9sbFRvcCkmJihzPWIodCxlLmNoYW5nZXMsbCYmbC5zY3JvbGxUb3AsZS5mb3JjZVVwZGF0ZSksdC5kaXNwbGF5LnNjcm9sbGVyLm9mZnNldEhlaWdodCYmKHQuZG9jLnNjcm9sbFRvcD10LmRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wKSksIXMmJmUuc2VsZWN0aW9uQ2hhbmdlZCYmQSh0KSxlLnVwZGF0ZVNjcm9sbFBvcyl7dmFyIHU9TWF0aC5tYXgoMCxNYXRoLm1pbihuLnNjcm9sbGVyLnNjcm9sbEhlaWdodC1uLnNjcm9sbGVyLmNsaWVudEhlaWdodCxsLnNjcm9sbFRvcCkpLGM9TWF0aC5tYXgoMCxNYXRoLm1pbihuLnNjcm9sbGVyLnNjcm9sbFdpZHRoLW4uc2Nyb2xsZXIuY2xpZW50V2lkdGgsbC5zY3JvbGxMZWZ0KSk7bi5zY3JvbGxlci5zY3JvbGxUb3A9bi5zY3JvbGxiYXJWLnNjcm9sbFRvcD1yLnNjcm9sbFRvcD11LG4uc2Nyb2xsZXIuc2Nyb2xsTGVmdD1uLnNjcm9sbGJhckguc2Nyb2xsTGVmdD1yLnNjcm9sbExlZnQ9YyxnKHQpLGUuc2Nyb2xsVG9Qb3MmJnNyKHQsUWUodC5kb2MsZS5zY3JvbGxUb1Bvcy5mcm9tKSxRZSh0LmRvYyxlLnNjcm9sbFRvUG9zLnRvKSxlLnNjcm9sbFRvUG9zLm1hcmdpbil9ZWxzZSBsJiZscih0KTtlLnNlbGVjdGlvbkNoYW5nZWQmJkQodCksdC5zdGF0ZS5mb2N1c2VkJiZlLnVwZGF0ZUlucHV0JiZkZSh0LGUudXNlclNlbENoYW5nZSk7dmFyIGg9ZS5tYXliZUhpZGRlbk1hcmtlcnMsZD1lLm1heWJlVW5oaWRkZW5NYXJrZXJzO2lmKGgpZm9yKHZhciBwPTA7cDxoLmxlbmd0aDsrK3ApaFtwXS5saW5lcy5sZW5ndGh8fEtuKGhbcF0sImhpZGUiKTtpZihkKWZvcih2YXIgcD0wO3A8ZC5sZW5ndGg7KytwKWRbcF0ubGluZXMubGVuZ3RoJiZLbihkW3BdLCJ1bmhpZGUiKTt2YXIgbTtpZigtLU1vfHwobT1TbyxTbz1udWxsKSxlLnRleHRDaGFuZ2VkJiZLbih0LCJjaGFuZ2UiLHQsZS50ZXh0Q2hhbmdlZCksZS5jdXJzb3JBY3Rpdml0eSYmS24odCwiY3Vyc29yQWN0aXZpdHkiLHQpLG0pZm9yKHZhciBwPTA7cDxtLmxlbmd0aDsrK3ApbVtwXSgpfWZ1bmN0aW9uIGxlKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIHI9dHx8dGhpcyxuPSFyLmN1ck9wO24mJmllKHIpO3RyeXt2YXIgaT1lLmFwcGx5KHIsYXJndW1lbnRzKX1maW5hbGx5e24mJm9lKHIpfXJldHVybiBpfX1mdW5jdGlvbiBzZSh0KXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgZSxyPXRoaXMuY20mJiF0aGlzLmNtLmN1ck9wO3ImJmllKHRoaXMuY20pO3RyeXtlPXQuYXBwbHkodGhpcyxhcmd1bWVudHMpfWZpbmFsbHl7ciYmb2UodGhpcy5jbSl9cmV0dXJuIGV9fWZ1bmN0aW9uIGFlKHQsZSl7dmFyIHIsbj0hdC5jdXJPcDtuJiZpZSh0KTt0cnl7cj1lKCl9ZmluYWxseXtuJiZvZSh0KX1yZXR1cm4gcn1mdW5jdGlvbiB1ZSh0LGUscixuKXtudWxsPT1lJiYoZT10LmRvYy5maXJzdCksbnVsbD09ciYmKHI9dC5kb2MuZmlyc3QrdC5kb2Muc2l6ZSksdC5jdXJPcC5jaGFuZ2VzLnB1c2goe2Zyb206ZSx0bzpyLGRpZmY6bn0pfWZ1bmN0aW9uIGNlKHQpe3QuZGlzcGxheS5wb2xsaW5nRmFzdHx8dC5kaXNwbGF5LnBvbGwuc2V0KHQub3B0aW9ucy5wb2xsSW50ZXJ2YWwsZnVuY3Rpb24oKXtoZSh0KSx0LnN0YXRlLmZvY3VzZWQmJmNlKHQpfSl9ZnVuY3Rpb24gZmUodCl7ZnVuY3Rpb24gZSgpe3ZhciBuPWhlKHQpO258fHI/KHQuZGlzcGxheS5wb2xsaW5nRmFzdD0hMSxjZSh0KSk6KHI9ITAsdC5kaXNwbGF5LnBvbGwuc2V0KDYwLGUpKX12YXIgcj0hMTt0LmRpc3BsYXkucG9sbGluZ0Zhc3Q9ITAsdC5kaXNwbGF5LnBvbGwuc2V0KDIwLGUpfWZ1bmN0aW9uIGhlKHQpe3ZhciBlPXQuZGlzcGxheS5pbnB1dCxyPXQuZGlzcGxheS5wcmV2SW5wdXQsbj10LmRvYyxpPW4uc2VsO2lmKCF0LnN0YXRlLmZvY3VzZWR8fElvKGUpfHxnZSh0KXx8dC5zdGF0ZS5kaXNhYmxlSW5wdXQpcmV0dXJuITE7dC5zdGF0ZS5wYXN0ZUluY29taW5nJiZ0LnN0YXRlLmZha2VkTGFzdENoYXImJihlLnZhbHVlPWUudmFsdWUuc3Vic3RyaW5nKDAsZS52YWx1ZS5sZW5ndGgtMSksdC5zdGF0ZS5mYWtlZExhc3RDaGFyPSExKTt2YXIgbz1lLnZhbHVlO2lmKG89PXImJmplKGkuZnJvbSxpLnRvKSlyZXR1cm4hMTtpZihBaSYmIU5pJiZ0LmRpc3BsYXkuaW5wdXRIYXNTZWxlY3Rpb249PT1vKXJldHVybiBkZSh0LCEwKSwhMTt2YXIgbD0hdC5jdXJPcDtsJiZpZSh0KSxpLnNoaWZ0PSExO2Zvcih2YXIgcz0wLGE9TWF0aC5taW4oci5sZW5ndGgsby5sZW5ndGgpO2E+cyYmci5jaGFyQ29kZUF0KHMpPT1vLmNoYXJDb2RlQXQocyk7KSsrczt2YXIgdT1pLmZyb20sYz1pLnRvO3M8ci5sZW5ndGg/dT1ZZSh1LmxpbmUsdS5jaC0oci5sZW5ndGgtcykpOnQuc3RhdGUub3ZlcndyaXRlJiZqZSh1LGMpJiYhdC5zdGF0ZS5wYXN0ZUluY29taW5nJiYoYz1ZZShjLmxpbmUsTWF0aC5taW4oZ24obixjLmxpbmUpLnRleHQubGVuZ3RoLGMuY2grKG8ubGVuZ3RoLXMpKSkpO3ZhciBmPXQuY3VyT3AudXBkYXRlSW5wdXQsaD17ZnJvbTp1LHRvOmMsdGV4dDp6byhvLnNsaWNlKHMpKSxvcmlnaW46dC5zdGF0ZS5wYXN0ZUluY29taW5nPyJwYXN0ZSI6IitpbnB1dCJ9O3JldHVybiBCZSh0LmRvYyxoLCJlbmQiKSx0LmN1ck9wLnVwZGF0ZUlucHV0PWYsVW4odCwiaW5wdXRSZWFkIix0LGgpLG8ubGVuZ3RoPjFlM3x8by5pbmRleE9mKCJcbiIpPi0xP2UudmFsdWU9dC5kaXNwbGF5LnByZXZJbnB1dD0iIjp0LmRpc3BsYXkucHJldklucHV0PW8sbCYmb2UodCksdC5zdGF0ZS5wYXN0ZUluY29taW5nPSExLCEwfWZ1bmN0aW9uIGRlKHQsZSl7dmFyIHIsbixpPXQuZG9jO2lmKGplKGkuc2VsLmZyb20saS5zZWwudG8pKWUmJih0LmRpc3BsYXkucHJldklucHV0PXQuZGlzcGxheS5pbnB1dC52YWx1ZT0iIixBaSYmIU5pJiYodC5kaXNwbGF5LmlucHV0SGFzU2VsZWN0aW9uPW51bGwpKTtlbHNle3QuZGlzcGxheS5wcmV2SW5wdXQ9IiIscj1GbyYmKGkuc2VsLnRvLmxpbmUtaS5zZWwuZnJvbS5saW5lPjEwMHx8KG49dC5nZXRTZWxlY3Rpb24oKSkubGVuZ3RoPjFlMyk7dmFyIG89cj8iLSI6bnx8dC5nZXRTZWxlY3Rpb24oKTt0LmRpc3BsYXkuaW5wdXQudmFsdWU9byx0LnN0YXRlLmZvY3VzZWQmJkpuKHQuZGlzcGxheS5pbnB1dCksQWkmJiFOaSYmKHQuZGlzcGxheS5pbnB1dEhhc1NlbGVjdGlvbj1vKX10LmRpc3BsYXkuaW5hY2N1cmF0ZVNlbGVjdGlvbj1yfWZ1bmN0aW9uIHBlKHQpeyJub2N1cnNvciI9PXQub3B0aW9ucy5yZWFkT25seXx8VmkmJmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ9PXQuZGlzcGxheS5pbnB1dHx8dC5kaXNwbGF5LmlucHV0LmZvY3VzKCl9ZnVuY3Rpb24gZ2UodCl7cmV0dXJuIHQub3B0aW9ucy5yZWFkT25seXx8dC5kb2MuY2FudEVkaXR9ZnVuY3Rpb24gbWUodCl7ZnVuY3Rpb24gZSgpe3Quc3RhdGUuZm9jdXNlZCYmc2V0VGltZW91dChpaShwZSx0KSwwKX1mdW5jdGlvbiByKCl7bnVsbD09cyYmKHM9c2V0VGltZW91dChmdW5jdGlvbigpe3M9bnVsbCxsLmNhY2hlZENoYXJXaWR0aD1sLmNhY2hlZFRleHRIZWlnaHQ9T289bnVsbCxfKHQpLGFlKHQsaWkodWUsdCkpfSwxMDApKX1mdW5jdGlvbiBuKCl7Zm9yKHZhciB0PWwud3JhcHBlci5wYXJlbnROb2RlO3QmJnQhPWRvY3VtZW50LmJvZHk7dD10LnBhcmVudE5vZGUpO3Q/c2V0VGltZW91dChuLDVlMyk6Vm4od2luZG93LCJyZXNpemUiLHIpfWZ1bmN0aW9uIGkoZSl7WG4odCxlKXx8dC5vcHRpb25zLm9uRHJhZ0V2ZW50JiZ0Lm9wdGlvbnMub25EcmFnRXZlbnQodCxFbihlKSl8fFBuKGUpfWZ1bmN0aW9uIG8oKXtsLmluYWNjdXJhdGVTZWxlY3Rpb24mJihsLnByZXZJbnB1dD0iIixsLmluYWNjdXJhdGVTZWxlY3Rpb249ITEsbC5pbnB1dC52YWx1ZT10LmdldFNlbGVjdGlvbigpLEpuKGwuaW5wdXQpKX12YXIgbD10LmRpc3BsYXk7R24obC5zY3JvbGxlciwibW91c2Vkb3duIixsZSh0LGJlKSksQWk/R24obC5zY3JvbGxlciwiZGJsY2xpY2siLGxlKHQsZnVuY3Rpb24oZSl7aWYoIVhuKHQsZSkpe3ZhciByPXllKHQsZSk7aWYociYmIXdlKHQsZSkmJiF2ZSh0LmRpc3BsYXksZSkpe3puKGUpO3ZhciBuPW1yKGduKHQuZG9jLHIubGluZSkudGV4dCxyKTtlcih0LmRvYyxuLmZyb20sbi50byl9fX0pKTpHbihsLnNjcm9sbGVyLCJkYmxjbGljayIsZnVuY3Rpb24oZSl7WG4odCxlKXx8em4oZSl9KSxHbihsLmxpbmVTcGFjZSwic2VsZWN0c3RhcnQiLGZ1bmN0aW9uKHQpe3ZlKGwsdCl8fHpuKHQpfSksWml8fEduKGwuc2Nyb2xsZXIsImNvbnRleHRtZW51IixmdW5jdGlvbihlKXtJZSh0LGUpfSksR24obC5zY3JvbGxlciwic2Nyb2xsIixmdW5jdGlvbigpe2wuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0JiYoU2UodCxsLnNjcm9sbGVyLnNjcm9sbFRvcCksTWUodCxsLnNjcm9sbGVyLnNjcm9sbExlZnQsITApLEtuKHQsInNjcm9sbCIsdCkpfSksR24obC5zY3JvbGxiYXJWLCJzY3JvbGwiLGZ1bmN0aW9uKCl7bC5zY3JvbGxlci5jbGllbnRIZWlnaHQmJlNlKHQsbC5zY3JvbGxiYXJWLnNjcm9sbFRvcCl9KSxHbihsLnNjcm9sbGJhckgsInNjcm9sbCIsZnVuY3Rpb24oKXtsLnNjcm9sbGVyLmNsaWVudEhlaWdodCYmTWUodCxsLnNjcm9sbGJhckguc2Nyb2xsTGVmdCl9KSxHbihsLnNjcm9sbGVyLCJtb3VzZXdoZWVsIixmdW5jdGlvbihlKXtUZSh0LGUpfSksR24obC5zY3JvbGxlciwiRE9NTW91c2VTY3JvbGwiLGZ1bmN0aW9uKGUpe1RlKHQsZSl9KSxHbihsLnNjcm9sbGJhckgsIm1vdXNlZG93biIsZSksR24obC5zY3JvbGxiYXJWLCJtb3VzZWRvd24iLGUpLEduKGwud3JhcHBlciwic2Nyb2xsIixmdW5jdGlvbigpe2wud3JhcHBlci5zY3JvbGxUb3A9bC53cmFwcGVyLnNjcm9sbExlZnQ9MH0pO3ZhciBzO0duKHdpbmRvdywicmVzaXplIixyKSxzZXRUaW1lb3V0KG4sNWUzKSxHbihsLmlucHV0LCJrZXl1cCIsbGUodCxmdW5jdGlvbihlKXtYbih0LGUpfHx0Lm9wdGlvbnMub25LZXlFdmVudCYmdC5vcHRpb25zLm9uS2V5RXZlbnQodCxFbihlKSl8fDE2PT1lLmtleUNvZGUmJih0LmRvYy5zZWwuc2hpZnQ9ITEpfSkpLEduKGwuaW5wdXQsImlucHV0IixmdW5jdGlvbigpe0FpJiYhTmkmJnQuZGlzcGxheS5pbnB1dEhhc1NlbGVjdGlvbiYmKHQuZGlzcGxheS5pbnB1dEhhc1NlbGVjdGlvbj1udWxsKSxmZSh0KX0pLEduKGwuaW5wdXQsImtleWRvd24iLGxlKHQsV2UpKSxHbihsLmlucHV0LCJrZXlwcmVzcyIsbGUodCxPZSkpLEduKGwuaW5wdXQsImZvY3VzIixpaShFZSx0KSksR24obC5pbnB1dCwiYmx1ciIsaWkoemUsdCkpLHQub3B0aW9ucy5kcmFnRHJvcCYmKEduKGwuc2Nyb2xsZXIsImRyYWdzdGFydCIsZnVuY3Rpb24oZSl7a2UodCxlKX0pLEduKGwuc2Nyb2xsZXIsImRyYWdlbnRlciIsaSksR24obC5zY3JvbGxlciwiZHJhZ292ZXIiLGkpLEduKGwuc2Nyb2xsZXIsImRyb3AiLGxlKHQsTGUpKSksR24obC5zY3JvbGxlciwicGFzdGUiLGZ1bmN0aW9uKGUpe3ZlKGwsZSl8fChwZSh0KSxmZSh0KSl9KSxHbihsLmlucHV0LCJwYXN0ZSIsZnVuY3Rpb24oKXtpZihXaSYmIXQuc3RhdGUuZmFrZWRMYXN0Q2hhciYmIShuZXcgRGF0ZS10LnN0YXRlLmxhc3RNaWRkbGVEb3duPDIwMCkpe3ZhciBlPWwuaW5wdXQuc2VsZWN0aW9uU3RhcnQscj1sLmlucHV0LnNlbGVjdGlvbkVuZDtsLmlucHV0LnZhbHVlKz0iJCIsbC5pbnB1dC5zZWxlY3Rpb25TdGFydD1lLGwuaW5wdXQuc2VsZWN0aW9uRW5kPXIsdC5zdGF0ZS5mYWtlZExhc3RDaGFyPSEwfXQuc3RhdGUucGFzdGVJbmNvbWluZz0hMCxmZSh0KX0pLEduKGwuaW5wdXQsImN1dCIsbyksR24obC5pbnB1dCwiY29weSIsbyksRmkmJkduKGwuc2l6ZXIsIm1vdXNldXAiLGZ1bmN0aW9uKCl7ZG9jdW1lbnQuYWN0aXZlRWxlbWVudD09bC5pbnB1dCYmbC5pbnB1dC5ibHVyKCkscGUodCl9KX1mdW5jdGlvbiB2ZSh0LGUpe2Zvcih2YXIgcj1SbihlKTtyIT10LndyYXBwZXI7cj1yLnBhcmVudE5vZGUpaWYoIXJ8fHIuaWdub3JlRXZlbnRzfHxyLnBhcmVudE5vZGU9PXQuc2l6ZXImJnIhPXQubW92ZXIpcmV0dXJuITB9ZnVuY3Rpb24geWUodCxlLHIpe3ZhciBuPXQuZGlzcGxheTtpZighcil7dmFyIGk9Um4oZSk7aWYoaT09bi5zY3JvbGxiYXJIfHxpPT1uLnNjcm9sbGJhckguZmlyc3RDaGlsZHx8aT09bi5zY3JvbGxiYXJWfHxpPT1uLnNjcm9sbGJhclYuZmlyc3RDaGlsZHx8aT09bi5zY3JvbGxiYXJGaWxsZXJ8fGk9PW4uZ3V0dGVyRmlsbGVyKXJldHVybiBudWxsfXZhciBvLGwscz1maShuLmxpbmVTcGFjZSk7dHJ5e289ZS5jbGllbnRYLGw9ZS5jbGllbnRZfWNhdGNoKGUpe3JldHVybiBudWxsfXJldHVybiB0ZSh0LG8tcy5sZWZ0LGwtcy50b3ApfWZ1bmN0aW9uIGJlKHQpe2Z1bmN0aW9uIGUodCl7aWYoIWplKHYsdCkpe2lmKHY9dCwic2luZ2xlIj09YylyZXR1cm4gZXIoaS5kb2MsUWUobCxhKSx0KSx2b2lkIDA7CmlmKGc9UWUobCxnKSxtPVFlKGwsbSksImRvdWJsZSI9PWMpe3ZhciBlPW1yKGduKGwsdC5saW5lKS50ZXh0LHQpOyRlKHQsZyk/ZXIoaS5kb2MsZS5mcm9tLG0pOmVyKGkuZG9jLGcsZS50byl9ZWxzZSJ0cmlwbGUiPT1jJiYoJGUodCxnKT9lcihpLmRvYyxtLFFlKGwsWWUodC5saW5lLDApKSk6ZXIoaS5kb2MsZyxRZShsLFllKHQubGluZSsxLDApKSkpfX1mdW5jdGlvbiByKHQpe3ZhciBuPSsrYixzPXllKGksdCwhMCk7aWYocylpZihqZShzLGgpKXt2YXIgYT10LmNsaWVudFk8eS50b3A/LTIwOnQuY2xpZW50WT55LmJvdHRvbT8yMDowO2EmJnNldFRpbWVvdXQobGUoaSxmdW5jdGlvbigpe2I9PW4mJihvLnNjcm9sbGVyLnNjcm9sbFRvcCs9YSxyKHQpKX0pLDUwKX1lbHNle2kuc3RhdGUuZm9jdXNlZHx8RWUoaSksaD1zLGUocyk7dmFyIHU9cChvLGwpOyhzLmxpbmU+PXUudG98fHMubGluZTx1LmZyb20pJiZzZXRUaW1lb3V0KGxlKGksZnVuY3Rpb24oKXtiPT1uJiZyKHQpfSksMTUwKX19ZnVuY3Rpb24gbih0KXtiPTEvMCx6bih0KSxwZShpKSxWbihkb2N1bWVudCwibW91c2Vtb3ZlIix4KSxWbihkb2N1bWVudCwibW91c2V1cCIsQyl9aWYoIVhuKHRoaXMsdCkpe3ZhciBpPXRoaXMsbz1pLmRpc3BsYXksbD1pLmRvYyxzPWwuc2VsO2lmKHMuc2hpZnQ9dC5zaGlmdEtleSx2ZShvLHQpKXJldHVybiBXaXx8KG8uc2Nyb2xsZXIuZHJhZ2dhYmxlPSExLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtvLnNjcm9sbGVyLmRyYWdnYWJsZT0hMH0sMTAwKSksdm9pZCAwO2lmKCF3ZShpLHQpKXt2YXIgYT15ZShpLHQpO3N3aXRjaChCbih0KSl7Y2FzZSAzOnJldHVybiBaaSYmSWUuY2FsbChpLGksdCksdm9pZCAwO2Nhc2UgMjpyZXR1cm4gV2kmJihpLnN0YXRlLmxhc3RNaWRkbGVEb3duPStuZXcgRGF0ZSksYSYmZXIoaS5kb2MsYSksc2V0VGltZW91dChpaShwZSxpKSwyMCksem4odCksdm9pZCAwfWlmKCFhKXJldHVybiBSbih0KT09by5zY3JvbGxlciYmem4odCksdm9pZCAwO2kuc3RhdGUuZm9jdXNlZHx8RWUoaSk7dmFyIHU9K25ldyBEYXRlLGM9InNpbmdsZSI7aWYoamkmJmppLnRpbWU+dS00MDAmJmplKGppLnBvcyxhKSljPSJ0cmlwbGUiLHpuKHQpLHNldFRpbWVvdXQoaWkocGUsaSksMjApLHZyKGksYS5saW5lKTtlbHNlIGlmKFlpJiZZaS50aW1lPnUtNDAwJiZqZShZaS5wb3MsYSkpe2M9ImRvdWJsZSIsamk9e3RpbWU6dSxwb3M6YX0sem4odCk7dmFyIGY9bXIoZ24obCxhLmxpbmUpLnRleHQsYSk7ZXIoaS5kb2MsZi5mcm9tLGYudG8pfWVsc2UgWWk9e3RpbWU6dSxwb3M6YX07dmFyIGg9YTtpZihpLm9wdGlvbnMuZHJhZ0Ryb3AmJldvJiYhZ2UoaSkmJiFqZShzLmZyb20scy50bykmJiEkZShhLHMuZnJvbSkmJiEkZShzLnRvLGEpJiYic2luZ2xlIj09Yyl7dmFyIGQ9bGUoaSxmdW5jdGlvbihlKXtXaSYmKG8uc2Nyb2xsZXIuZHJhZ2dhYmxlPSExKSxpLnN0YXRlLmRyYWdnaW5nVGV4dD0hMSxWbihkb2N1bWVudCwibW91c2V1cCIsZCksVm4oby5zY3JvbGxlciwiZHJvcCIsZCksTWF0aC5hYnModC5jbGllbnRYLWUuY2xpZW50WCkrTWF0aC5hYnModC5jbGllbnRZLWUuY2xpZW50WSk8MTAmJih6bihlKSxlcihpLmRvYyxhKSxwZShpKSl9KTtyZXR1cm4gV2kmJihvLnNjcm9sbGVyLmRyYWdnYWJsZT0hMCksaS5zdGF0ZS5kcmFnZ2luZ1RleHQ9ZCxvLnNjcm9sbGVyLmRyYWdEcm9wJiZvLnNjcm9sbGVyLmRyYWdEcm9wKCksR24oZG9jdW1lbnQsIm1vdXNldXAiLGQpLEduKG8uc2Nyb2xsZXIsImRyb3AiLGQpLHZvaWQgMH16bih0KSwic2luZ2xlIj09YyYmZXIoaS5kb2MsUWUobCxhKSk7dmFyIGc9cy5mcm9tLG09cy50byx2PWEseT1maShvLndyYXBwZXIpLGI9MCx4PWxlKGksZnVuY3Rpb24odCl7QWl8fEJuKHQpP3IodCk6bih0KX0pLEM9bGUoaSxuKTtHbihkb2N1bWVudCwibW91c2Vtb3ZlIix4KSxHbihkb2N1bWVudCwibW91c2V1cCIsQyl9fX1mdW5jdGlvbiB4ZSh0LGUscixuLGkpe3RyeXt2YXIgbz1lLmNsaWVudFgsbD1lLmNsaWVudFl9Y2F0Y2goZSl7cmV0dXJuITF9aWYobz49TWF0aC5mbG9vcihmaSh0LmRpc3BsYXkuZ3V0dGVycykucmlnaHQpKXJldHVybiExO24mJnpuKGUpO3ZhciBzPXQuZGlzcGxheSxhPWZpKHMubGluZURpdik7aWYobD5hLmJvdHRvbXx8IVluKHQscikpcmV0dXJuIEZuKGUpO2wtPWEudG9wLXMudmlld09mZnNldDtmb3IodmFyIHU9MDt1PHQub3B0aW9ucy5ndXR0ZXJzLmxlbmd0aDsrK3Upe3ZhciBjPXMuZ3V0dGVycy5jaGlsZE5vZGVzW3VdO2lmKGMmJmZpKGMpLnJpZ2h0Pj1vKXt2YXIgZj14bih0LmRvYyxsKSxoPXQub3B0aW9ucy5ndXR0ZXJzW3VdO3JldHVybiBpKHQscix0LGYsaCxlKSxGbihlKX19fWZ1bmN0aW9uIENlKHQsZSl7cmV0dXJuIFluKHQsImd1dHRlckNvbnRleHRNZW51Iik/eGUodCxlLCJndXR0ZXJDb250ZXh0TWVudSIsITEsS24pOiExfWZ1bmN0aW9uIHdlKHQsZSl7cmV0dXJuIHhlKHQsZSwiZ3V0dGVyQ2xpY2siLCEwLFVuKX1mdW5jdGlvbiBMZSh0KXt2YXIgZT10aGlzO2lmKCEoWG4oZSx0KXx8dmUoZS5kaXNwbGF5LHQpfHxlLm9wdGlvbnMub25EcmFnRXZlbnQmJmUub3B0aW9ucy5vbkRyYWdFdmVudChlLEVuKHQpKSkpe3puKHQpLEFpJiYodG89K25ldyBEYXRlKTt2YXIgcj15ZShlLHQsITApLG49dC5kYXRhVHJhbnNmZXIuZmlsZXM7aWYociYmIWdlKGUpKWlmKG4mJm4ubGVuZ3RoJiZ3aW5kb3cuRmlsZVJlYWRlciYmd2luZG93LkZpbGUpZm9yKHZhciBpPW4ubGVuZ3RoLG89QXJyYXkoaSksbD0wLHM9ZnVuY3Rpb24odCxuKXt2YXIgcz1uZXcgRmlsZVJlYWRlcjtzLm9ubG9hZD1mdW5jdGlvbigpe29bbl09cy5yZXN1bHQsKytsPT1pJiYocj1RZShlLmRvYyxyKSxCZShlLmRvYyx7ZnJvbTpyLHRvOnIsdGV4dDp6byhvLmpvaW4oIlxuIikpLG9yaWdpbjoicGFzdGUifSwiYXJvdW5kIikpfSxzLnJlYWRBc1RleHQodCl9LGE9MDtpPmE7KythKXMoblthXSxhKTtlbHNle2lmKGUuc3RhdGUuZHJhZ2dpbmdUZXh0JiYhJGUocixlLmRvYy5zZWwuZnJvbSkmJiEkZShlLmRvYy5zZWwudG8scikpcmV0dXJuIGUuc3RhdGUuZHJhZ2dpbmdUZXh0KHQpLHNldFRpbWVvdXQoaWkocGUsZSksMjApLHZvaWQgMDt0cnl7dmFyIG89dC5kYXRhVHJhbnNmZXIuZ2V0RGF0YSgiVGV4dCIpO2lmKG8pe3ZhciB1PWUuZG9jLnNlbC5mcm9tLGM9ZS5kb2Muc2VsLnRvO25yKGUuZG9jLHIsciksZS5zdGF0ZS5kcmFnZ2luZ1RleHQmJl9lKGUuZG9jLCIiLHUsYywicGFzdGUiKSxlLnJlcGxhY2VTZWxlY3Rpb24obyxudWxsLCJwYXN0ZSIpLHBlKGUpfX1jYXRjaCh0KXt9fX19ZnVuY3Rpb24ga2UodCxlKXtpZihBaSYmKCF0LnN0YXRlLmRyYWdnaW5nVGV4dHx8K25ldyBEYXRlLXRvPDEwMCkpcmV0dXJuIFBuKGUpLHZvaWQgMDtpZighWG4odCxlKSYmIXZlKHQuZGlzcGxheSxlKSl7dmFyIHI9dC5nZXRTZWxlY3Rpb24oKTtpZihlLmRhdGFUcmFuc2Zlci5zZXREYXRhKCJUZXh0IixyKSxlLmRhdGFUcmFuc2Zlci5zZXREcmFnSW1hZ2UmJiFJaSl7dmFyIG49c2koImltZyIsbnVsbCxudWxsLCJwb3NpdGlvbjogZml4ZWQ7IGxlZnQ6IDA7IHRvcDogMDsiKTtuLnNyYz0iZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoQVFBQkFBQUFBQ0g1QkFFS0FBRUFMQUFBQUFBQkFBRUFBQUlDVEFFQU93PT0iLHppJiYobi53aWR0aD1uLmhlaWdodD0xLHQuZGlzcGxheS53cmFwcGVyLmFwcGVuZENoaWxkKG4pLG4uX3RvcD1uLm9mZnNldFRvcCksZS5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKG4sMCwwKSx6aSYmbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pfX19ZnVuY3Rpb24gU2UodCxlKXtNYXRoLmFicyh0LmRvYy5zY3JvbGxUb3AtZSk8Mnx8KHQuZG9jLnNjcm9sbFRvcD1lLFRpfHxiKHQsW10sZSksdC5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcCE9ZSYmKHQuZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3A9ZSksdC5kaXNwbGF5LnNjcm9sbGJhclYuc2Nyb2xsVG9wIT1lJiYodC5kaXNwbGF5LnNjcm9sbGJhclYuc2Nyb2xsVG9wPWUpLFRpJiZiKHQsW10pLFcodCwxMDApKX1mdW5jdGlvbiBNZSh0LGUscil7KHI/ZT09dC5kb2Muc2Nyb2xsTGVmdDpNYXRoLmFicyh0LmRvYy5zY3JvbGxMZWZ0LWUpPDIpfHwoZT1NYXRoLm1pbihlLHQuZGlzcGxheS5zY3JvbGxlci5zY3JvbGxXaWR0aC10LmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGgpLHQuZG9jLnNjcm9sbExlZnQ9ZSxnKHQpLHQuZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0IT1lJiYodC5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQ9ZSksdC5kaXNwbGF5LnNjcm9sbGJhckguc2Nyb2xsTGVmdCE9ZSYmKHQuZGlzcGxheS5zY3JvbGxiYXJILnNjcm9sbExlZnQ9ZSkpfWZ1bmN0aW9uIFRlKHQsZSl7dmFyIHI9ZS53aGVlbERlbHRhWCxuPWUud2hlZWxEZWx0YVk7bnVsbD09ciYmZS5kZXRhaWwmJmUuYXhpcz09ZS5IT1JJWk9OVEFMX0FYSVMmJihyPWUuZGV0YWlsKSxudWxsPT1uJiZlLmRldGFpbCYmZS5heGlzPT1lLlZFUlRJQ0FMX0FYSVM/bj1lLmRldGFpbDpudWxsPT1uJiYobj1lLndoZWVsRGVsdGEpO3ZhciBpPXQuZGlzcGxheSxvPWkuc2Nyb2xsZXI7aWYociYmby5zY3JvbGxXaWR0aD5vLmNsaWVudFdpZHRofHxuJiZvLnNjcm9sbEhlaWdodD5vLmNsaWVudEhlaWdodCl7aWYobiYmS2kmJldpKWZvcih2YXIgbD1lLnRhcmdldDtsIT1vO2w9bC5wYXJlbnROb2RlKWlmKGwubGluZU9iail7dC5kaXNwbGF5LmN1cnJlbnRXaGVlbFRhcmdldD1sO2JyZWFrfWlmKHImJiFUaSYmIXppJiZudWxsIT1ybylyZXR1cm4gbiYmU2UodCxNYXRoLm1heCgwLE1hdGgubWluKG8uc2Nyb2xsVG9wK24qcm8sby5zY3JvbGxIZWlnaHQtby5jbGllbnRIZWlnaHQpKSksTWUodCxNYXRoLm1heCgwLE1hdGgubWluKG8uc2Nyb2xsTGVmdCtyKnJvLG8uc2Nyb2xsV2lkdGgtby5jbGllbnRXaWR0aCkpKSx6bihlKSxpLndoZWVsU3RhcnRYPW51bGwsdm9pZCAwO2lmKG4mJm51bGwhPXJvKXt2YXIgcz1uKnJvLGE9dC5kb2Muc2Nyb2xsVG9wLHU9YStpLndyYXBwZXIuY2xpZW50SGVpZ2h0OzA+cz9hPU1hdGgubWF4KDAsYStzLTUwKTp1PU1hdGgubWluKHQuZG9jLmhlaWdodCx1K3MrNTApLGIodCxbXSx7dG9wOmEsYm90dG9tOnV9KX0yMD5lbyYmKG51bGw9PWkud2hlZWxTdGFydFg/KGkud2hlZWxTdGFydFg9by5zY3JvbGxMZWZ0LGkud2hlZWxTdGFydFk9by5zY3JvbGxUb3AsaS53aGVlbERYPXIsaS53aGVlbERZPW4sc2V0VGltZW91dChmdW5jdGlvbigpe2lmKG51bGwhPWkud2hlZWxTdGFydFgpe3ZhciB0PW8uc2Nyb2xsTGVmdC1pLndoZWVsU3RhcnRYLGU9by5zY3JvbGxUb3AtaS53aGVlbFN0YXJ0WSxyPWUmJmkud2hlZWxEWSYmZS9pLndoZWVsRFl8fHQmJmkud2hlZWxEWCYmdC9pLndoZWVsRFg7aS53aGVlbFN0YXJ0WD1pLndoZWVsU3RhcnRZPW51bGwsciYmKHJvPShybyplbytyKS8oZW8rMSksKytlbyl9fSwyMDApKTooaS53aGVlbERYKz1yLGkud2hlZWxEWSs9bikpfX1mdW5jdGlvbiBBZSh0LGUscil7aWYoInN0cmluZyI9PXR5cGVvZiBlJiYoZT1tb1tlXSwhZSkpcmV0dXJuITE7dC5kaXNwbGF5LnBvbGxpbmdGYXN0JiZoZSh0KSYmKHQuZGlzcGxheS5wb2xsaW5nRmFzdD0hMSk7dmFyIG49dC5kb2MsaT1uLnNlbC5zaGlmdCxvPSExO3RyeXtnZSh0KSYmKHQuc3RhdGUuc3VwcHJlc3NFZGl0cz0hMCksciYmKG4uc2VsLnNoaWZ0PSExKSxvPWUodCkhPUFvfWZpbmFsbHl7bi5zZWwuc2hpZnQ9aSx0LnN0YXRlLnN1cHByZXNzRWRpdHM9ITF9cmV0dXJuIG99ZnVuY3Rpb24gSGUodCl7dmFyIGU9dC5zdGF0ZS5rZXlNYXBzLnNsaWNlKDApO3JldHVybiB0Lm9wdGlvbnMuZXh0cmFLZXlzJiZlLnB1c2godC5vcHRpb25zLmV4dHJhS2V5cyksZS5wdXNoKHQub3B0aW9ucy5rZXlNYXApLGV9ZnVuY3Rpb24gTmUodCxlKXt2YXIgcj1Dcih0Lm9wdGlvbnMua2V5TWFwKSxuPXIuYXV0bztjbGVhclRpbWVvdXQobm8pLG4mJiFMcihlKSYmKG5vPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtDcih0Lm9wdGlvbnMua2V5TWFwKT09ciYmKHQub3B0aW9ucy5rZXlNYXA9bi5jYWxsP24uY2FsbChudWxsLHQpOm4sbCh0KSl9LDUwKSk7dmFyIGk9a3IoZSwhMCksbz0hMTtpZighaSlyZXR1cm4hMTt2YXIgcz1IZSh0KTtyZXR1cm4gbz1lLnNoaWZ0S2V5P3dyKCJTaGlmdC0iK2kscyxmdW5jdGlvbihlKXtyZXR1cm4gQWUodCxlLCEwKX0pfHx3cihpLHMsZnVuY3Rpb24oZSl7cmV0dXJuKCJzdHJpbmciPT10eXBlb2YgZT8vXmdvW0EtWl0vLnRlc3QoZSk6ZS5tb3Rpb24pP0FlKHQsZSk6dm9pZCAwfSk6d3IoaSxzLGZ1bmN0aW9uKGUpe3JldHVybiBBZSh0LGUpfSksbyYmKHpuKGUpLEQodCksTmkmJihlLm9sZEtleUNvZGU9ZS5rZXlDb2RlLGUua2V5Q29kZT0wKSxVbih0LCJrZXlIYW5kbGVkIix0LGksZSkpLG99ZnVuY3Rpb24gRGUodCxlLHIpe3ZhciBuPXdyKCInIityKyInIixIZSh0KSxmdW5jdGlvbihlKXtyZXR1cm4gQWUodCxlLCEwKX0pO3JldHVybiBuJiYoem4oZSksRCh0KSxVbih0LCJrZXlIYW5kbGVkIix0LCInIityKyInIixlKSksbn1mdW5jdGlvbiBXZSh0KXt2YXIgZT10aGlzO2lmKGUuc3RhdGUuZm9jdXNlZHx8RWUoZSksIShYbihlLHQpfHxlLm9wdGlvbnMub25LZXlFdmVudCYmZS5vcHRpb25zLm9uS2V5RXZlbnQoZSxFbih0KSkpKXtBaSYmMjc9PXQua2V5Q29kZSYmKHQucmV0dXJuVmFsdWU9ITEpO3ZhciByPXQua2V5Q29kZTtlLmRvYy5zZWwuc2hpZnQ9MTY9PXJ8fHQuc2hpZnRLZXk7dmFyIG49TmUoZSx0KTt6aSYmKG9vPW4/cjpudWxsLCFuJiY4OD09ciYmIUZvJiYoS2k/dC5tZXRhS2V5OnQuY3RybEtleSkmJmUucmVwbGFjZVNlbGVjdGlvbigiIikpfX1mdW5jdGlvbiBPZSh0KXt2YXIgZT10aGlzO2lmKCEoWG4oZSx0KXx8ZS5vcHRpb25zLm9uS2V5RXZlbnQmJmUub3B0aW9ucy5vbktleUV2ZW50KGUsRW4odCkpKSl7dmFyIHI9dC5rZXlDb2RlLG49dC5jaGFyQ29kZTtpZih6aSYmcj09b28pcmV0dXJuIG9vPW51bGwsem4odCksdm9pZCAwO2lmKCEoemkmJighdC53aGljaHx8dC53aGljaDwxMCl8fEZpKXx8IU5lKGUsdCkpe3ZhciBpPVN0cmluZy5mcm9tQ2hhckNvZGUobnVsbD09bj9yOm4pO3RoaXMub3B0aW9ucy5lbGVjdHJpY0NoYXJzJiZ0aGlzLmRvYy5tb2RlLmVsZWN0cmljQ2hhcnMmJnRoaXMub3B0aW9ucy5zbWFydEluZGVudCYmIWdlKHRoaXMpJiZ0aGlzLmRvYy5tb2RlLmVsZWN0cmljQ2hhcnMuaW5kZXhPZihpKT4tMSYmc2V0VGltZW91dChsZShlLGZ1bmN0aW9uKCl7aHIoZSxlLmRvYy5zZWwudG8ubGluZSwic21hcnQiKX0pLDc1KSxEZShlLHQsaSl8fChBaSYmIU5pJiYoZS5kaXNwbGF5LmlucHV0SGFzU2VsZWN0aW9uPW51bGwpLGZlKGUpKX19fWZ1bmN0aW9uIEVlKHQpeyJub2N1cnNvciIhPXQub3B0aW9ucy5yZWFkT25seSYmKHQuc3RhdGUuZm9jdXNlZHx8KEtuKHQsImZvY3VzIix0KSx0LnN0YXRlLmZvY3VzZWQ9ITAsLTE9PXQuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZS5zZWFyY2goL1xiQ29kZU1pcnJvci1mb2N1c2VkXGIvKSYmKHQuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZSs9IiBDb2RlTWlycm9yLWZvY3VzZWQiKSx0LmN1ck9wfHwoZGUodCwhMCksV2kmJnNldFRpbWVvdXQoaWkoZGUsdCwhMCksMCkpKSxjZSh0KSxEKHQpKX1mdW5jdGlvbiB6ZSh0KXt0LnN0YXRlLmZvY3VzZWQmJihLbih0LCJibHVyIix0KSx0LnN0YXRlLmZvY3VzZWQ9ITEsdC5kaXNwbGF5LndyYXBwZXIuY2xhc3NOYW1lPXQuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZS5yZXBsYWNlKCIgQ29kZU1pcnJvci1mb2N1c2VkIiwiIikpLGNsZWFySW50ZXJ2YWwodC5kaXNwbGF5LmJsaW5rZXIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXt0LnN0YXRlLmZvY3VzZWR8fCh0LmRvYy5zZWwuc2hpZnQ9ITEpfSwxNTApfWZ1bmN0aW9uIEllKHQsZSl7ZnVuY3Rpb24gcigpe2lmKG51bGwhPWkuaW5wdXQuc2VsZWN0aW9uU3RhcnQpe3ZhciB0PWkuaW5wdXQudmFsdWU9IuKAiyIrKGplKG8uZnJvbSxvLnRvKT8iIjppLmlucHV0LnZhbHVlKTtpLnByZXZJbnB1dD0i4oCLIixpLmlucHV0LnNlbGVjdGlvblN0YXJ0PTEsaS5pbnB1dC5zZWxlY3Rpb25FbmQ9dC5sZW5ndGh9fWZ1bmN0aW9uIG4oKXtpZihpLmlucHV0RGl2LnN0eWxlLnBvc2l0aW9uPSJyZWxhdGl2ZSIsaS5pbnB1dC5zdHlsZS5jc3NUZXh0PXUsTmkmJihpLnNjcm9sbGJhclYuc2Nyb2xsVG9wPWkuc2Nyb2xsZXIuc2Nyb2xsVG9wPXMpLGNlKHQpLG51bGwhPWkuaW5wdXQuc2VsZWN0aW9uU3RhcnQpeyghQWl8fE5pKSYmcigpLGNsZWFyVGltZW91dChpbyk7dmFyIGU9MCxuPWZ1bmN0aW9uKCl7IiAiPT1pLnByZXZJbnB1dCYmMD09aS5pbnB1dC5zZWxlY3Rpb25TdGFydD9sZSh0LG1vLnNlbGVjdEFsbCkodCk6ZSsrPDEwP2lvPXNldFRpbWVvdXQobiw1MDApOmRlKHQpfTtpbz1zZXRUaW1lb3V0KG4sMjAwKX19aWYoIVhuKHQsZSwiY29udGV4dG1lbnUiKSl7dmFyIGk9dC5kaXNwbGF5LG89dC5kb2Muc2VsO2lmKCF2ZShpLGUpJiYhQ2UodCxlKSl7dmFyIGw9eWUodCxlKSxzPWkuc2Nyb2xsZXIuc2Nyb2xsVG9wO2lmKGwmJiF6aSl7dmFyIGE9dC5vcHRpb25zLnJlc2V0U2VsZWN0aW9uT25Db250ZXh0TWVudTthJiYoamUoby5mcm9tLG8udG8pfHwkZShsLG8uZnJvbSl8fCEkZShsLG8udG8pKSYmbGUodCxucikodC5kb2MsbCxsKTt2YXIgdT1pLmlucHV0LnN0eWxlLmNzc1RleHQ7aWYoaS5pbnB1dERpdi5zdHlsZS5wb3NpdGlvbj0iYWJzb2x1dGUiLGkuaW5wdXQuc3R5bGUuY3NzVGV4dD0icG9zaXRpb246IGZpeGVkOyB3aWR0aDogMzBweDsgaGVpZ2h0OiAzMHB4OyB0b3A6ICIrKGUuY2xpZW50WS01KSsicHg7IGxlZnQ6ICIrKGUuY2xpZW50WC01KSsicHg7IHotaW5kZXg6IDEwMDA7IGJhY2tncm91bmQ6IHdoaXRlOyBvdXRsaW5lOiBub25lOyIrImJvcmRlci13aWR0aDogMDsgb3V0bGluZTogbm9uZTsgb3ZlcmZsb3c6IGhpZGRlbjsgb3BhY2l0eTogLjA1OyAtbXMtb3BhY2l0eTogLjA1OyBmaWx0ZXI6IGFscGhhKG9wYWNpdHk9NSk7IixwZSh0KSxkZSh0LCEwKSxqZShvLmZyb20sby50bykmJihpLmlucHV0LnZhbHVlPWkucHJldklucHV0PSIgIiksQWkmJiFOaSYmcigpLFppKXtQbihlKTt2YXIgYz1mdW5jdGlvbigpe1ZuKHdpbmRvdywibW91c2V1cCIsYyksc2V0VGltZW91dChuLDIwKX07R24od2luZG93LCJtb3VzZXVwIixjKX1lbHNlIHNldFRpbWVvdXQobiw1MCl9fX19ZnVuY3Rpb24gRmUodCxlLHIpe2lmKCEkZShlLmZyb20scikpcmV0dXJuIFFlKHQscik7dmFyIG49ZS50ZXh0Lmxlbmd0aC0xLShlLnRvLmxpbmUtZS5mcm9tLmxpbmUpO2lmKHIubGluZT5lLnRvLmxpbmUrbil7dmFyIGk9ci5saW5lLW4sbz10LmZpcnN0K3Quc2l6ZS0xO3JldHVybiBpPm8/WWUobyxnbih0LG8pLnRleHQubGVuZ3RoKTpKZShyLGduKHQsaSkudGV4dC5sZW5ndGgpfWlmKHIubGluZT09ZS50by5saW5lK24pcmV0dXJuIEplKHIsUW4oZS50ZXh0KS5sZW5ndGgrKDE9PWUudGV4dC5sZW5ndGg/ZS5mcm9tLmNoOjApK2duKHQsZS50by5saW5lKS50ZXh0Lmxlbmd0aC1lLnRvLmNoKTt2YXIgbD1yLmxpbmUtZS5mcm9tLmxpbmU7cmV0dXJuIEplKHIsZS50ZXh0W2xdLmxlbmd0aCsobD8wOmUuZnJvbS5jaCkpfWZ1bmN0aW9uIFBlKHQsZSxyKXtpZihyJiYib2JqZWN0Ij09dHlwZW9mIHIpcmV0dXJue2FuY2hvcjpGZSh0LGUsci5hbmNob3IpLGhlYWQ6RmUodCxlLHIuaGVhZCl9O2lmKCJzdGFydCI9PXIpcmV0dXJue2FuY2hvcjplLmZyb20saGVhZDplLmZyb219O3ZhciBuPWxvKGUpO2lmKCJhcm91bmQiPT1yKXJldHVybnthbmNob3I6ZS5mcm9tLGhlYWQ6bn07aWYoImVuZCI9PXIpcmV0dXJue2FuY2hvcjpuLGhlYWQ6bn07dmFyIGk9ZnVuY3Rpb24odCl7aWYoJGUodCxlLmZyb20pKXJldHVybiB0O2lmKCEkZShlLnRvLHQpKXJldHVybiBuO3ZhciByPXQubGluZStlLnRleHQubGVuZ3RoLShlLnRvLmxpbmUtZS5mcm9tLmxpbmUpLTEsaT10LmNoO3JldHVybiB0LmxpbmU9PWUudG8ubGluZSYmKGkrPW4uY2gtZS50by5jaCksWWUocixpKX07cmV0dXJue2FuY2hvcjppKHQuc2VsLmFuY2hvciksaGVhZDppKHQuc2VsLmhlYWQpfX1mdW5jdGlvbiBSZSh0LGUscil7dmFyIG49e2NhbmNlbGVkOiExLGZyb206ZS5mcm9tLHRvOmUudG8sdGV4dDplLnRleHQsb3JpZ2luOmUub3JpZ2luLGNhbmNlbDpmdW5jdGlvbigpe3RoaXMuY2FuY2VsZWQ9ITB9fTtyZXR1cm4gciYmKG4udXBkYXRlPWZ1bmN0aW9uKGUscixuLGkpe2UmJih0aGlzLmZyb209UWUodCxlKSksciYmKHRoaXMudG89UWUodCxyKSksbiYmKHRoaXMudGV4dD1uKSx2b2lkIDAhPT1pJiYodGhpcy5vcmlnaW49aSl9KSxLbih0LCJiZWZvcmVDaGFuZ2UiLHQsbiksdC5jbSYmS24odC5jbSwiYmVmb3JlQ2hhbmdlIix0LmNtLG4pLG4uY2FuY2VsZWQ/bnVsbDp7ZnJvbTpuLmZyb20sdG86bi50byx0ZXh0Om4udGV4dCxvcmlnaW46bi5vcmlnaW59fWZ1bmN0aW9uIEJlKHQsZSxyLG4pe2lmKHQuY20pe2lmKCF0LmNtLmN1ck9wKXJldHVybiBsZSh0LmNtLEJlKSh0LGUscixuKTtpZih0LmNtLnN0YXRlLnN1cHByZXNzRWRpdHMpcmV0dXJufWlmKCEoWW4odCwiYmVmb3JlQ2hhbmdlIil8fHQuY20mJlluKHQuY20sImJlZm9yZUNoYW5nZSIpKXx8KGU9UmUodCxlLCEwKSkpe3ZhciBpPXFpJiYhbiYmRnIodCxlLmZyb20sZS50byk7aWYoaSl7Zm9yKHZhciBvPWkubGVuZ3RoLTE7bz49MTstLW8pR2UodCx7ZnJvbTppW29dLmZyb20sdG86aVtvXS50byx0ZXh0OlsiIl19KTtpLmxlbmd0aCYmR2UodCx7ZnJvbTppWzBdLmZyb20sdG86aVswXS50byx0ZXh0OmUudGV4dH0scil9ZWxzZSBHZSh0LGUscil9fWZ1bmN0aW9uIEdlKHQsZSxyKXtpZigxIT1lLnRleHQubGVuZ3RofHwiIiE9ZS50ZXh0WzBdfHwhamUoZS5mcm9tLGUudG8pKXt2YXIgbj1QZSh0LGUscik7TW4odCxlLG4sdC5jbT90LmNtLmN1ck9wLmlkOjAvMCksVWUodCxlLG4senIodCxlKSk7dmFyIGk9W107ZG4odCxmdW5jdGlvbih0LHIpe3J8fC0xIT10aShpLHQuaGlzdG9yeSl8fChXbih0Lmhpc3RvcnksZSksaS5wdXNoKHQuaGlzdG9yeSkpLFVlKHQsZSxudWxsLHpyKHQsZSkpfSl9fWZ1bmN0aW9uIFZlKHQsZSl7aWYoIXQuY218fCF0LmNtLnN0YXRlLnN1cHByZXNzRWRpdHMpe3ZhciByPXQuaGlzdG9yeSxuPSgidW5kbyI9PWU/ci5kb25lOnIudW5kb25lKS5wb3AoKTtpZihuKXt2YXIgaT17Y2hhbmdlczpbXSxhbmNob3JCZWZvcmU6bi5hbmNob3JBZnRlcixoZWFkQmVmb3JlOm4uaGVhZEFmdGVyLGFuY2hvckFmdGVyOm4uYW5jaG9yQmVmb3JlLGhlYWRBZnRlcjpuLmhlYWRCZWZvcmUsZ2VuZXJhdGlvbjpyLmdlbmVyYXRpb259OygidW5kbyI9PWU/ci51bmRvbmU6ci5kb25lKS5wdXNoKGkpLHIuZ2VuZXJhdGlvbj1uLmdlbmVyYXRpb258fCsrci5tYXhHZW5lcmF0aW9uO2Zvcih2YXIgbz1Zbih0LCJiZWZvcmVDaGFuZ2UiKXx8dC5jbSYmWW4odC5jbSwiYmVmb3JlQ2hhbmdlIiksbD1uLmNoYW5nZXMubGVuZ3RoLTE7bD49MDstLWwpe3ZhciBzPW4uY2hhbmdlc1tsXTtpZihzLm9yaWdpbj1lLG8mJiFSZSh0LHMsITEpKXJldHVybigidW5kbyI9PWU/ci5kb25lOnIudW5kb25lKS5sZW5ndGg9MCx2b2lkIDA7aS5jaGFuZ2VzLnB1c2goU24odCxzKSk7dmFyIGE9bD9QZSh0LHMsbnVsbCk6e2FuY2hvcjpuLmFuY2hvckJlZm9yZSxoZWFkOm4uaGVhZEJlZm9yZX07VWUodCxzLGEsSXIodCxzKSk7dmFyIHU9W107ZG4odCxmdW5jdGlvbih0LGUpe2V8fC0xIT10aSh1LHQuaGlzdG9yeSl8fChXbih0Lmhpc3RvcnkscyksdS5wdXNoKHQuaGlzdG9yeSkpLFVlKHQscyxudWxsLElyKHQscykpfSl9fX19ZnVuY3Rpb24gS2UodCxlKXtmdW5jdGlvbiByKHQpe3JldHVybiBZZSh0LmxpbmUrZSx0LmNoKX10LmZpcnN0Kz1lLHQuY20mJnVlKHQuY20sdC5maXJzdCx0LmZpcnN0LGUpLHQuc2VsLmhlYWQ9cih0LnNlbC5oZWFkKSx0LnNlbC5hbmNob3I9cih0LnNlbC5hbmNob3IpLHQuc2VsLmZyb209cih0LnNlbC5mcm9tKSx0LnNlbC50bz1yKHQuc2VsLnRvKX1mdW5jdGlvbiBVZSh0LGUscixuKXtpZih0LmNtJiYhdC5jbS5jdXJPcClyZXR1cm4gbGUodC5jbSxVZSkodCxlLHIsbik7aWYoZS50by5saW5lPHQuZmlyc3QpcmV0dXJuIEtlKHQsZS50ZXh0Lmxlbmd0aC0xLShlLnRvLmxpbmUtZS5mcm9tLmxpbmUpKSx2b2lkIDA7aWYoIShlLmZyb20ubGluZT50Lmxhc3RMaW5lKCkpKXtpZihlLmZyb20ubGluZTx0LmZpcnN0KXt2YXIgaT1lLnRleHQubGVuZ3RoLTEtKHQuZmlyc3QtZS5mcm9tLmxpbmUpO0tlKHQsaSksZT17ZnJvbTpZZSh0LmZpcnN0LDApLHRvOlllKGUudG8ubGluZStpLGUudG8uY2gpLHRleHQ6W1FuKGUudGV4dCldLG9yaWdpbjplLm9yaWdpbn19dmFyIG89dC5sYXN0TGluZSgpO2UudG8ubGluZT5vJiYoZT17ZnJvbTplLmZyb20sdG86WWUobyxnbih0LG8pLnRleHQubGVuZ3RoKSx0ZXh0OltlLnRleHRbMF1dLG9yaWdpbjplLm9yaWdpbn0pLGUucmVtb3ZlZD1tbih0LGUuZnJvbSxlLnRvKSxyfHwocj1QZSh0LGUsbnVsbCkpLHQuY20/WGUodC5jbSxlLG4scik6Y24odCxlLG4scil9fWZ1bmN0aW9uIFhlKHQsZSxyLG4pe3ZhciBvPXQuZG9jLGw9dC5kaXNwbGF5LHM9ZS5mcm9tLGE9ZS50byx1PSExLGY9cy5saW5lO3Qub3B0aW9ucy5saW5lV3JhcHBpbmd8fChmPWJuKEdyKG8sZ24obyxzLmxpbmUpKSksby5pdGVyKGYsYS5saW5lKzEsZnVuY3Rpb24odCl7cmV0dXJuIHQ9PWwubWF4TGluZT8odT0hMCwhMCk6dm9pZCAwfSkpLCRlKG8uc2VsLmhlYWQsZS5mcm9tKXx8JGUoZS50byxvLnNlbC5oZWFkKXx8KHQuY3VyT3AuY3Vyc29yQWN0aXZpdHk9ITApLGNuKG8sZSxyLG4saSh0KSksdC5vcHRpb25zLmxpbmVXcmFwcGluZ3x8KG8uaXRlcihmLHMubGluZStlLnRleHQubGVuZ3RoLGZ1bmN0aW9uKHQpe3ZhciBlPWMobyx0KTtlPmwubWF4TGluZUxlbmd0aCYmKGwubWF4TGluZT10LGwubWF4TGluZUxlbmd0aD1lLGwubWF4TGluZUNoYW5nZWQ9ITAsdT0hMSl9KSx1JiYodC5jdXJPcC51cGRhdGVNYXhMaW5lPSEwKSksby5mcm9udGllcj1NYXRoLm1pbihvLmZyb250aWVyLHMubGluZSksVyh0LDQwMCk7dmFyIGg9ZS50ZXh0Lmxlbmd0aC0oYS5saW5lLXMubGluZSktMTtpZih1ZSh0LHMubGluZSxhLmxpbmUrMSxoKSxZbih0LCJjaGFuZ2UiKSl7dmFyIGQ9e2Zyb206cyx0bzphLHRleHQ6ZS50ZXh0LHJlbW92ZWQ6ZS5yZW1vdmVkLG9yaWdpbjplLm9yaWdpbn07aWYodC5jdXJPcC50ZXh0Q2hhbmdlZCl7Zm9yKHZhciBwPXQuY3VyT3AudGV4dENoYW5nZWQ7cC5uZXh0O3A9cC5uZXh0KTtwLm5leHQ9ZH1lbHNlIHQuY3VyT3AudGV4dENoYW5nZWQ9ZH19ZnVuY3Rpb24gX2UodCxlLHIsbixpKXtpZihufHwobj1yKSwkZShuLHIpKXt2YXIgbz1uO249cixyPW99InN0cmluZyI9PXR5cGVvZiBlJiYoZT16byhlKSksQmUodCx7ZnJvbTpyLHRvOm4sdGV4dDplLG9yaWdpbjppfSxudWxsKX1mdW5jdGlvbiBZZSh0LGUpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgWWU/KHRoaXMubGluZT10LHRoaXMuY2g9ZSx2b2lkIDApOm5ldyBZZSh0LGUpfWZ1bmN0aW9uIGplKHQsZSl7cmV0dXJuIHQubGluZT09ZS5saW5lJiZ0LmNoPT1lLmNofWZ1bmN0aW9uICRlKHQsZSl7cmV0dXJuIHQubGluZTxlLmxpbmV8fHQubGluZT09ZS5saW5lJiZ0LmNoPGUuY2h9ZnVuY3Rpb24gWmUodCl7cmV0dXJuIFllKHQubGluZSx0LmNoKX1mdW5jdGlvbiBxZSh0LGUpe3JldHVybiBNYXRoLm1heCh0LmZpcnN0LE1hdGgubWluKGUsdC5maXJzdCt0LnNpemUtMSkpfWZ1bmN0aW9uIFFlKHQsZSl7aWYoZS5saW5lPHQuZmlyc3QpcmV0dXJuIFllKHQuZmlyc3QsMCk7dmFyIHI9dC5maXJzdCt0LnNpemUtMTtyZXR1cm4gZS5saW5lPnI/WWUocixnbih0LHIpLnRleHQubGVuZ3RoKTpKZShlLGduKHQsZS5saW5lKS50ZXh0Lmxlbmd0aCl9ZnVuY3Rpb24gSmUodCxlKXt2YXIgcj10LmNoO3JldHVybiBudWxsPT1yfHxyPmU/WWUodC5saW5lLGUpOjA+cj9ZZSh0LmxpbmUsMCk6dH1mdW5jdGlvbiB0cih0LGUpe3JldHVybiBlPj10LmZpcnN0JiZlPHQuZmlyc3QrdC5zaXplfWZ1bmN0aW9uIGVyKHQsZSxyLG4pe2lmKHQuc2VsLnNoaWZ0fHx0LnNlbC5leHRlbmQpe3ZhciBpPXQuc2VsLmFuY2hvcjtpZihyKXt2YXIgbz0kZShlLGkpO28hPSRlKHIsaSk/KGk9ZSxlPXIpOm8hPSRlKGUscikmJihlPXIpfW5yKHQsaSxlLG4pfWVsc2UgbnIodCxlLHJ8fGUsbik7dC5jbSYmKHQuY20uY3VyT3AudXNlclNlbENoYW5nZT0hMCl9ZnVuY3Rpb24gcnIodCxlLHIpe3ZhciBuPXthbmNob3I6ZSxoZWFkOnJ9O3JldHVybiBLbih0LCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2UiLHQsbiksdC5jbSYmS24odC5jbSwiYmVmb3JlU2VsZWN0aW9uQ2hhbmdlIix0LmNtLG4pLG4uYW5jaG9yPVFlKHQsbi5hbmNob3IpLG4uaGVhZD1RZSh0LG4uaGVhZCksbn1mdW5jdGlvbiBucih0LGUscixuLGkpe2lmKCFpJiZZbih0LCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2UiKXx8dC5jbSYmWW4odC5jbSwiYmVmb3JlU2VsZWN0aW9uQ2hhbmdlIikpe3ZhciBvPXJyKHQsZSxyKTtyPW8uaGVhZCxlPW8uYW5jaG9yfXZhciBsPXQuc2VsO2lmKGwuZ29hbENvbHVtbj1udWxsLG51bGw9PW4mJihuPSRlKHIsbC5oZWFkKT8tMToxKSwoaXx8IWplKGUsbC5hbmNob3IpKSYmKGU9b3IodCxlLG4sInB1c2giIT1pKSksKGl8fCFqZShyLGwuaGVhZCkpJiYocj1vcih0LHIsbiwicHVzaCIhPWkpKSwhamUobC5hbmNob3IsZSl8fCFqZShsLmhlYWQscikpe2wuYW5jaG9yPWUsbC5oZWFkPXI7dmFyIHM9JGUocixlKTtsLmZyb209cz9yOmUsbC50bz1zP2U6cix0LmNtJiYodC5jbS5jdXJPcC51cGRhdGVJbnB1dD10LmNtLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQ9dC5jbS5jdXJPcC5jdXJzb3JBY3Rpdml0eT0hMCksVW4odCwiY3Vyc29yQWN0aXZpdHkiLHQpfX1mdW5jdGlvbiBpcih0KXtucih0LmRvYyx0LmRvYy5zZWwuZnJvbSx0LmRvYy5zZWwudG8sbnVsbCwicHVzaCIpfWZ1bmN0aW9uIG9yKHQsZSxyLG4pe3ZhciBpPSExLG89ZSxsPXJ8fDE7dC5jYW50RWRpdD0hMTt0OmZvcig7Oyl7dmFyIHM9Z24odCxvLmxpbmUpO2lmKHMubWFya2VkU3BhbnMpZm9yKHZhciBhPTA7YTxzLm1hcmtlZFNwYW5zLmxlbmd0aDsrK2Epe3ZhciB1PXMubWFya2VkU3BhbnNbYV0sYz11Lm1hcmtlcjtpZigobnVsbD09dS5mcm9tfHwoYy5pbmNsdXNpdmVMZWZ0P3UuZnJvbTw9by5jaDp1LmZyb208by5jaCkpJiYobnVsbD09dS50b3x8KGMuaW5jbHVzaXZlUmlnaHQ/dS50bz49by5jaDp1LnRvPm8uY2gpKSl7aWYobiYmKEtuKGMsImJlZm9yZUN1cnNvckVudGVyIiksYy5leHBsaWNpdGx5Q2xlYXJlZCkpe2lmKHMubWFya2VkU3BhbnMpey0tYTtjb250aW51ZX1icmVha31pZighYy5hdG9taWMpY29udGludWU7dmFyIGY9Yy5maW5kKClbMD5sPyJmcm9tIjoidG8iXTtpZihqZShmLG8pJiYoZi5jaCs9bCxmLmNoPDA/Zj1mLmxpbmU+dC5maXJzdD9RZSh0LFllKGYubGluZS0xKSk6bnVsbDpmLmNoPnMudGV4dC5sZW5ndGgmJihmPWYubGluZTx0LmZpcnN0K3Quc2l6ZS0xP1llKGYubGluZSsxLDApOm51bGwpLCFmKSl7aWYoaSlyZXR1cm4gbj8odC5jYW50RWRpdD0hMCxZZSh0LmZpcnN0LDApKTpvcih0LGUsciwhMCk7aT0hMCxmPWUsbD0tbH1vPWY7Y29udGludWUgdH19cmV0dXJuIG99fWZ1bmN0aW9uIGxyKHQpe3ZhciBlPXNyKHQsdC5kb2Muc2VsLmhlYWQsbnVsbCx0Lm9wdGlvbnMuY3Vyc29yU2Nyb2xsTWFyZ2luKTtpZih0LnN0YXRlLmZvY3VzZWQpe3ZhciByPXQuZGlzcGxheSxuPWZpKHIuc2l6ZXIpLGk9bnVsbDtpZihlLnRvcCtuLnRvcDwwP2k9ITA6ZS5ib3R0b20rbi50b3A+KHdpbmRvdy5pbm5lckhlaWdodHx8ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkmJihpPSExKSxudWxsIT1pJiYhQmkpe3ZhciBvPSJub25lIj09ci5jdXJzb3Iuc3R5bGUuZGlzcGxheTtvJiYoci5jdXJzb3Iuc3R5bGUuZGlzcGxheT0iIixyLmN1cnNvci5zdHlsZS5sZWZ0PWUubGVmdCsicHgiLHIuY3Vyc29yLnN0eWxlLnRvcD1lLnRvcC1yLnZpZXdPZmZzZXQrInB4Iiksci5jdXJzb3Iuc2Nyb2xsSW50b1ZpZXcoaSksbyYmKHIuY3Vyc29yLnN0eWxlLmRpc3BsYXk9Im5vbmUiKX19fWZ1bmN0aW9uIHNyKHQsZSxyLG4pe2ZvcihudWxsPT1uJiYobj0wKTs7KXt2YXIgaT0hMSxvPVEodCxlKSxsPXImJnIhPWU/USh0LHIpOm8scz11cih0LE1hdGgubWluKG8ubGVmdCxsLmxlZnQpLE1hdGgubWluKG8udG9wLGwudG9wKS1uLE1hdGgubWF4KG8ubGVmdCxsLmxlZnQpLE1hdGgubWF4KG8uYm90dG9tLGwuYm90dG9tKStuKSxhPXQuZG9jLnNjcm9sbFRvcCx1PXQuZG9jLnNjcm9sbExlZnQ7aWYobnVsbCE9cy5zY3JvbGxUb3AmJihTZSh0LHMuc2Nyb2xsVG9wKSxNYXRoLmFicyh0LmRvYy5zY3JvbGxUb3AtYSk+MSYmKGk9ITApKSxudWxsIT1zLnNjcm9sbExlZnQmJihNZSh0LHMuc2Nyb2xsTGVmdCksTWF0aC5hYnModC5kb2Muc2Nyb2xsTGVmdC11KT4xJiYoaT0hMCkpLCFpKXJldHVybiBvfX1mdW5jdGlvbiBhcih0LGUscixuLGkpe3ZhciBvPXVyKHQsZSxyLG4saSk7bnVsbCE9by5zY3JvbGxUb3AmJlNlKHQsby5zY3JvbGxUb3ApLG51bGwhPW8uc2Nyb2xsTGVmdCYmTWUodCxvLnNjcm9sbExlZnQpfWZ1bmN0aW9uIHVyKHQsZSxyLG4saSl7dmFyIG89dC5kaXNwbGF5LGw9cmUodC5kaXNwbGF5KTswPnImJihyPTApO3ZhciBzPW8uc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LVRvLGE9by5zY3JvbGxlci5zY3JvbGxUb3AsdT17fSxjPXQuZG9jLmhlaWdodCtGKG8pLGY9bD5yLGg9aT5jLWw7aWYoYT5yKXUuc2Nyb2xsVG9wPWY/MDpyO2Vsc2UgaWYoaT5hK3Mpe3ZhciBkPU1hdGgubWluKHIsKGg/YzppKS1zKTtkIT1hJiYodS5zY3JvbGxUb3A9ZCl9dmFyIHA9by5zY3JvbGxlci5jbGllbnRXaWR0aC1UbyxnPW8uc2Nyb2xsZXIuc2Nyb2xsTGVmdDtlKz1vLmd1dHRlcnMub2Zmc2V0V2lkdGgsbis9by5ndXR0ZXJzLm9mZnNldFdpZHRoO3ZhciBtPW8uZ3V0dGVycy5vZmZzZXRXaWR0aCx2PW0rMTA+ZTtyZXR1cm4gZyttPmV8fHY/KHYmJihlPTApLHUuc2Nyb2xsTGVmdD1NYXRoLm1heCgwLGUtMTAtbSkpOm4+cCtnLTMmJih1LnNjcm9sbExlZnQ9bisxMC1wKSx1fWZ1bmN0aW9uIGNyKHQsZSxyKXt0LmN1ck9wLnVwZGF0ZVNjcm9sbFBvcz17c2Nyb2xsTGVmdDpudWxsPT1lP3QuZG9jLnNjcm9sbExlZnQ6ZSxzY3JvbGxUb3A6bnVsbD09cj90LmRvYy5zY3JvbGxUb3A6cn19ZnVuY3Rpb24gZnIodCxlLHIpe3ZhciBuPXQuY3VyT3AudXBkYXRlU2Nyb2xsUG9zfHwodC5jdXJPcC51cGRhdGVTY3JvbGxQb3M9e3Njcm9sbExlZnQ6dC5kb2Muc2Nyb2xsTGVmdCxzY3JvbGxUb3A6dC5kb2Muc2Nyb2xsVG9wfSksaT10LmRpc3BsYXkuc2Nyb2xsZXI7bi5zY3JvbGxUb3A9TWF0aC5tYXgoMCxNYXRoLm1pbihpLnNjcm9sbEhlaWdodC1pLmNsaWVudEhlaWdodCxuLnNjcm9sbFRvcCtyKSksbi5zY3JvbGxMZWZ0PU1hdGgubWF4KDAsTWF0aC5taW4oaS5zY3JvbGxXaWR0aC1pLmNsaWVudFdpZHRoLG4uc2Nyb2xsTGVmdCtlKSl9ZnVuY3Rpb24gaHIodCxlLHIsbil7dmFyIGk9dC5kb2M7aWYobnVsbD09ciYmKHI9ImFkZCIpLCJzbWFydCI9PXIpaWYodC5kb2MubW9kZS5pbmRlbnQpdmFyIG89eih0LGUpO2Vsc2Ugcj0icHJldiI7dmFyIGwscz10Lm9wdGlvbnMudGFiU2l6ZSxhPWduKGksZSksdT1abihhLnRleHQsbnVsbCxzKSxjPWEudGV4dC5tYXRjaCgvXlxzKi8pWzBdO2lmKCJzbWFydCI9PXImJihsPXQuZG9jLm1vZGUuaW5kZW50KG8sYS50ZXh0LnNsaWNlKGMubGVuZ3RoKSxhLnRleHQpLGw9PUFvKSl7aWYoIW4pcmV0dXJuO3I9InByZXYifSJwcmV2Ij09cj9sPWU+aS5maXJzdD9abihnbihpLGUtMSkudGV4dCxudWxsLHMpOjA6ImFkZCI9PXI/bD11K3Qub3B0aW9ucy5pbmRlbnRVbml0OiJzdWJ0cmFjdCI9PXI/bD11LXQub3B0aW9ucy5pbmRlbnRVbml0OiJudW1iZXIiPT10eXBlb2YgciYmKGw9dStyKSxsPU1hdGgubWF4KDAsbCk7dmFyIGY9IiIsaD0wO2lmKHQub3B0aW9ucy5pbmRlbnRXaXRoVGFicylmb3IodmFyIGQ9TWF0aC5mbG9vcihsL3MpO2Q7LS1kKWgrPXMsZis9IgkiO2w+aCYmKGYrPXFuKGwtaCkpLGYhPWM/X2UodC5kb2MsZixZZShlLDApLFllKGUsYy5sZW5ndGgpLCIraW5wdXQiKTppLnNlbC5oZWFkLmxpbmU9PWUmJmkuc2VsLmhlYWQuY2g8Yy5sZW5ndGgmJm5yKGksWWUoZSxjLmxlbmd0aCksWWUoZSxjLmxlbmd0aCksMSksYS5zdGF0ZUFmdGVyPW51bGx9ZnVuY3Rpb24gZHIodCxlLHIpe3ZhciBuPWUsaT1lLG89dC5kb2M7cmV0dXJuIm51bWJlciI9PXR5cGVvZiBlP2k9Z24obyxxZShvLGUpKTpuPWJuKGUpLG51bGw9PW4/bnVsbDpyKGksbik/KHVlKHQsbixuKzEpLGkpOm51bGx9ZnVuY3Rpb24gcHIodCxlLHIsbixpKXtmdW5jdGlvbiBvKCl7dmFyIGU9cytyO3JldHVybiBlPHQuZmlyc3R8fGU+PXQuZmlyc3QrdC5zaXplP2Y9ITE6KHM9ZSxjPWduKHQsZSkpfWZ1bmN0aW9uIGwodCl7dmFyIGU9KGk/U2k6TWkpKGMsYSxyLCEwKTtpZihudWxsPT1lKXtpZih0fHwhbygpKXJldHVybiBmPSExO2E9aT8oMD5yP2JpOnlpKShjKTowPnI/Yy50ZXh0Lmxlbmd0aDowfWVsc2UgYT1lO3JldHVybiEwfXZhciBzPWUubGluZSxhPWUuY2gsdT1yLGM9Z24odCxzKSxmPSEwO2lmKCJjaGFyIj09bilsKCk7ZWxzZSBpZigiY29sdW1uIj09bilsKCEwKTtlbHNlIGlmKCJ3b3JkIj09bnx8Imdyb3VwIj09bilmb3IodmFyIGg9bnVsbCxkPSJncm91cCI9PW4scD0hMDshKDA+cil8fGwoIXApO3A9ITEpe3ZhciBnPWMudGV4dC5jaGFyQXQoYSl8fCJcbiIsbT1vaShnKT8idyI6ZD8vXHMvLnRlc3QoZyk/bnVsbDoicCI6bnVsbDtpZihoJiZoIT1tKXswPnImJihyPTEsbCgpKTticmVha31pZihtJiYoaD1tKSxyPjAmJiFsKCFwKSlicmVha312YXIgdj1vcih0LFllKHMsYSksdSwhMCk7cmV0dXJuIGZ8fCh2LmhpdFNpZGU9ITApLHZ9ZnVuY3Rpb24gZ3IodCxlLHIsbil7dmFyIGksbz10LmRvYyxsPWUubGVmdDtpZigicGFnZSI9PW4pe3ZhciBzPU1hdGgubWluKHQuZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodCx3aW5kb3cuaW5uZXJIZWlnaHR8fGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpO2k9ZS50b3Arcioocy0oMD5yPzEuNTouNSkqcmUodC5kaXNwbGF5KSl9ZWxzZSJsaW5lIj09biYmKGk9cj4wP2UuYm90dG9tKzM6ZS50b3AtMyk7Zm9yKDs7KXt2YXIgYT10ZSh0LGwsaSk7aWYoIWEub3V0c2lkZSlicmVhaztpZigwPnI/MD49aTppPj1vLmhlaWdodCl7YS5oaXRTaWRlPSEwO2JyZWFrfWkrPTUqcn1yZXR1cm4gYX1mdW5jdGlvbiBtcih0LGUpe3ZhciByPWUuY2gsbj1lLmNoO2lmKHQpeyhlLnhSZWw8MHx8bj09dC5sZW5ndGgpJiZyPy0tcjorK247Zm9yKHZhciBpPXQuY2hhckF0KHIpLG89b2koaSk/b2k6L1xzLy50ZXN0KGkpP2Z1bmN0aW9uKHQpe3JldHVybi9ccy8udGVzdCh0KX06ZnVuY3Rpb24odCl7cmV0dXJuIS9ccy8udGVzdCh0KSYmIW9pKHQpfTtyPjAmJm8odC5jaGFyQXQoci0xKSk7KS0tcjtmb3IoO248dC5sZW5ndGgmJm8odC5jaGFyQXQobikpOykrK259cmV0dXJue2Zyb206WWUoZS5saW5lLHIpLHRvOlllKGUubGluZSxuKX19ZnVuY3Rpb24gdnIodCxlKXtlcih0LmRvYyxZZShlLDApLFFlKHQuZG9jLFllKGUrMSwwKSkpfWZ1bmN0aW9uIHlyKGUscixuLGkpe3QuZGVmYXVsdHNbZV09cixuJiYoc29bZV09aT9mdW5jdGlvbih0LGUscil7ciE9dW8mJm4odCxlLHIpfTpuKX1mdW5jdGlvbiBicih0LGUpe2lmKGU9PT0hMClyZXR1cm4gZTtpZih0LmNvcHlTdGF0ZSlyZXR1cm4gdC5jb3B5U3RhdGUoZSk7dmFyIHI9e307Zm9yKHZhciBuIGluIGUpe3ZhciBpPWVbbl07aSBpbnN0YW5jZW9mIEFycmF5JiYoaT1pLmNvbmNhdChbXSkpLHJbbl09aX1yZXR1cm4gcn1mdW5jdGlvbiB4cih0LGUscil7cmV0dXJuIHQuc3RhcnRTdGF0ZT90LnN0YXJ0U3RhdGUoZSxyKTohMH1mdW5jdGlvbiBDcih0KXtyZXR1cm4ic3RyaW5nIj09dHlwZW9mIHQ/dm9bdF06dH1mdW5jdGlvbiB3cih0LGUscil7ZnVuY3Rpb24gbihlKXtlPUNyKGUpO3ZhciBpPWVbdF07aWYoaT09PSExKXJldHVybiJzdG9wIjtpZihudWxsIT1pJiZyKGkpKXJldHVybiEwO2lmKGUubm9mYWxsdGhyb3VnaClyZXR1cm4ic3RvcCI7dmFyIG89ZS5mYWxsdGhyb3VnaDtpZihudWxsPT1vKXJldHVybiExO2lmKCJbb2JqZWN0IEFycmF5XSIhPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKSlyZXR1cm4gbihvKTtmb3IodmFyIGw9MCxzPW8ubGVuZ3RoO3M+bDsrK2wpe3ZhciBhPW4ob1tsXSk7aWYoYSlyZXR1cm4gYX1yZXR1cm4hMX1mb3IodmFyIGk9MDtpPGUubGVuZ3RoOysraSl7dmFyIG89bihlW2ldKTtpZihvKXJldHVybiJzdG9wIiE9b319ZnVuY3Rpb24gTHIodCl7dmFyIGU9UG9bdC5rZXlDb2RlXTtyZXR1cm4iQ3RybCI9PWV8fCJBbHQiPT1lfHwiU2hpZnQiPT1lfHwiTW9kIj09ZX1mdW5jdGlvbiBrcih0LGUpe2lmKHppJiYzND09dC5rZXlDb2RlJiZ0WyJjaGFyIl0pcmV0dXJuITE7dmFyIHI9UG9bdC5rZXlDb2RlXTtyZXR1cm4gbnVsbD09cnx8dC5hbHRHcmFwaEtleT8hMToodC5hbHRLZXkmJihyPSJBbHQtIityKSwoJGk/dC5tZXRhS2V5OnQuY3RybEtleSkmJihyPSJDdHJsLSIrciksKCRpP3QuY3RybEtleTp0Lm1ldGFLZXkpJiYocj0iQ21kLSIrciksIWUmJnQuc2hpZnRLZXkmJihyPSJTaGlmdC0iK3IpLHIpfWZ1bmN0aW9uIFNyKHQsZSl7dGhpcy5wb3M9dGhpcy5zdGFydD0wLHRoaXMuc3RyaW5nPXQsdGhpcy50YWJTaXplPWV8fDgsdGhpcy5sYXN0Q29sdW1uUG9zPXRoaXMubGFzdENvbHVtblZhbHVlPTB9ZnVuY3Rpb24gTXIodCxlKXt0aGlzLmxpbmVzPVtdLHRoaXMudHlwZT1lLHRoaXMuZG9jPXR9ZnVuY3Rpb24gVHIodCxlLHIsbixpKXtpZihuJiZuLnNoYXJlZClyZXR1cm4gSHIodCxlLHIsbixpKTtpZih0LmNtJiYhdC5jbS5jdXJPcClyZXR1cm4gbGUodC5jbSxUcikodCxlLHIsbixpKTt2YXIgbz1uZXcgTXIodCxpKTtpZigkZShyLGUpfHxqZShlLHIpJiYicmFuZ2UiPT1pJiYoIW4uaW5jbHVzaXZlTGVmdHx8IW4uaW5jbHVzaXZlUmlnaHQpKXJldHVybiBvO24mJnJpKG4sbyksby5yZXBsYWNlZFdpdGgmJihvLmNvbGxhcHNlZD0hMCxvLnJlcGxhY2VkV2l0aD1zaSgic3BhbiIsW28ucmVwbGFjZWRXaXRoXSwiQ29kZU1pcnJvci13aWRnZXQiKSxuLmhhbmRsZU1vdXNlRXZlbnRzfHwoby5yZXBsYWNlZFdpdGguaWdub3JlRXZlbnRzPSEwKSksby5jb2xsYXBzZWQmJihRaT0hMCksby5hZGRUb0hpc3RvcnkmJk1uKHQse2Zyb206ZSx0bzpyLG9yaWdpbjoibWFya1RleHQifSx7aGVhZDp0LnNlbC5oZWFkLGFuY2hvcjp0LnNlbC5hbmNob3J9LDAvMCk7dmFyIGwscyxhLHU9ZS5saW5lLGM9MCxmPXQuY207aWYodC5pdGVyKHUsci5saW5lKzEsZnVuY3Rpb24obil7ZiYmby5jb2xsYXBzZWQmJiFmLm9wdGlvbnMubGluZVdyYXBwaW5nJiZHcih0LG4pPT1mLmRpc3BsYXkubWF4TGluZSYmKGE9ITApO3ZhciBpPXtmcm9tOm51bGwsdG86bnVsbCxtYXJrZXI6b307Yys9bi50ZXh0Lmxlbmd0aCx1PT1lLmxpbmUmJihpLmZyb209ZS5jaCxjLT1lLmNoKSx1PT1yLmxpbmUmJihpLnRvPXIuY2gsYy09bi50ZXh0Lmxlbmd0aC1yLmNoKSxvLmNvbGxhcHNlZCYmKHU9PXIubGluZSYmKHM9UHIobixyLmNoKSksdT09ZS5saW5lP2w9UHIobixlLmNoKTp5bihuLDApKSxXcihuLGkpLCsrdX0pLG8uY29sbGFwc2VkJiZ0Lml0ZXIoZS5saW5lLHIubGluZSsxLGZ1bmN0aW9uKGUpe1ZyKHQsZSkmJnluKGUsMCl9KSxvLmNsZWFyT25FbnRlciYmR24obywiYmVmb3JlQ3Vyc29yRW50ZXIiLGZ1bmN0aW9uKCl7by5jbGVhcigpfSksby5yZWFkT25seSYmKHFpPSEwLCh0Lmhpc3RvcnkuZG9uZS5sZW5ndGh8fHQuaGlzdG9yeS51bmRvbmUubGVuZ3RoKSYmdC5jbGVhckhpc3RvcnkoKSksby5jb2xsYXBzZWQpe2lmKGwhPXMpdGhyb3cgbmV3IEVycm9yKCJJbnNlcnRpbmcgY29sbGFwc2VkIG1hcmtlciBvdmVybGFwcGluZyBhbiBleGlzdGluZyBvbmUiKTtvLnNpemU9YyxvLmF0b21pYz0hMH1yZXR1cm4gZiYmKGEmJihmLmN1ck9wLnVwZGF0ZU1heExpbmU9ITApLChvLmNsYXNzTmFtZXx8by50aXRsZXx8by5zdGFydFN0eWxlfHxvLmVuZFN0eWxlfHxvLmNvbGxhcHNlZCkmJnVlKGYsZS5saW5lLHIubGluZSsxKSxvLmF0b21pYyYmaXIoZikpLG99ZnVuY3Rpb24gQXIodCxlKXt0aGlzLm1hcmtlcnM9dCx0aGlzLnByaW1hcnk9ZTtmb3IodmFyIHI9MCxuPXRoaXM7cjx0Lmxlbmd0aDsrK3IpdFtyXS5wYXJlbnQ9dGhpcyxHbih0W3JdLCJjbGVhciIsZnVuY3Rpb24oKXtuLmNsZWFyKCl9KX1mdW5jdGlvbiBIcih0LGUscixuLGkpe249cmkobiksbi5zaGFyZWQ9ITE7dmFyIG89W1RyKHQsZSxyLG4saSldLGw9b1swXSxzPW4ucmVwbGFjZWRXaXRoO3JldHVybiBkbih0LGZ1bmN0aW9uKHQpe3MmJihuLnJlcGxhY2VkV2l0aD1zLmNsb25lTm9kZSghMCkpLG8ucHVzaChUcih0LFFlKHQsZSksUWUodCxyKSxuLGkpKTtmb3IodmFyIGE9MDthPHQubGlua2VkLmxlbmd0aDsrK2EpaWYodC5saW5rZWRbYV0uaXNQYXJlbnQpcmV0dXJuO2w9UW4obyl9KSxuZXcgQXIobyxsKX1mdW5jdGlvbiBOcih0LGUpe2lmKHQpZm9yKHZhciByPTA7cjx0Lmxlbmd0aDsrK3Ipe3ZhciBuPXRbcl07aWYobi5tYXJrZXI9PWUpcmV0dXJuIG59fWZ1bmN0aW9uIERyKHQsZSl7Zm9yKHZhciByLG49MDtuPHQubGVuZ3RoOysrbil0W25dIT1lJiYocnx8KHI9W10pKS5wdXNoKHRbbl0pO3JldHVybiByfWZ1bmN0aW9uIFdyKHQsZSl7dC5tYXJrZWRTcGFucz10Lm1hcmtlZFNwYW5zP3QubWFya2VkU3BhbnMuY29uY2F0KFtlXSk6W2VdLGUubWFya2VyLmF0dGFjaExpbmUodCl9ZnVuY3Rpb24gT3IodCxlLHIpe2lmKHQpZm9yKHZhciBuLGk9MDtpPHQubGVuZ3RoOysraSl7dmFyIG89dFtpXSxsPW8ubWFya2VyLHM9bnVsbD09by5mcm9tfHwobC5pbmNsdXNpdmVMZWZ0P28uZnJvbTw9ZTpvLmZyb208ZSk7aWYoc3x8KGwuaW5jbHVzaXZlTGVmdCYmbC5pbmNsdXNpdmVSaWdodHx8ImJvb2ttYXJrIj09bC50eXBlKSYmby5mcm9tPT1lJiYoIXJ8fCFvLm1hcmtlci5pbnNlcnRMZWZ0KSl7dmFyIGE9bnVsbD09by50b3x8KGwuaW5jbHVzaXZlUmlnaHQ/by50bz49ZTpvLnRvPmUpOyhufHwobj1bXSkpLnB1c2goe2Zyb206by5mcm9tLHRvOmE/bnVsbDpvLnRvLG1hcmtlcjpsfSl9fXJldHVybiBufWZ1bmN0aW9uIEVyKHQsZSxyKXtpZih0KWZvcih2YXIgbixpPTA7aTx0Lmxlbmd0aDsrK2kpe3ZhciBvPXRbaV0sbD1vLm1hcmtlcixzPW51bGw9PW8udG98fChsLmluY2x1c2l2ZVJpZ2h0P28udG8+PWU6by50bz5lKTtpZihzfHwiYm9va21hcmsiPT1sLnR5cGUmJm8uZnJvbT09ZSYmKCFyfHxvLm1hcmtlci5pbnNlcnRMZWZ0KSl7dmFyIGE9bnVsbD09by5mcm9tfHwobC5pbmNsdXNpdmVMZWZ0P28uZnJvbTw9ZTpvLmZyb208ZSk7KG58fChuPVtdKSkucHVzaCh7ZnJvbTphP251bGw6by5mcm9tLWUsdG86bnVsbD09by50bz9udWxsOm8udG8tZSxtYXJrZXI6bH0pfX1yZXR1cm4gbn1mdW5jdGlvbiB6cih0LGUpe3ZhciByPXRyKHQsZS5mcm9tLmxpbmUpJiZnbih0LGUuZnJvbS5saW5lKS5tYXJrZWRTcGFucyxuPXRyKHQsZS50by5saW5lKSYmZ24odCxlLnRvLmxpbmUpLm1hcmtlZFNwYW5zO2lmKCFyJiYhbilyZXR1cm4gbnVsbDt2YXIgaT1lLmZyb20uY2gsbz1lLnRvLmNoLGw9amUoZS5mcm9tLGUudG8pLHM9T3IocixpLGwpLGE9RXIobixvLGwpLHU9MT09ZS50ZXh0Lmxlbmd0aCxjPVFuKGUudGV4dCkubGVuZ3RoKyh1P2k6MCk7aWYocylmb3IodmFyIGY9MDtmPHMubGVuZ3RoOysrZil7dmFyIGg9c1tmXTtpZihudWxsPT1oLnRvKXt2YXIgZD1OcihhLGgubWFya2VyKTtkP3UmJihoLnRvPW51bGw9PWQudG8/bnVsbDpkLnRvK2MpOmgudG89aX19aWYoYSlmb3IodmFyIGY9MDtmPGEubGVuZ3RoOysrZil7dmFyIGg9YVtmXTtpZihudWxsIT1oLnRvJiYoaC50bys9YyksbnVsbD09aC5mcm9tKXt2YXIgZD1OcihzLGgubWFya2VyKTtkfHwoaC5mcm9tPWMsdSYmKHN8fChzPVtdKSkucHVzaChoKSl9ZWxzZSBoLmZyb20rPWMsdSYmKHN8fChzPVtdKSkucHVzaChoKX1pZih1JiZzKXtmb3IodmFyIGY9MDtmPHMubGVuZ3RoOysrZiludWxsIT1zW2ZdLmZyb20mJnNbZl0uZnJvbT09c1tmXS50byYmImJvb2ttYXJrIiE9c1tmXS5tYXJrZXIudHlwZSYmcy5zcGxpY2UoZi0tLDEpO3MubGVuZ3RofHwocz1udWxsKX12YXIgcD1bc107aWYoIXUpe3ZhciBnLG09ZS50ZXh0Lmxlbmd0aC0yO2lmKG0+MCYmcylmb3IodmFyIGY9MDtmPHMubGVuZ3RoOysrZiludWxsPT1zW2ZdLnRvJiYoZ3x8KGc9W10pKS5wdXNoKHtmcm9tOm51bGwsdG86bnVsbCxtYXJrZXI6c1tmXS5tYXJrZXJ9KTtmb3IodmFyIGY9MDttPmY7KytmKXAucHVzaChnKTtwLnB1c2goYSl9cmV0dXJuIHB9ZnVuY3Rpb24gSXIodCxlKXt2YXIgcj1Bbih0LGUpLG49enIodCxlKTtpZighcilyZXR1cm4gbjtpZighbilyZXR1cm4gcjtmb3IodmFyIGk9MDtpPHIubGVuZ3RoOysraSl7dmFyIG89cltpXSxsPW5baV07aWYobyYmbCl0OmZvcih2YXIgcz0wO3M8bC5sZW5ndGg7KytzKXtmb3IodmFyIGE9bFtzXSx1PTA7dTxvLmxlbmd0aDsrK3UpaWYob1t1XS5tYXJrZXI9PWEubWFya2VyKWNvbnRpbnVlIHQ7by5wdXNoKGEpfWVsc2UgbCYmKHJbaV09bCl9cmV0dXJuIHJ9ZnVuY3Rpb24gRnIodCxlLHIpe3ZhciBuPW51bGw7aWYodC5pdGVyKGUubGluZSxyLmxpbmUrMSxmdW5jdGlvbih0KXtpZih0Lm1hcmtlZFNwYW5zKWZvcih2YXIgZT0wO2U8dC5tYXJrZWRTcGFucy5sZW5ndGg7KytlKXt2YXIgcj10Lm1hcmtlZFNwYW5zW2VdLm1hcmtlcjshci5yZWFkT25seXx8biYmLTEhPXRpKG4scil8fChufHwobj1bXSkpLnB1c2gocil9fSksIW4pcmV0dXJuIG51bGw7Zm9yKHZhciBpPVt7ZnJvbTplLHRvOnJ9XSxvPTA7bzxuLmxlbmd0aDsrK28pZm9yKHZhciBsPW5bb10scz1sLmZpbmQoKSxhPTA7YTxpLmxlbmd0aDsrK2Epe3ZhciB1PWlbYV07aWYoISRlKHUudG8scy5mcm9tKSYmISRlKHMudG8sdS5mcm9tKSl7dmFyIGM9W2EsMV07KCRlKHUuZnJvbSxzLmZyb20pfHwhbC5pbmNsdXNpdmVMZWZ0JiZqZSh1LmZyb20scy5mcm9tKSkmJmMucHVzaCh7ZnJvbTp1LmZyb20sdG86cy5mcm9tfSksKCRlKHMudG8sdS50byl8fCFsLmluY2x1c2l2ZVJpZ2h0JiZqZSh1LnRvLHMudG8pKSYmYy5wdXNoKHtmcm9tOnMudG8sdG86dS50b30pLGkuc3BsaWNlLmFwcGx5KGksYyksYSs9Yy5sZW5ndGgtMX19cmV0dXJuIGl9ZnVuY3Rpb24gUHIodCxlKXt2YXIgcixuPVFpJiZ0Lm1hcmtlZFNwYW5zO2lmKG4pZm9yKHZhciBpLG89MDtvPG4ubGVuZ3RoOysrbylpPW5bb10saS5tYXJrZXIuY29sbGFwc2VkJiYobnVsbD09aS5mcm9tfHxpLmZyb208ZSkmJihudWxsPT1pLnRvfHxpLnRvPmUpJiYoIXJ8fHIud2lkdGg8aS5tYXJrZXIud2lkdGgpJiYocj1pLm1hcmtlcik7cmV0dXJuIHJ9ZnVuY3Rpb24gUnIodCl7cmV0dXJuIFByKHQsLTEpfWZ1bmN0aW9uIEJyKHQpe3JldHVybiBQcih0LHQudGV4dC5sZW5ndGgrMSl9ZnVuY3Rpb24gR3IodCxlKXtmb3IodmFyIHI7cj1ScihlKTspZT1nbih0LHIuZmluZCgpLmZyb20ubGluZSk7cmV0dXJuIGV9ZnVuY3Rpb24gVnIodCxlKXt2YXIgcj1RaSYmZS5tYXJrZWRTcGFucztpZihyKWZvcih2YXIgbixpPTA7aTxyLmxlbmd0aDsrK2kpaWYobj1yW2ldLG4ubWFya2VyLmNvbGxhcHNlZCl7aWYobnVsbD09bi5mcm9tKXJldHVybiEwO2lmKCFuLm1hcmtlci5yZXBsYWNlZFdpdGgmJjA9PW4uZnJvbSYmbi5tYXJrZXIuaW5jbHVzaXZlTGVmdCYmS3IodCxlLG4pKXJldHVybiEwfX1mdW5jdGlvbiBLcih0LGUscil7aWYobnVsbD09ci50byl7dmFyIG49ci5tYXJrZXIuZmluZCgpLnRvLGk9Z24odCxuLmxpbmUpO3JldHVybiBLcih0LGksTnIoaS5tYXJrZWRTcGFucyxyLm1hcmtlcikpfWlmKHIubWFya2VyLmluY2x1c2l2ZVJpZ2h0JiZyLnRvPT1lLnRleHQubGVuZ3RoKXJldHVybiEwO2Zvcih2YXIgbyxsPTA7bDxlLm1hcmtlZFNwYW5zLmxlbmd0aDsrK2wpaWYobz1lLm1hcmtlZFNwYW5zW2xdLG8ubWFya2VyLmNvbGxhcHNlZCYmIW8ubWFya2VyLnJlcGxhY2VkV2l0aCYmby5mcm9tPT1yLnRvJiYoby5tYXJrZXIuaW5jbHVzaXZlTGVmdHx8ci5tYXJrZXIuaW5jbHVzaXZlUmlnaHQpJiZLcih0LGUsbykpcmV0dXJuITB9ZnVuY3Rpb24gVXIodCl7dmFyIGU9dC5tYXJrZWRTcGFucztpZihlKXtmb3IodmFyIHI9MDtyPGUubGVuZ3RoOysrcillW3JdLm1hcmtlci5kZXRhY2hMaW5lKHQpO3QubWFya2VkU3BhbnM9bnVsbH19ZnVuY3Rpb24gWHIodCxlKXtpZihlKXtmb3IodmFyIHI9MDtyPGUubGVuZ3RoOysrcillW3JdLm1hcmtlci5hdHRhY2hMaW5lKHQpO3QubWFya2VkU3BhbnM9ZX19ZnVuY3Rpb24gX3IodCl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIGU9IXRoaXMuY20uY3VyT3A7ZSYmaWUodGhpcy5jbSk7dHJ5e3ZhciByPXQuYXBwbHkodGhpcyxhcmd1bWVudHMpfWZpbmFsbHl7ZSYmb2UodGhpcy5jbSl9cmV0dXJuIHJ9fWZ1bmN0aW9uIFlyKHQpe3JldHVybiBudWxsIT10LmhlaWdodD90LmhlaWdodDoodC5ub2RlLnBhcmVudE5vZGUmJjE9PXQubm9kZS5wYXJlbnROb2RlLm5vZGVUeXBlfHx1aSh0LmNtLmRpc3BsYXkubWVhc3VyZSxzaSgiZGl2IixbdC5ub2RlXSxudWxsLCJwb3NpdGlvbjogcmVsYXRpdmUiKSksdC5oZWlnaHQ9dC5ub2RlLm9mZnNldEhlaWdodCl9ZnVuY3Rpb24ganIodCxlLHIsbil7dmFyIGk9bmV3IHlvKHQscixuKTtyZXR1cm4gaS5ub0hTY3JvbGwmJih0LmRpc3BsYXkuYWxpZ25XaWRnZXRzPSEwKSxkcih0LGUsZnVuY3Rpb24oZSl7dmFyIHI9ZS53aWRnZXRzfHwoZS53aWRnZXRzPVtdKTtpZihudWxsPT1pLmluc2VydEF0P3IucHVzaChpKTpyLnNwbGljZShNYXRoLm1pbihyLmxlbmd0aC0xLE1hdGgubWF4KDAsaS5pbnNlcnRBdCkpLDAsaSksaS5saW5lPWUsIVZyKHQuZG9jLGUpfHxpLnNob3dJZkhpZGRlbil7dmFyIG49Q24odCxlKTx0LmRvYy5zY3JvbGxUb3A7eW4oZSxlLmhlaWdodCtZcihpKSksbiYmZnIodCwwLGkuaGVpZ2h0KX1yZXR1cm4hMH0pLGl9ZnVuY3Rpb24gJHIodCxlLHIsbil7dC50ZXh0PWUsdC5zdGF0ZUFmdGVyJiYodC5zdGF0ZUFmdGVyPW51bGwpLHQuc3R5bGVzJiYodC5zdHlsZXM9bnVsbCksbnVsbCE9dC5vcmRlciYmKHQub3JkZXI9bnVsbCksVXIodCksWHIodCxyKTt2YXIgaT1uP24odCk6MTtpIT10LmhlaWdodCYmeW4odCxpKX1mdW5jdGlvbiBacih0KXt0LnBhcmVudD1udWxsLFVyKHQpfWZ1bmN0aW9uIHFyKHQsZSxyLG4saSxvKXt2YXIgbD1yLmZsYXR0ZW5TcGFucztudWxsPT1sJiYobD10Lm9wdGlvbnMuZmxhdHRlblNwYW5zKTt2YXIgcyxhPTAsdT1udWxsLGM9bmV3IFNyKGUsdC5vcHRpb25zLnRhYlNpemUpO2ZvcigiIj09ZSYmci5ibGFua0xpbmUmJnIuYmxhbmtMaW5lKG4pOyFjLmVvbCgpOyljLnBvcz50Lm9wdGlvbnMubWF4SGlnaGxpZ2h0TGVuZ3RoPyhsPSExLG8mJnRuKHQsZSxuLGMucG9zKSxjLnBvcz1lLmxlbmd0aCxzPW51bGwpOnM9ci50b2tlbihjLG4pLGwmJnU9PXN8fChhPGMuc3RhcnQmJmkoYy5zdGFydCx1KSxhPWMuc3RhcnQsdT1zKSxjLnN0YXJ0PWMucG9zO2Zvcig7YTxjLnBvczspe3ZhciBmPU1hdGgubWluKGMucG9zLGErNWU0KTtpKGYsdSksYT1mfX1mdW5jdGlvbiBRcih0LGUscixuKXt2YXIgaT1bdC5zdGF0ZS5tb2RlR2VuXTtxcih0LGUudGV4dCx0LmRvYy5tb2RlLHIsZnVuY3Rpb24odCxlKXtpLnB1c2godCxlKX0sbik7Zm9yKHZhciBvPTA7bzx0LnN0YXRlLm92ZXJsYXlzLmxlbmd0aDsrK28pe3ZhciBsPXQuc3RhdGUub3ZlcmxheXNbb10scz0xLGE9MDtxcih0LGUudGV4dCxsLm1vZGUsITAsZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9czt0PmE7KXt2YXIgbj1pW3NdO24+dCYmaS5zcGxpY2UocywxLHQsaVtzKzFdLG4pLHMrPTIsYT1NYXRoLm1pbih0LG4pfWlmKGUpaWYobC5vcGFxdWUpaS5zcGxpY2UocixzLXIsdCxlKSxzPXIrMjtlbHNlIGZvcig7cz5yO3IrPTIpe3ZhciBvPWlbcisxXTtpW3IrMV09bz9vKyIgIitlOmV9fSl9cmV0dXJuIGl9ZnVuY3Rpb24gSnIodCxlKXtyZXR1cm4gZS5zdHlsZXMmJmUuc3R5bGVzWzBdPT10LnN0YXRlLm1vZGVHZW58fChlLnN0eWxlcz1Rcih0LGUsZS5zdGF0ZUFmdGVyPXoodCxibihlKSkpKSxlLnN0eWxlc31mdW5jdGlvbiB0bih0LGUscixuKXt2YXIgaT10LmRvYy5tb2RlLG89bmV3IFNyKGUsdC5vcHRpb25zLnRhYlNpemUpO2ZvcihvLnN0YXJ0PW8ucG9zPW58fDAsIiI9PWUmJmkuYmxhbmtMaW5lJiZpLmJsYW5rTGluZShyKTshby5lb2woKSYmby5wb3M8PXQub3B0aW9ucy5tYXhIaWdobGlnaHRMZW5ndGg7KWkudG9rZW4obyxyKSxvLnN0YXJ0PW8ucG9zfWZ1bmN0aW9uIGVuKHQsZSl7aWYoIXQpcmV0dXJuIG51bGw7Zm9yKDs7KXt2YXIgcj10Lm1hdGNoKC8oPzpefFxzKWxpbmUtKGJhY2tncm91bmQtKT8oXFMrKS8pO2lmKCFyKWJyZWFrO3Q9dC5zbGljZSgwLHIuaW5kZXgpK3Quc2xpY2Uoci5pbmRleCtyWzBdLmxlbmd0aCk7dmFyIG49clsxXT8iYmdDbGFzcyI6InRleHRDbGFzcyI7bnVsbD09ZVtuXT9lW25dPXJbMl06bmV3IFJlZ0V4cCgiKD86XnxzKSIrclsyXSsiKD86JHxzKSIpLnRlc3QoZVtuXSl8fChlW25dKz0iICIrclsyXSl9cmV0dXJuIHhvW3RdfHwoeG9bdF09ImNtLSIrdC5yZXBsYWNlKC8gKy9nLCIgY20tIikpfWZ1bmN0aW9uIHJuKHQsZSxyLG4pe2Zvcih2YXIgaSxvPWUsbD0hMDtpPVJyKG8pOylvPWduKHQuZG9jLGkuZmluZCgpLmZyb20ubGluZSk7dmFyIHM9e3ByZTpzaSgicHJlIiksY29sOjAscG9zOjAsbWVhc3VyZTpudWxsLG1lYXN1cmVkU29tZXRoaW5nOiExLGNtOnQsY29weVdpZGdldHM6bn07ZG97by50ZXh0JiYobD0hMSkscy5tZWFzdXJlPW89PWUmJnIscy5wb3M9MCxzLmFkZFRva2VuPXMubWVhc3VyZT9sbjpvbiwoQWl8fFdpKSYmdC5nZXRPcHRpb24oImxpbmVXcmFwcGluZyIpJiYocy5hZGRUb2tlbj1zbihzLmFkZFRva2VuKSk7dmFyIGE9dW4obyxzLEpyKHQsbykpO3ImJm89PWUmJiFzLm1lYXN1cmVkU29tZXRoaW5nJiYoclswXT1zLnByZS5hcHBlbmRDaGlsZChwaSh0LmRpc3BsYXkubWVhc3VyZSkpLHMubWVhc3VyZWRTb21ldGhpbmc9ITApLGEmJihvPWduKHQuZG9jLGEudG8ubGluZSkpfXdoaWxlKGEpOyFyfHxzLm1lYXN1cmVkU29tZXRoaW5nfHxyWzBdfHwoclswXT1zLnByZS5hcHBlbmRDaGlsZChsP3NpKCJzcGFuIiwiwqAiKTpwaSh0LmRpc3BsYXkubWVhc3VyZSkpKSxzLnByZS5maXJzdENoaWxkfHxWcih0LmRvYyxlKXx8cy5wcmUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIsKgIikpO3ZhciB1O2lmKHImJihBaXx8RGkpJiYodT13bihvKSkpe3ZhciBjPXUubGVuZ3RoLTE7dVtjXS5mcm9tPT11W2NdLnRvJiYtLWM7dmFyIGY9dVtjXSxoPXVbYy0xXTtpZihmLmZyb20rMT09Zi50byYmaCYmZi5sZXZlbDxoLmxldmVsKXt2YXIgZD1yW3MucG9zLTFdO2QmJmQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZC5tZWFzdXJlUmlnaHQ9cGkodC5kaXNwbGF5Lm1lYXN1cmUpLGQubmV4dFNpYmxpbmcpfX12YXIgcD1zLnRleHRDbGFzcz9zLnRleHRDbGFzcysiICIrKGUudGV4dENsYXNzfHwiIik6ZS50ZXh0Q2xhc3M7cmV0dXJuIHAmJihzLnByZS5jbGFzc05hbWU9cCksS24odCwicmVuZGVyTGluZSIsdCxlLHMucHJlKSxzfWZ1bmN0aW9uIG5uKHQpe3ZhciBlPXNpKCJzcGFuIiwi4oCiIiwiY20taW52YWxpZGNoYXIiKTtyZXR1cm4gZS50aXRsZT0iXFx1Iit0LmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLGV9ZnVuY3Rpb24gb24odCxlLHIsbixpLG8pe2lmKGUpe3ZhciBsPXQuY20ub3B0aW9ucy5zcGVjaWFsQ2hhcnM7aWYobC50ZXN0KGUpKWZvcih2YXIgcz1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksYT0wOzspe2wubGFzdEluZGV4PWE7dmFyIHU9bC5leGVjKGUpLGM9dT91LmluZGV4LWE6ZS5sZW5ndGgtYTtpZihjJiYocy5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShlLnNsaWNlKGEsYStjKSkpLHQuY29sKz1jKSwhdSlicmVhaztpZihhKz1jKzEsIgkiPT11WzBdKXt2YXIgZj10LmNtLm9wdGlvbnMudGFiU2l6ZSxoPWYtdC5jb2wlZjtzLmFwcGVuZENoaWxkKHNpKCJzcGFuIixxbihoKSwiY20tdGFiIikpLHQuY29sKz1ofWVsc2V7dmFyIGQ9dC5jbS5vcHRpb25zLnNwZWNpYWxDaGFyUGxhY2Vob2xkZXIodVswXSk7cy5hcHBlbmRDaGlsZChkKSx0LmNvbCs9MX19ZWxzZXt0LmNvbCs9ZS5sZW5ndGg7dmFyIHM9ZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoZSl9aWYocnx8bnx8aXx8dC5tZWFzdXJlKXt2YXIgcD1yfHwiIjtuJiYocCs9biksaSYmKHArPWkpO3ZhciBkPXNpKCJzcGFuIixbc10scCk7cmV0dXJuIG8mJihkLnRpdGxlPW8pLHQucHJlLmFwcGVuZENoaWxkKGQpfXQucHJlLmFwcGVuZENoaWxkKHMpfX1mdW5jdGlvbiBsbih0LGUscixuLGkpe2Zvcih2YXIgbz10LmNtLm9wdGlvbnMubGluZVdyYXBwaW5nLGw9MDtsPGUubGVuZ3RoOysrbCl7dmFyIHM9ZS5jaGFyQXQobCksYT0wPT1sO3M+PSLtoIAiJiYi7a+/Ij5zJiZsPGUubGVuZ3RoLTE/KHM9ZS5zbGljZShsLGwrMiksKytsKTpsJiZvJiZoaShlLGwpJiZ0LnByZS5hcHBlbmRDaGlsZChzaSgid2JyIikpO3ZhciB1PXQubWVhc3VyZVt0LnBvc10sYz10Lm1lYXN1cmVbdC5wb3NdPW9uKHQscyxyLGEmJm4sbD09ZS5sZW5ndGgtMSYmaSk7dSYmKGMubGVmdFNpZGU9dS5sZWZ0U2lkZXx8dSksQWkmJm8mJiIgIj09cyYmbCYmIS9ccy8udGVzdChlLmNoYXJBdChsLTEpKSYmbDxlLmxlbmd0aC0xJiYhL1xzLy50ZXN0KGUuY2hhckF0KGwrMSkpJiYoYy5zdHlsZS53aGl0ZVNwYWNlPSJub3JtYWwiKSx0LnBvcys9cy5sZW5ndGh9ZS5sZW5ndGgmJih0Lm1lYXN1cmVkU29tZXRoaW5nPSEwKX1mdW5jdGlvbiBzbih0KXtmdW5jdGlvbiBlKHQpe2Zvcih2YXIgZT0iICIscj0wO3I8dC5sZW5ndGgtMjsrK3IpZSs9ciUyPyIgIjoiwqAiO3JldHVybiBlKz0iICJ9cmV0dXJuIGZ1bmN0aW9uKHIsbixpLG8sbCxzKXtyZXR1cm4gdChyLG4ucmVwbGFjZSgvIHszLH0vZyxlKSxpLG8sbCxzKX19ZnVuY3Rpb24gYW4odCxlLHIsbil7dmFyIGk9IW4mJnIucmVwbGFjZWRXaXRoO2lmKGkmJih0LmNvcHlXaWRnZXRzJiYoaT1pLmNsb25lTm9kZSghMCkpLHQucHJlLmFwcGVuZENoaWxkKGkpLHQubWVhc3VyZSkpe2lmKGUpdC5tZWFzdXJlW3QucG9zXT1pO2Vsc2V7dmFyIG89cGkodC5jbS5kaXNwbGF5Lm1lYXN1cmUpO2lmKCJib29rbWFyayIhPXIudHlwZXx8ci5pbnNlcnRMZWZ0KXtpZih0Lm1lYXN1cmVbdC5wb3NdKXJldHVybjt0Lm1lYXN1cmVbdC5wb3NdPXQucHJlLmluc2VydEJlZm9yZShvLGkpfWVsc2UgdC5tZWFzdXJlW3QucG9zXT10LnByZS5hcHBlbmRDaGlsZChvKX10Lm1lYXN1cmVkU29tZXRoaW5nPSEwfXQucG9zKz1lfWZ1bmN0aW9uIHVuKHQsZSxyKXt2YXIgbj10Lm1hcmtlZFNwYW5zLGk9dC50ZXh0LG89MDtpZihuKWZvcih2YXIgbCxzLGEsdSxjLGYsaD1pLmxlbmd0aCxkPTAscD0xLGc9IiIsbT0wOzspe2lmKG09PWQpe3M9YT11PWM9IiIsZj1udWxsLG09MS8wO2Zvcih2YXIgdj1bXSx5PTA7eTxuLmxlbmd0aDsrK3kpe3ZhciBiPW5beV0seD1iLm1hcmtlcjtiLmZyb208PWQmJihudWxsPT1iLnRvfHxiLnRvPmQpPyhudWxsIT1iLnRvJiZtPmIudG8mJihtPWIudG8sYT0iIikseC5jbGFzc05hbWUmJihzKz0iICIreC5jbGFzc05hbWUpLHguc3RhcnRTdHlsZSYmYi5mcm9tPT1kJiYodSs9IiAiK3guc3RhcnRTdHlsZSkseC5lbmRTdHlsZSYmYi50bz09bSYmKGErPSIgIit4LmVuZFN0eWxlKSx4LnRpdGxlJiYhYyYmKGM9eC50aXRsZSkseC5jb2xsYXBzZWQmJighZnx8Zi5tYXJrZXIuc2l6ZTx4LnNpemUpJiYoZj1iKSk6Yi5mcm9tPmQmJm0+Yi5mcm9tJiYobT1iLmZyb20pLCJib29rbWFyayI9PXgudHlwZSYmYi5mcm9tPT1kJiZ4LnJlcGxhY2VkV2l0aCYmdi5wdXNoKHgpCn1pZihmJiYoZi5mcm9tfHwwKT09ZCYmKGFuKGUsKG51bGw9PWYudG8/aDpmLnRvKS1kLGYubWFya2VyLG51bGw9PWYuZnJvbSksbnVsbD09Zi50bykpcmV0dXJuIGYubWFya2VyLmZpbmQoKTtpZighZiYmdi5sZW5ndGgpZm9yKHZhciB5PTA7eTx2Lmxlbmd0aDsrK3kpYW4oZSwwLHZbeV0pfWlmKGQ+PWgpYnJlYWs7Zm9yKHZhciBDPU1hdGgubWluKGgsbSk7Oyl7aWYoZyl7dmFyIHc9ZCtnLmxlbmd0aDtpZighZil7dmFyIEw9dz5DP2cuc2xpY2UoMCxDLWQpOmc7ZS5hZGRUb2tlbihlLEwsbD9sK3M6cyx1LGQrTC5sZW5ndGg9PW0/YToiIixjKX1pZih3Pj1DKXtnPWcuc2xpY2UoQy1kKSxkPUM7YnJlYWt9ZD13LHU9IiJ9Zz1pLnNsaWNlKG8sbz1yW3ArK10pLGw9ZW4ocltwKytdLGUpfX1lbHNlIGZvcih2YXIgcD0xO3A8ci5sZW5ndGg7cCs9MillLmFkZFRva2VuKGUsaS5zbGljZShvLG89cltwXSksZW4ocltwKzFdLGUpKX1mdW5jdGlvbiBjbih0LGUscixuLGkpe2Z1bmN0aW9uIG8odCl7cmV0dXJuIHI/clt0XTpudWxsfWZ1bmN0aW9uIGwodCxyLG4peyRyKHQscixuLGkpLFVuKHQsImNoYW5nZSIsdCxlKX12YXIgcz1lLmZyb20sYT1lLnRvLHU9ZS50ZXh0LGM9Z24odCxzLmxpbmUpLGY9Z24odCxhLmxpbmUpLGg9UW4odSksZD1vKHUubGVuZ3RoLTEpLHA9YS5saW5lLXMubGluZTtpZigwIT1zLmNofHwwIT1hLmNofHwiIiE9aHx8dC5jbSYmIXQuY20ub3B0aW9ucy53aG9sZUxpbmVVcGRhdGVCZWZvcmUpaWYoYz09ZilpZigxPT11Lmxlbmd0aClsKGMsYy50ZXh0LnNsaWNlKDAscy5jaCkraCtjLnRleHQuc2xpY2UoYS5jaCksZCk7ZWxzZXtmb3IodmFyIGc9W10sbT0xLHY9dS5sZW5ndGgtMTt2Pm07KyttKWcucHVzaChuZXcgYm8odVttXSxvKG0pLGkpKTtnLnB1c2gobmV3IGJvKGgrYy50ZXh0LnNsaWNlKGEuY2gpLGQsaSkpLGwoYyxjLnRleHQuc2xpY2UoMCxzLmNoKSt1WzBdLG8oMCkpLHQuaW5zZXJ0KHMubGluZSsxLGcpfWVsc2UgaWYoMT09dS5sZW5ndGgpbChjLGMudGV4dC5zbGljZSgwLHMuY2gpK3VbMF0rZi50ZXh0LnNsaWNlKGEuY2gpLG8oMCkpLHQucmVtb3ZlKHMubGluZSsxLHApO2Vsc2V7bChjLGMudGV4dC5zbGljZSgwLHMuY2gpK3VbMF0sbygwKSksbChmLGgrZi50ZXh0LnNsaWNlKGEuY2gpLGQpO2Zvcih2YXIgbT0xLHY9dS5sZW5ndGgtMSxnPVtdO3Y+bTsrK20pZy5wdXNoKG5ldyBibyh1W21dLG8obSksaSkpO3A+MSYmdC5yZW1vdmUocy5saW5lKzEscC0xKSx0Lmluc2VydChzLmxpbmUrMSxnKX1lbHNle2Zvcih2YXIgbT0wLHY9dS5sZW5ndGgtMSxnPVtdO3Y+bTsrK20pZy5wdXNoKG5ldyBibyh1W21dLG8obSksaSkpO2woZixmLnRleHQsZCkscCYmdC5yZW1vdmUocy5saW5lLHApLGcubGVuZ3RoJiZ0Lmluc2VydChzLmxpbmUsZyl9VW4odCwiY2hhbmdlIix0LGUpLG5yKHQsbi5hbmNob3Isbi5oZWFkLG51bGwsITApfWZ1bmN0aW9uIGZuKHQpe3RoaXMubGluZXM9dCx0aGlzLnBhcmVudD1udWxsO2Zvcih2YXIgZT0wLHI9dC5sZW5ndGgsbj0wO3I+ZTsrK2UpdFtlXS5wYXJlbnQ9dGhpcyxuKz10W2VdLmhlaWdodDt0aGlzLmhlaWdodD1ufWZ1bmN0aW9uIGhuKHQpe3RoaXMuY2hpbGRyZW49dDtmb3IodmFyIGU9MCxyPTAsbj0wLGk9dC5sZW5ndGg7aT5uOysrbil7dmFyIG89dFtuXTtlKz1vLmNodW5rU2l6ZSgpLHIrPW8uaGVpZ2h0LG8ucGFyZW50PXRoaXN9dGhpcy5zaXplPWUsdGhpcy5oZWlnaHQ9cix0aGlzLnBhcmVudD1udWxsfWZ1bmN0aW9uIGRuKHQsZSxyKXtmdW5jdGlvbiBuKHQsaSxvKXtpZih0LmxpbmtlZClmb3IodmFyIGw9MDtsPHQubGlua2VkLmxlbmd0aDsrK2wpe3ZhciBzPXQubGlua2VkW2xdO2lmKHMuZG9jIT1pKXt2YXIgYT1vJiZzLnNoYXJlZEhpc3Q7KCFyfHxhKSYmKGUocy5kb2MsYSksbihzLmRvYyx0LGEpKX19fW4odCxudWxsLCEwKX1mdW5jdGlvbiBwbih0LGUpe2lmKGUuY20pdGhyb3cgbmV3IEVycm9yKCJUaGlzIGRvY3VtZW50IGlzIGFscmVhZHkgaW4gdXNlLiIpO3QuZG9jPWUsZS5jbT10LG8odCkscih0KSx0Lm9wdGlvbnMubGluZVdyYXBwaW5nfHxmKHQpLHQub3B0aW9ucy5tb2RlPWUubW9kZU9wdGlvbix1ZSh0KX1mdW5jdGlvbiBnbih0LGUpe2ZvcihlLT10LmZpcnN0OyF0LmxpbmVzOylmb3IodmFyIHI9MDs7KytyKXt2YXIgbj10LmNoaWxkcmVuW3JdLGk9bi5jaHVua1NpemUoKTtpZihpPmUpe3Q9bjticmVha31lLT1pfXJldHVybiB0LmxpbmVzW2VdfWZ1bmN0aW9uIG1uKHQsZSxyKXt2YXIgbj1bXSxpPWUubGluZTtyZXR1cm4gdC5pdGVyKGUubGluZSxyLmxpbmUrMSxmdW5jdGlvbih0KXt2YXIgbz10LnRleHQ7aT09ci5saW5lJiYobz1vLnNsaWNlKDAsci5jaCkpLGk9PWUubGluZSYmKG89by5zbGljZShlLmNoKSksbi5wdXNoKG8pLCsraX0pLG59ZnVuY3Rpb24gdm4odCxlLHIpe3ZhciBuPVtdO3JldHVybiB0Lml0ZXIoZSxyLGZ1bmN0aW9uKHQpe24ucHVzaCh0LnRleHQpfSksbn1mdW5jdGlvbiB5bih0LGUpe2Zvcih2YXIgcj1lLXQuaGVpZ2h0LG49dDtuO249bi5wYXJlbnQpbi5oZWlnaHQrPXJ9ZnVuY3Rpb24gYm4odCl7aWYobnVsbD09dC5wYXJlbnQpcmV0dXJuIG51bGw7Zm9yKHZhciBlPXQucGFyZW50LHI9dGkoZS5saW5lcyx0KSxuPWUucGFyZW50O247ZT1uLG49bi5wYXJlbnQpZm9yKHZhciBpPTA7bi5jaGlsZHJlbltpXSE9ZTsrK2kpcis9bi5jaGlsZHJlbltpXS5jaHVua1NpemUoKTtyZXR1cm4gcitlLmZpcnN0fWZ1bmN0aW9uIHhuKHQsZSl7dmFyIHI9dC5maXJzdDt0OmRve2Zvcih2YXIgbj0wLGk9dC5jaGlsZHJlbi5sZW5ndGg7aT5uOysrbil7dmFyIG89dC5jaGlsZHJlbltuXSxsPW8uaGVpZ2h0O2lmKGw+ZSl7dD1vO2NvbnRpbnVlIHR9ZS09bCxyKz1vLmNodW5rU2l6ZSgpfXJldHVybiByfXdoaWxlKCF0LmxpbmVzKTtmb3IodmFyIG49MCxpPXQubGluZXMubGVuZ3RoO2k+bjsrK24pe3ZhciBzPXQubGluZXNbbl0sYT1zLmhlaWdodDtpZihhPmUpYnJlYWs7ZS09YX1yZXR1cm4gcitufWZ1bmN0aW9uIENuKHQsZSl7ZT1Hcih0LmRvYyxlKTtmb3IodmFyIHI9MCxuPWUucGFyZW50LGk9MDtpPG4ubGluZXMubGVuZ3RoOysraSl7dmFyIG89bi5saW5lc1tpXTtpZihvPT1lKWJyZWFrO3IrPW8uaGVpZ2h0fWZvcih2YXIgbD1uLnBhcmVudDtsO249bCxsPW4ucGFyZW50KWZvcih2YXIgaT0wO2k8bC5jaGlsZHJlbi5sZW5ndGg7KytpKXt2YXIgcz1sLmNoaWxkcmVuW2ldO2lmKHM9PW4pYnJlYWs7cis9cy5oZWlnaHR9cmV0dXJuIHJ9ZnVuY3Rpb24gd24odCl7dmFyIGU9dC5vcmRlcjtyZXR1cm4gbnVsbD09ZSYmKGU9dC5vcmRlcj1Cbyh0LnRleHQpKSxlfWZ1bmN0aW9uIExuKHQpe3JldHVybntkb25lOltdLHVuZG9uZTpbXSx1bmRvRGVwdGg6MS8wLGxhc3RUaW1lOjAsbGFzdE9wOm51bGwsbGFzdE9yaWdpbjpudWxsLGdlbmVyYXRpb246dHx8MSxtYXhHZW5lcmF0aW9uOnR8fDF9fWZ1bmN0aW9uIGtuKHQsZSxyLG4pe3ZhciBpPWVbInNwYW5zXyIrdC5pZF0sbz0wO3QuaXRlcihNYXRoLm1heCh0LmZpcnN0LHIpLE1hdGgubWluKHQuZmlyc3QrdC5zaXplLG4pLGZ1bmN0aW9uKHIpe3IubWFya2VkU3BhbnMmJigoaXx8KGk9ZVsic3BhbnNfIit0LmlkXT17fSkpW29dPXIubWFya2VkU3BhbnMpLCsrb30pfWZ1bmN0aW9uIFNuKHQsZSl7dmFyIHI9e2xpbmU6ZS5mcm9tLmxpbmUsY2g6ZS5mcm9tLmNofSxuPXtmcm9tOnIsdG86bG8oZSksdGV4dDptbih0LGUuZnJvbSxlLnRvKX07cmV0dXJuIGtuKHQsbixlLmZyb20ubGluZSxlLnRvLmxpbmUrMSksZG4odCxmdW5jdGlvbih0KXtrbih0LG4sZS5mcm9tLmxpbmUsZS50by5saW5lKzEpfSwhMCksbn1mdW5jdGlvbiBNbih0LGUscixuKXt2YXIgaT10Lmhpc3Rvcnk7aS51bmRvbmUubGVuZ3RoPTA7dmFyIG89K25ldyBEYXRlLGw9UW4oaS5kb25lKTtpZihsJiYoaS5sYXN0T3A9PW58fGkubGFzdE9yaWdpbj09ZS5vcmlnaW4mJmUub3JpZ2luJiYoIisiPT1lLm9yaWdpbi5jaGFyQXQoMCkmJnQuY20mJmkubGFzdFRpbWU+by10LmNtLm9wdGlvbnMuaGlzdG9yeUV2ZW50RGVsYXl8fCIqIj09ZS5vcmlnaW4uY2hhckF0KDApKSkpe3ZhciBzPVFuKGwuY2hhbmdlcyk7amUoZS5mcm9tLGUudG8pJiZqZShlLmZyb20scy50byk/cy50bz1sbyhlKTpsLmNoYW5nZXMucHVzaChTbih0LGUpKSxsLmFuY2hvckFmdGVyPXIuYW5jaG9yLGwuaGVhZEFmdGVyPXIuaGVhZH1lbHNlIGZvcihsPXtjaGFuZ2VzOltTbih0LGUpXSxnZW5lcmF0aW9uOmkuZ2VuZXJhdGlvbixhbmNob3JCZWZvcmU6dC5zZWwuYW5jaG9yLGhlYWRCZWZvcmU6dC5zZWwuaGVhZCxhbmNob3JBZnRlcjpyLmFuY2hvcixoZWFkQWZ0ZXI6ci5oZWFkfSxpLmRvbmUucHVzaChsKSxpLmdlbmVyYXRpb249KytpLm1heEdlbmVyYXRpb247aS5kb25lLmxlbmd0aD5pLnVuZG9EZXB0aDspaS5kb25lLnNoaWZ0KCk7aS5sYXN0VGltZT1vLGkubGFzdE9wPW4saS5sYXN0T3JpZ2luPWUub3JpZ2lufWZ1bmN0aW9uIFRuKHQpe2lmKCF0KXJldHVybiBudWxsO2Zvcih2YXIgZSxyPTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5tYXJrZXIuZXhwbGljaXRseUNsZWFyZWQ/ZXx8KGU9dC5zbGljZSgwLHIpKTplJiZlLnB1c2godFtyXSk7cmV0dXJuIGU/ZS5sZW5ndGg/ZTpudWxsOnR9ZnVuY3Rpb24gQW4odCxlKXt2YXIgcj1lWyJzcGFuc18iK3QuaWRdO2lmKCFyKXJldHVybiBudWxsO2Zvcih2YXIgbj0wLGk9W107bjxlLnRleHQubGVuZ3RoOysrbilpLnB1c2goVG4ocltuXSkpO3JldHVybiBpfWZ1bmN0aW9uIEhuKHQsZSl7Zm9yKHZhciByPTAsbj1bXTtyPHQubGVuZ3RoOysrcil7dmFyIGk9dFtyXSxvPWkuY2hhbmdlcyxsPVtdO24ucHVzaCh7Y2hhbmdlczpsLGFuY2hvckJlZm9yZTppLmFuY2hvckJlZm9yZSxoZWFkQmVmb3JlOmkuaGVhZEJlZm9yZSxhbmNob3JBZnRlcjppLmFuY2hvckFmdGVyLGhlYWRBZnRlcjppLmhlYWRBZnRlcn0pO2Zvcih2YXIgcz0wO3M8by5sZW5ndGg7KytzKXt2YXIgYSx1PW9bc107aWYobC5wdXNoKHtmcm9tOnUuZnJvbSx0bzp1LnRvLHRleHQ6dS50ZXh0fSksZSlmb3IodmFyIGMgaW4gdSkoYT1jLm1hdGNoKC9ec3BhbnNfKFxkKykkLykpJiZ0aShlLE51bWJlcihhWzFdKSk+LTEmJihRbihsKVtjXT11W2NdLGRlbGV0ZSB1W2NdKX19cmV0dXJuIG59ZnVuY3Rpb24gTm4odCxlLHIsbil7cjx0LmxpbmU/dC5saW5lKz1uOmU8dC5saW5lJiYodC5saW5lPWUsdC5jaD0wKX1mdW5jdGlvbiBEbih0LGUscixuKXtmb3IodmFyIGk9MDtpPHQubGVuZ3RoOysraSl7Zm9yKHZhciBvPXRbaV0sbD0hMCxzPTA7czxvLmNoYW5nZXMubGVuZ3RoOysrcyl7dmFyIGE9by5jaGFuZ2VzW3NdO2lmKG8uY29waWVkfHwoYS5mcm9tPVplKGEuZnJvbSksYS50bz1aZShhLnRvKSkscjxhLmZyb20ubGluZSlhLmZyb20ubGluZSs9bixhLnRvLmxpbmUrPW47ZWxzZSBpZihlPD1hLnRvLmxpbmUpe2w9ITE7YnJlYWt9fW8uY29waWVkfHwoby5hbmNob3JCZWZvcmU9WmUoby5hbmNob3JCZWZvcmUpLG8uaGVhZEJlZm9yZT1aZShvLmhlYWRCZWZvcmUpLG8uYW5jaG9yQWZ0ZXI9WmUoby5hbmNob3JBZnRlciksby5yZWFkQWZ0ZXI9WmUoby5oZWFkQWZ0ZXIpLG8uY29waWVkPSEwKSxsPyhObihvLmFuY2hvckJlZm9yZSksTm4oby5oZWFkQmVmb3JlKSxObihvLmFuY2hvckFmdGVyKSxObihvLmhlYWRBZnRlcikpOih0LnNwbGljZSgwLGkrMSksaT0wKX19ZnVuY3Rpb24gV24odCxlKXt2YXIgcj1lLmZyb20ubGluZSxuPWUudG8ubGluZSxpPWUudGV4dC5sZW5ndGgtKG4tciktMTtEbih0LmRvbmUscixuLGkpLERuKHQudW5kb25lLHIsbixpKX1mdW5jdGlvbiBPbigpe1BuKHRoaXMpfWZ1bmN0aW9uIEVuKHQpe3JldHVybiB0LnN0b3B8fCh0LnN0b3A9T24pLHR9ZnVuY3Rpb24gem4odCl7dC5wcmV2ZW50RGVmYXVsdD90LnByZXZlbnREZWZhdWx0KCk6dC5yZXR1cm5WYWx1ZT0hMX1mdW5jdGlvbiBJbih0KXt0LnN0b3BQcm9wYWdhdGlvbj90LnN0b3BQcm9wYWdhdGlvbigpOnQuY2FuY2VsQnViYmxlPSEwfWZ1bmN0aW9uIEZuKHQpe3JldHVybiBudWxsIT10LmRlZmF1bHRQcmV2ZW50ZWQ/dC5kZWZhdWx0UHJldmVudGVkOjA9PXQucmV0dXJuVmFsdWV9ZnVuY3Rpb24gUG4odCl7em4odCksSW4odCl9ZnVuY3Rpb24gUm4odCl7cmV0dXJuIHQudGFyZ2V0fHx0LnNyY0VsZW1lbnR9ZnVuY3Rpb24gQm4odCl7dmFyIGU9dC53aGljaDtyZXR1cm4gbnVsbD09ZSYmKDEmdC5idXR0b24/ZT0xOjImdC5idXR0b24/ZT0zOjQmdC5idXR0b24mJihlPTIpKSxLaSYmdC5jdHJsS2V5JiYxPT1lJiYoZT0zKSxlfWZ1bmN0aW9uIEduKHQsZSxyKXtpZih0LmFkZEV2ZW50TGlzdGVuZXIpdC5hZGRFdmVudExpc3RlbmVyKGUsciwhMSk7ZWxzZSBpZih0LmF0dGFjaEV2ZW50KXQuYXR0YWNoRXZlbnQoIm9uIitlLHIpO2Vsc2V7dmFyIG49dC5faGFuZGxlcnN8fCh0Ll9oYW5kbGVycz17fSksaT1uW2VdfHwobltlXT1bXSk7aS5wdXNoKHIpfX1mdW5jdGlvbiBWbih0LGUscil7aWYodC5yZW1vdmVFdmVudExpc3RlbmVyKXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLHIsITEpO2Vsc2UgaWYodC5kZXRhY2hFdmVudCl0LmRldGFjaEV2ZW50KCJvbiIrZSxyKTtlbHNle3ZhciBuPXQuX2hhbmRsZXJzJiZ0Ll9oYW5kbGVyc1tlXTtpZighbilyZXR1cm47Zm9yKHZhciBpPTA7aTxuLmxlbmd0aDsrK2kpaWYobltpXT09cil7bi5zcGxpY2UoaSwxKTticmVha319fWZ1bmN0aW9uIEtuKHQsZSl7dmFyIHI9dC5faGFuZGxlcnMmJnQuX2hhbmRsZXJzW2VdO2lmKHIpZm9yKHZhciBuPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKSxpPTA7aTxyLmxlbmd0aDsrK2kpcltpXS5hcHBseShudWxsLG4pfWZ1bmN0aW9uIFVuKHQsZSl7ZnVuY3Rpb24gcih0KXtyZXR1cm4gZnVuY3Rpb24oKXt0LmFwcGx5KG51bGwsaSl9fXZhciBuPXQuX2hhbmRsZXJzJiZ0Ll9oYW5kbGVyc1tlXTtpZihuKXt2YXIgaT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMik7U298fCgrK01vLFNvPVtdLHNldFRpbWVvdXQoX24sMCkpO2Zvcih2YXIgbz0wO288bi5sZW5ndGg7KytvKVNvLnB1c2gocihuW29dKSl9fWZ1bmN0aW9uIFhuKHQsZSxyKXtyZXR1cm4gS24odCxyfHxlLnR5cGUsdCxlKSxGbihlKXx8ZS5jb2RlbWlycm9ySWdub3JlfWZ1bmN0aW9uIF9uKCl7LS1Nbzt2YXIgdD1TbztTbz1udWxsO2Zvcih2YXIgZT0wO2U8dC5sZW5ndGg7KytlKXRbZV0oKX1mdW5jdGlvbiBZbih0LGUpe3ZhciByPXQuX2hhbmRsZXJzJiZ0Ll9oYW5kbGVyc1tlXTtyZXR1cm4gciYmci5sZW5ndGg+MH1mdW5jdGlvbiBqbih0KXt0LnByb3RvdHlwZS5vbj1mdW5jdGlvbih0LGUpe0duKHRoaXMsdCxlKX0sdC5wcm90b3R5cGUub2ZmPWZ1bmN0aW9uKHQsZSl7Vm4odGhpcyx0LGUpfX1mdW5jdGlvbiAkbigpe3RoaXMuaWQ9bnVsbH1mdW5jdGlvbiBabih0LGUscixuLGkpe251bGw9PWUmJihlPXQuc2VhcmNoKC9bXlxzXHUwMGEwXS8pLC0xPT1lJiYoZT10Lmxlbmd0aCkpO2Zvcih2YXIgbz1ufHwwLGw9aXx8MDtlPm87KytvKSIJIj09dC5jaGFyQXQobyk/bCs9ci1sJXI6KytsO3JldHVybiBsfWZ1bmN0aW9uIHFuKHQpe2Zvcig7SG8ubGVuZ3RoPD10OylIby5wdXNoKFFuKEhvKSsiICIpO3JldHVybiBIb1t0XX1mdW5jdGlvbiBRbih0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXX1mdW5jdGlvbiBKbih0KXtpZihHaSl0LnNlbGVjdGlvblN0YXJ0PTAsdC5zZWxlY3Rpb25FbmQ9dC52YWx1ZS5sZW5ndGg7ZWxzZSB0cnl7dC5zZWxlY3QoKX1jYXRjaChlKXt9fWZ1bmN0aW9uIHRpKHQsZSl7aWYodC5pbmRleE9mKXJldHVybiB0LmluZGV4T2YoZSk7Zm9yKHZhciByPTAsbj10Lmxlbmd0aDtuPnI7KytyKWlmKHRbcl09PWUpcmV0dXJuIHI7cmV0dXJuLTF9ZnVuY3Rpb24gZWkodCxlKXtmdW5jdGlvbiByKCl7fXIucHJvdG90eXBlPXQ7dmFyIG49bmV3IHI7cmV0dXJuIGUmJnJpKGUsbiksbn1mdW5jdGlvbiByaSh0LGUpe2V8fChlPXt9KTtmb3IodmFyIHIgaW4gdCl0Lmhhc093blByb3BlcnR5KHIpJiYoZVtyXT10W3JdKTtyZXR1cm4gZX1mdW5jdGlvbiBuaSh0KXtmb3IodmFyIGU9W10scj0wO3Q+cjsrK3IpZS5wdXNoKHZvaWQgMCk7cmV0dXJuIGV9ZnVuY3Rpb24gaWkodCl7dmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO3JldHVybiBmdW5jdGlvbigpe3JldHVybiB0LmFwcGx5KG51bGwsZSl9fWZ1bmN0aW9uIG9pKHQpe3JldHVybi9cdy8udGVzdCh0KXx8dD4iwoAiJiYodC50b1VwcGVyQ2FzZSgpIT10LnRvTG93ZXJDYXNlKCl8fE5vLnRlc3QodCkpfWZ1bmN0aW9uIGxpKHQpe2Zvcih2YXIgZSBpbiB0KWlmKHQuaGFzT3duUHJvcGVydHkoZSkmJnRbZV0pcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gc2kodCxlLHIsbil7dmFyIGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0KTtpZihyJiYoaS5jbGFzc05hbWU9ciksbiYmKGkuc3R5bGUuY3NzVGV4dD1uKSwic3RyaW5nIj09dHlwZW9mIGUpY2koaSxlKTtlbHNlIGlmKGUpZm9yKHZhciBvPTA7bzxlLmxlbmd0aDsrK28paS5hcHBlbmRDaGlsZChlW29dKTtyZXR1cm4gaX1mdW5jdGlvbiBhaSh0KXtmb3IodmFyIGU9dC5jaGlsZE5vZGVzLmxlbmd0aDtlPjA7LS1lKXQucmVtb3ZlQ2hpbGQodC5maXJzdENoaWxkKTtyZXR1cm4gdH1mdW5jdGlvbiB1aSh0LGUpe3JldHVybiBhaSh0KS5hcHBlbmRDaGlsZChlKX1mdW5jdGlvbiBjaSh0LGUpe05pPyh0LmlubmVySFRNTD0iIix0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGUpKSk6dC50ZXh0Q29udGVudD1lfWZ1bmN0aW9uIGZpKHQpe3JldHVybiB0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpfWZ1bmN0aW9uIGhpKCl7cmV0dXJuITF9ZnVuY3Rpb24gZGkodCl7aWYobnVsbCE9T28pcmV0dXJuIE9vO3ZhciBlPXNpKCJkaXYiLG51bGwsbnVsbCwid2lkdGg6IDUwcHg7IGhlaWdodDogNTBweDsgb3ZlcmZsb3cteDogc2Nyb2xsIik7cmV0dXJuIHVpKHQsZSksZS5vZmZzZXRXaWR0aCYmKE9vPWUub2Zmc2V0SGVpZ2h0LWUuY2xpZW50SGVpZ2h0KSxPb3x8MH1mdW5jdGlvbiBwaSh0KXtpZihudWxsPT1Fbyl7dmFyIGU9c2koInNwYW4iLCLigIsiKTt1aSh0LHNpKCJzcGFuIixbZSxkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgieCIpXSkpLDAhPXQuZmlyc3RDaGlsZC5vZmZzZXRIZWlnaHQmJihFbz1lLm9mZnNldFdpZHRoPD0xJiZlLm9mZnNldEhlaWdodD4yJiYhSGkpfXJldHVybiBFbz9zaSgic3BhbiIsIuKAiyIpOnNpKCJzcGFuIiwiwqAiLG51bGwsImRpc3BsYXk6IGlubGluZS1ibG9jazsgd2lkdGg6IDFweDsgbWFyZ2luLXJpZ2h0OiAtMXB4Iil9ZnVuY3Rpb24gZ2kodCxlLHIsbil7aWYoIXQpcmV0dXJuIG4oZSxyLCJsdHIiKTtmb3IodmFyIGk9ITEsbz0wO288dC5sZW5ndGg7KytvKXt2YXIgbD10W29dOyhsLmZyb208ciYmbC50bz5lfHxlPT1yJiZsLnRvPT1lKSYmKG4oTWF0aC5tYXgobC5mcm9tLGUpLE1hdGgubWluKGwudG8sciksMT09bC5sZXZlbD8icnRsIjoibHRyIiksaT0hMCl9aXx8bihlLHIsImx0ciIpfWZ1bmN0aW9uIG1pKHQpe3JldHVybiB0LmxldmVsJTI/dC50bzp0LmZyb219ZnVuY3Rpb24gdmkodCl7cmV0dXJuIHQubGV2ZWwlMj90LmZyb206dC50b31mdW5jdGlvbiB5aSh0KXt2YXIgZT13bih0KTtyZXR1cm4gZT9taShlWzBdKTowfWZ1bmN0aW9uIGJpKHQpe3ZhciBlPXduKHQpO3JldHVybiBlP3ZpKFFuKGUpKTp0LnRleHQubGVuZ3RofWZ1bmN0aW9uIHhpKHQsZSl7dmFyIHI9Z24odC5kb2MsZSksbj1Hcih0LmRvYyxyKTtuIT1yJiYoZT1ibihuKSk7dmFyIGk9d24obiksbz1pP2lbMF0ubGV2ZWwlMj9iaShuKTp5aShuKTowO3JldHVybiBZZShlLG8pfWZ1bmN0aW9uIENpKHQsZSl7Zm9yKHZhciByLG47cj1CcihuPWduKHQuZG9jLGUpKTspZT1yLmZpbmQoKS50by5saW5lO3ZhciBpPXduKG4pLG89aT9pWzBdLmxldmVsJTI/eWkobik6Ymkobik6bi50ZXh0Lmxlbmd0aDtyZXR1cm4gWWUoZSxvKX1mdW5jdGlvbiB3aSh0LGUscil7dmFyIG49dFswXS5sZXZlbDtyZXR1cm4gZT09bj8hMDpyPT1uPyExOnI+ZX1mdW5jdGlvbiBMaSh0LGUpe2Zvcih2YXIgcixuPTA7bjx0Lmxlbmd0aDsrK24pe3ZhciBpPXRbbl07aWYoaS5mcm9tPGUmJmkudG8+ZSlyZXR1cm4gUm89bnVsbCxuO2lmKGkuZnJvbT09ZXx8aS50bz09ZSl7aWYobnVsbCE9cilyZXR1cm4gd2kodCxpLmxldmVsLHRbcl0ubGV2ZWwpPyhSbz1yLG4pOihSbz1uLHIpO3I9bn19cmV0dXJuIFJvPW51bGwscn1mdW5jdGlvbiBraSh0LGUscixuKXtpZighbilyZXR1cm4gZStyO2RvIGUrPXI7d2hpbGUoZT4wJiZEby50ZXN0KHQudGV4dC5jaGFyQXQoZSkpKTtyZXR1cm4gZX1mdW5jdGlvbiBTaSh0LGUscixuKXt2YXIgaT13bih0KTtpZighaSlyZXR1cm4gTWkodCxlLHIsbik7Zm9yKHZhciBvPUxpKGksZSksbD1pW29dLHM9a2kodCxlLGwubGV2ZWwlMj8tcjpyLG4pOzspe2lmKHM+bC5mcm9tJiZzPGwudG8pcmV0dXJuIHM7aWYocz09bC5mcm9tfHxzPT1sLnRvKXJldHVybiBMaShpLHMpPT1vP3M6KGw9aVtvKz1yXSxyPjA9PWwubGV2ZWwlMj9sLnRvOmwuZnJvbSk7aWYobD1pW28rPXJdLCFsKXJldHVybiBudWxsO3M9cj4wPT1sLmxldmVsJTI/a2kodCxsLnRvLC0xLG4pOmtpKHQsbC5mcm9tLDEsbil9fWZ1bmN0aW9uIE1pKHQsZSxyLG4pe3ZhciBpPWUrcjtpZihuKWZvcig7aT4wJiZEby50ZXN0KHQudGV4dC5jaGFyQXQoaSkpOylpKz1yO3JldHVybiAwPml8fGk+dC50ZXh0Lmxlbmd0aD9udWxsOml9dmFyIFRpPS9nZWNrb1wvXGQvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLEFpPS9NU0lFIFxkLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLEhpPUFpJiYobnVsbD09ZG9jdW1lbnQuZG9jdW1lbnRNb2RlfHxkb2N1bWVudC5kb2N1bWVudE1vZGU8OCksTmk9QWkmJihudWxsPT1kb2N1bWVudC5kb2N1bWVudE1vZGV8fGRvY3VtZW50LmRvY3VtZW50TW9kZTw5KSxEaT0vVHJpZGVudFwvKFs3LTldfFxkezIsfSlcLi8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSxXaT0vV2ViS2l0XC8vLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksT2k9V2kmJi9RdFwvXGQrXC5cZCsvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksRWk9L0Nocm9tZVwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLHppPS9PcGVyYVwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLElpPS9BcHBsZSBDb21wdXRlci8udGVzdChuYXZpZ2F0b3IudmVuZG9yKSxGaT0vS0hUTUxcLy8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSxQaT0vTWFjIE9TIFggMVxkXEQoWzctOV18XGRcZClcRC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSxSaT0vTWFjIE9TIFggMVxkXEQoWzgtOV18XGRcZClcRC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSxCaT0vUGhhbnRvbUpTLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLEdpPS9BcHBsZVdlYktpdC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSYmL01vYmlsZVwvXHcrLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLFZpPUdpfHwvQW5kcm9pZHx3ZWJPU3xCbGFja0JlcnJ5fE9wZXJhIE1pbml8T3BlcmEgTW9iaXxJRU1vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksS2k9R2l8fC9NYWMvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKSxVaT0vd2luL2kudGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pLFhpPXppJiZuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9WZXJzaW9uXC8oXGQqXC5cZCopLyk7WGkmJihYaT1OdW1iZXIoWGlbMV0pKSxYaSYmWGk+PTE1JiYoemk9ITEsV2k9ITApO3ZhciBfaSxZaSxqaSwkaT1LaSYmKE9pfHx6aSYmKG51bGw9PVhpfHwxMi4xMT5YaSkpLFppPVRpfHxBaSYmIU5pLHFpPSExLFFpPSExLEppPTAsdG89MCxlbz0wLHJvPW51bGw7QWk/cm89LS41MzpUaT9ybz0xNTpFaT9ybz0tLjc6SWkmJihybz0tMS8zKTt2YXIgbm8saW8sb289bnVsbCxsbz10LmNoYW5nZUVuZD1mdW5jdGlvbih0KXtyZXR1cm4gdC50ZXh0P1llKHQuZnJvbS5saW5lK3QudGV4dC5sZW5ndGgtMSxRbih0LnRleHQpLmxlbmd0aCsoMT09dC50ZXh0Lmxlbmd0aD90LmZyb20uY2g6MCkpOnQudG99O3QuUG9zPVllLHQucHJvdG90eXBlPXtjb25zdHJ1Y3Rvcjp0LGZvY3VzOmZ1bmN0aW9uKCl7d2luZG93LmZvY3VzKCkscGUodGhpcyksZmUodGhpcyl9LHNldE9wdGlvbjpmdW5jdGlvbih0LGUpe3ZhciByPXRoaXMub3B0aW9ucyxuPXJbdF07KHJbdF0hPWV8fCJtb2RlIj09dCkmJihyW3RdPWUsc28uaGFzT3duUHJvcGVydHkodCkmJmxlKHRoaXMsc29bdF0pKHRoaXMsZSxuKSl9LGdldE9wdGlvbjpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5vcHRpb25zW3RdfSxnZXREb2M6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb2N9LGFkZEtleU1hcDpmdW5jdGlvbih0LGUpe3RoaXMuc3RhdGUua2V5TWFwc1tlPyJwdXNoIjoidW5zaGlmdCJdKHQpfSxyZW1vdmVLZXlNYXA6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXRoaXMuc3RhdGUua2V5TWFwcyxyPTA7cjxlLmxlbmd0aDsrK3IpaWYoZVtyXT09dHx8InN0cmluZyIhPXR5cGVvZiBlW3JdJiZlW3JdLm5hbWU9PXQpcmV0dXJuIGUuc3BsaWNlKHIsMSksITB9LGFkZE92ZXJsYXk6bGUobnVsbCxmdW5jdGlvbihlLHIpe3ZhciBuPWUudG9rZW4/ZTp0LmdldE1vZGUodGhpcy5vcHRpb25zLGUpO2lmKG4uc3RhcnRTdGF0ZSl0aHJvdyBuZXcgRXJyb3IoIk92ZXJsYXlzIG1heSBub3QgYmUgc3RhdGVmdWwuIik7dGhpcy5zdGF0ZS5vdmVybGF5cy5wdXNoKHttb2RlOm4sbW9kZVNwZWM6ZSxvcGFxdWU6ciYmci5vcGFxdWV9KSx0aGlzLnN0YXRlLm1vZGVHZW4rKyx1ZSh0aGlzKX0pLHJlbW92ZU92ZXJsYXk6bGUobnVsbCxmdW5jdGlvbih0KXtmb3IodmFyIGU9dGhpcy5zdGF0ZS5vdmVybGF5cyxyPTA7cjxlLmxlbmd0aDsrK3Ipe3ZhciBuPWVbcl0ubW9kZVNwZWM7aWYobj09dHx8InN0cmluZyI9PXR5cGVvZiB0JiZuLm5hbWU9PXQpcmV0dXJuIGUuc3BsaWNlKHIsMSksdGhpcy5zdGF0ZS5tb2RlR2VuKyssdWUodGhpcyksdm9pZCAwfX0pLGluZGVudExpbmU6bGUobnVsbCxmdW5jdGlvbih0LGUscil7InN0cmluZyIhPXR5cGVvZiBlJiYibnVtYmVyIiE9dHlwZW9mIGUmJihlPW51bGw9PWU/dGhpcy5vcHRpb25zLnNtYXJ0SW5kZW50PyJzbWFydCI6InByZXYiOmU/ImFkZCI6InN1YnRyYWN0IiksdHIodGhpcy5kb2MsdCkmJmhyKHRoaXMsdCxlLHIpfSksaW5kZW50U2VsZWN0aW9uOmxlKG51bGwsZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5kb2Muc2VsO2lmKGplKGUuZnJvbSxlLnRvKSlyZXR1cm4gaHIodGhpcyxlLmZyb20ubGluZSx0KTtmb3IodmFyIHI9ZS50by5saW5lLShlLnRvLmNoPzA6MSksbj1lLmZyb20ubGluZTtyPj1uOysrbilocih0aGlzLG4sdCl9KSxnZXRUb2tlbkF0OmZ1bmN0aW9uKHQsZSl7dmFyIHI9dGhpcy5kb2M7dD1RZShyLHQpO2Zvcih2YXIgbj16KHRoaXMsdC5saW5lLGUpLGk9dGhpcy5kb2MubW9kZSxvPWduKHIsdC5saW5lKSxsPW5ldyBTcihvLnRleHQsdGhpcy5vcHRpb25zLnRhYlNpemUpO2wucG9zPHQuY2gmJiFsLmVvbCgpOyl7bC5zdGFydD1sLnBvczt2YXIgcz1pLnRva2VuKGwsbil9cmV0dXJue3N0YXJ0Omwuc3RhcnQsZW5kOmwucG9zLHN0cmluZzpsLmN1cnJlbnQoKSxjbGFzc05hbWU6c3x8bnVsbCx0eXBlOnN8fG51bGwsc3RhdGU6bn19LGdldFRva2VuVHlwZUF0OmZ1bmN0aW9uKHQpe3Q9UWUodGhpcy5kb2MsdCk7dmFyIGU9SnIodGhpcyxnbih0aGlzLmRvYyx0LmxpbmUpKSxyPTAsbj0oZS5sZW5ndGgtMSkvMixpPXQuY2g7aWYoMD09aSlyZXR1cm4gZVsyXTtmb3IoOzspe3ZhciBvPXIrbj4+MTtpZigobz9lWzIqby0xXTowKT49aSluPW87ZWxzZXtpZighKGVbMipvKzFdPGkpKXJldHVybiBlWzIqbysyXTtyPW8rMX19fSxnZXRNb2RlQXQ6ZnVuY3Rpb24oZSl7dmFyIHI9dGhpcy5kb2MubW9kZTtyZXR1cm4gci5pbm5lck1vZGU/dC5pbm5lck1vZGUocix0aGlzLmdldFRva2VuQXQoZSkuc3RhdGUpLm1vZGU6cn0sZ2V0SGVscGVyOmZ1bmN0aW9uKHQsZSl7aWYoZ28uaGFzT3duUHJvcGVydHkoZSkpe3ZhciByPWdvW2VdLG49dGhpcy5nZXRNb2RlQXQodCk7cmV0dXJuIG5bZV0mJnJbbltlXV18fG4uaGVscGVyVHlwZSYmcltuLmhlbHBlclR5cGVdfHxyW24ubmFtZV19fSxnZXRTdGF0ZUFmdGVyOmZ1bmN0aW9uKHQsZSl7dmFyIHI9dGhpcy5kb2M7cmV0dXJuIHQ9cWUocixudWxsPT10P3IuZmlyc3Qrci5zaXplLTE6dCkseih0aGlzLHQrMSxlKX0sY3Vyc29yQ29vcmRzOmZ1bmN0aW9uKHQsZSl7dmFyIHIsbj10aGlzLmRvYy5zZWw7cmV0dXJuIHI9bnVsbD09dD9uLmhlYWQ6Im9iamVjdCI9PXR5cGVvZiB0P1FlKHRoaXMuZG9jLHQpOnQ/bi5mcm9tOm4udG8sUSh0aGlzLHIsZXx8InBhZ2UiKX0sY2hhckNvb3JkczpmdW5jdGlvbih0LGUpe3JldHVybiBxKHRoaXMsUWUodGhpcy5kb2MsdCksZXx8InBhZ2UiKX0sY29vcmRzQ2hhcjpmdW5jdGlvbih0LGUpe3JldHVybiB0PVoodGhpcyx0LGV8fCJwYWdlIiksdGUodGhpcyx0LmxlZnQsdC50b3ApfSxsaW5lQXRIZWlnaHQ6ZnVuY3Rpb24odCxlKXtyZXR1cm4gdD1aKHRoaXMse3RvcDp0LGxlZnQ6MH0sZXx8InBhZ2UiKS50b3AseG4odGhpcy5kb2MsdCt0aGlzLmRpc3BsYXkudmlld09mZnNldCl9LGhlaWdodEF0TGluZTpmdW5jdGlvbih0LGUpe3ZhciByPSExLG49dGhpcy5kb2MuZmlyc3QrdGhpcy5kb2Muc2l6ZS0xO3Q8dGhpcy5kb2MuZmlyc3Q/dD10aGlzLmRvYy5maXJzdDp0Pm4mJih0PW4scj0hMCk7dmFyIGk9Z24odGhpcy5kb2MsdCk7cmV0dXJuICQodGhpcyxnbih0aGlzLmRvYyx0KSx7dG9wOjAsbGVmdDowfSxlfHwicGFnZSIpLnRvcCsocj9pLmhlaWdodDowKX0sZGVmYXVsdFRleHRIZWlnaHQ6ZnVuY3Rpb24oKXtyZXR1cm4gcmUodGhpcy5kaXNwbGF5KX0sZGVmYXVsdENoYXJXaWR0aDpmdW5jdGlvbigpe3JldHVybiBuZSh0aGlzLmRpc3BsYXkpfSxzZXRHdXR0ZXJNYXJrZXI6bGUobnVsbCxmdW5jdGlvbih0LGUscil7cmV0dXJuIGRyKHRoaXMsdCxmdW5jdGlvbih0KXt2YXIgbj10Lmd1dHRlck1hcmtlcnN8fCh0Lmd1dHRlck1hcmtlcnM9e30pO3JldHVybiBuW2VdPXIsIXImJmxpKG4pJiYodC5ndXR0ZXJNYXJrZXJzPW51bGwpLCEwfSl9KSxjbGVhckd1dHRlcjpsZShudWxsLGZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMscj1lLmRvYyxuPXIuZmlyc3Q7ci5pdGVyKGZ1bmN0aW9uKHIpe3IuZ3V0dGVyTWFya2VycyYmci5ndXR0ZXJNYXJrZXJzW3RdJiYoci5ndXR0ZXJNYXJrZXJzW3RdPW51bGwsdWUoZSxuLG4rMSksbGkoci5ndXR0ZXJNYXJrZXJzKSYmKHIuZ3V0dGVyTWFya2Vycz1udWxsKSksKytufSl9KSxhZGRMaW5lQ2xhc3M6bGUobnVsbCxmdW5jdGlvbih0LGUscil7cmV0dXJuIGRyKHRoaXMsdCxmdW5jdGlvbih0KXt2YXIgbj0idGV4dCI9PWU/InRleHRDbGFzcyI6ImJhY2tncm91bmQiPT1lPyJiZ0NsYXNzIjoid3JhcENsYXNzIjtpZih0W25dKXtpZihuZXcgUmVnRXhwKCIoPzpefFxccykiK3IrIig/OiR8XFxzKSIpLnRlc3QodFtuXSkpcmV0dXJuITE7dFtuXSs9IiAiK3J9ZWxzZSB0W25dPXI7cmV0dXJuITB9KX0pLHJlbW92ZUxpbmVDbGFzczpsZShudWxsLGZ1bmN0aW9uKHQsZSxyKXtyZXR1cm4gZHIodGhpcyx0LGZ1bmN0aW9uKHQpe3ZhciBuPSJ0ZXh0Ij09ZT8idGV4dENsYXNzIjoiYmFja2dyb3VuZCI9PWU/ImJnQ2xhc3MiOiJ3cmFwQ2xhc3MiLGk9dFtuXTtpZighaSlyZXR1cm4hMTtpZihudWxsPT1yKXRbbl09bnVsbDtlbHNle3ZhciBvPWkubWF0Y2gobmV3IFJlZ0V4cCgiKD86XnxcXHMrKSIrcisiKD86JHxcXHMrKSIpKTtpZighbylyZXR1cm4hMTt2YXIgbD1vLmluZGV4K29bMF0ubGVuZ3RoO3Rbbl09aS5zbGljZSgwLG8uaW5kZXgpKyhvLmluZGV4JiZsIT1pLmxlbmd0aD8iICI6IiIpK2kuc2xpY2UobCl8fG51bGx9cmV0dXJuITB9KX0pLGFkZExpbmVXaWRnZXQ6bGUobnVsbCxmdW5jdGlvbih0LGUscil7cmV0dXJuIGpyKHRoaXMsdCxlLHIpfSkscmVtb3ZlTGluZVdpZGdldDpmdW5jdGlvbih0KXt0LmNsZWFyKCl9LGxpbmVJbmZvOmZ1bmN0aW9uKHQpe2lmKCJudW1iZXIiPT10eXBlb2YgdCl7aWYoIXRyKHRoaXMuZG9jLHQpKXJldHVybiBudWxsO3ZhciBlPXQ7aWYodD1nbih0aGlzLmRvYyx0KSwhdClyZXR1cm4gbnVsbH1lbHNle3ZhciBlPWJuKHQpO2lmKG51bGw9PWUpcmV0dXJuIG51bGx9cmV0dXJue2xpbmU6ZSxoYW5kbGU6dCx0ZXh0OnQudGV4dCxndXR0ZXJNYXJrZXJzOnQuZ3V0dGVyTWFya2Vycyx0ZXh0Q2xhc3M6dC50ZXh0Q2xhc3MsYmdDbGFzczp0LmJnQ2xhc3Msd3JhcENsYXNzOnQud3JhcENsYXNzLHdpZGdldHM6dC53aWRnZXRzfX0sZ2V0Vmlld3BvcnQ6ZnVuY3Rpb24oKXtyZXR1cm57ZnJvbTp0aGlzLmRpc3BsYXkuc2hvd2luZ0Zyb20sdG86dGhpcy5kaXNwbGF5LnNob3dpbmdUb319LGFkZFdpZGdldDpmdW5jdGlvbih0LGUscixuLGkpe3ZhciBvPXRoaXMuZGlzcGxheTt0PVEodGhpcyxRZSh0aGlzLmRvYyx0KSk7dmFyIGw9dC5ib3R0b20scz10LmxlZnQ7aWYoZS5zdHlsZS5wb3NpdGlvbj0iYWJzb2x1dGUiLG8uc2l6ZXIuYXBwZW5kQ2hpbGQoZSksIm92ZXIiPT1uKWw9dC50b3A7ZWxzZSBpZigiYWJvdmUiPT1ufHwibmVhciI9PW4pe3ZhciBhPU1hdGgubWF4KG8ud3JhcHBlci5jbGllbnRIZWlnaHQsdGhpcy5kb2MuaGVpZ2h0KSx1PU1hdGgubWF4KG8uc2l6ZXIuY2xpZW50V2lkdGgsby5saW5lU3BhY2UuY2xpZW50V2lkdGgpOygiYWJvdmUiPT1ufHx0LmJvdHRvbStlLm9mZnNldEhlaWdodD5hKSYmdC50b3A+ZS5vZmZzZXRIZWlnaHQ/bD10LnRvcC1lLm9mZnNldEhlaWdodDp0LmJvdHRvbStlLm9mZnNldEhlaWdodDw9YSYmKGw9dC5ib3R0b20pLHMrZS5vZmZzZXRXaWR0aD51JiYocz11LWUub2Zmc2V0V2lkdGgpfWUuc3R5bGUudG9wPWwrInB4IixlLnN0eWxlLmxlZnQ9ZS5zdHlsZS5yaWdodD0iIiwicmlnaHQiPT1pPyhzPW8uc2l6ZXIuY2xpZW50V2lkdGgtZS5vZmZzZXRXaWR0aCxlLnN0eWxlLnJpZ2h0PSIwcHgiKTooImxlZnQiPT1pP3M9MDoibWlkZGxlIj09aSYmKHM9KG8uc2l6ZXIuY2xpZW50V2lkdGgtZS5vZmZzZXRXaWR0aCkvMiksZS5zdHlsZS5sZWZ0PXMrInB4IiksciYmYXIodGhpcyxzLGwscytlLm9mZnNldFdpZHRoLGwrZS5vZmZzZXRIZWlnaHQpfSx0cmlnZ2VyT25LZXlEb3duOmxlKG51bGwsV2UpLGV4ZWNDb21tYW5kOmZ1bmN0aW9uKHQpe3JldHVybiBtb1t0XSh0aGlzKX0sZmluZFBvc0g6ZnVuY3Rpb24odCxlLHIsbil7dmFyIGk9MTswPmUmJihpPS0xLGU9LWUpO2Zvcih2YXIgbz0wLGw9UWUodGhpcy5kb2MsdCk7ZT5vJiYobD1wcih0aGlzLmRvYyxsLGkscixuKSwhbC5oaXRTaWRlKTsrK28pO3JldHVybiBsfSxtb3ZlSDpsZShudWxsLGZ1bmN0aW9uKHQsZSl7dmFyIHIsbj10aGlzLmRvYy5zZWw7cj1uLnNoaWZ0fHxuLmV4dGVuZHx8amUobi5mcm9tLG4udG8pP3ByKHRoaXMuZG9jLG4uaGVhZCx0LGUsdGhpcy5vcHRpb25zLnJ0bE1vdmVWaXN1YWxseSk6MD50P24uZnJvbTpuLnRvLGVyKHRoaXMuZG9jLHIscix0KX0pLGRlbGV0ZUg6bGUobnVsbCxmdW5jdGlvbih0LGUpe3ZhciByPXRoaXMuZG9jLnNlbDtqZShyLmZyb20sci50byk/X2UodGhpcy5kb2MsIiIsci5mcm9tLHByKHRoaXMuZG9jLHIuaGVhZCx0LGUsITEpLCIrZGVsZXRlIik6X2UodGhpcy5kb2MsIiIsci5mcm9tLHIudG8sIitkZWxldGUiKSx0aGlzLmN1ck9wLnVzZXJTZWxDaGFuZ2U9ITB9KSxmaW5kUG9zVjpmdW5jdGlvbih0LGUscixuKXt2YXIgaT0xLG89bjswPmUmJihpPS0xLGU9LWUpO2Zvcih2YXIgbD0wLHM9UWUodGhpcy5kb2MsdCk7ZT5sOysrbCl7dmFyIGE9USh0aGlzLHMsImRpdiIpO2lmKG51bGw9PW8/bz1hLmxlZnQ6YS5sZWZ0PW8scz1ncih0aGlzLGEsaSxyKSxzLmhpdFNpZGUpYnJlYWt9cmV0dXJuIHN9LG1vdmVWOmxlKG51bGwsZnVuY3Rpb24odCxlKXt2YXIgcj10aGlzLmRvYy5zZWwsbj1RKHRoaXMsci5oZWFkLCJkaXYiKTtudWxsIT1yLmdvYWxDb2x1bW4mJihuLmxlZnQ9ci5nb2FsQ29sdW1uKTt2YXIgaT1ncih0aGlzLG4sdCxlKTsicGFnZSI9PWUmJmZyKHRoaXMsMCxxKHRoaXMsaSwiZGl2IikudG9wLW4udG9wKSxlcih0aGlzLmRvYyxpLGksdCksci5nb2FsQ29sdW1uPW4ubGVmdH0pLHRvZ2dsZU92ZXJ3cml0ZTpmdW5jdGlvbih0KXsobnVsbD09dHx8dCE9dGhpcy5zdGF0ZS5vdmVyd3JpdGUpJiYoKHRoaXMuc3RhdGUub3ZlcndyaXRlPSF0aGlzLnN0YXRlLm92ZXJ3cml0ZSk/dGhpcy5kaXNwbGF5LmN1cnNvci5jbGFzc05hbWUrPSIgQ29kZU1pcnJvci1vdmVyd3JpdGUiOnRoaXMuZGlzcGxheS5jdXJzb3IuY2xhc3NOYW1lPXRoaXMuZGlzcGxheS5jdXJzb3IuY2xhc3NOYW1lLnJlcGxhY2UoIiBDb2RlTWlycm9yLW92ZXJ3cml0ZSIsIiIpKX0saGFzRm9jdXM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zdGF0ZS5mb2N1c2VkfSxzY3JvbGxUbzpsZShudWxsLGZ1bmN0aW9uKHQsZSl7Y3IodGhpcyx0LGUpfSksZ2V0U2Nyb2xsSW5mbzpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZGlzcGxheS5zY3JvbGxlcixlPVRvO3JldHVybntsZWZ0OnQuc2Nyb2xsTGVmdCx0b3A6dC5zY3JvbGxUb3AsaGVpZ2h0OnQuc2Nyb2xsSGVpZ2h0LWUsd2lkdGg6dC5zY3JvbGxXaWR0aC1lLGNsaWVudEhlaWdodDp0LmNsaWVudEhlaWdodC1lLGNsaWVudFdpZHRoOnQuY2xpZW50V2lkdGgtZX19LHNjcm9sbEludG9WaWV3OmxlKG51bGwsZnVuY3Rpb24odCxlKXtudWxsPT10P3Q9e2Zyb206dGhpcy5kb2Muc2VsLmhlYWQsdG86bnVsbH06Im51bWJlciI9PXR5cGVvZiB0P3Q9e2Zyb206WWUodCwwKSx0bzpudWxsfTpudWxsPT10LmZyb20mJih0PXtmcm9tOnQsdG86bnVsbH0pLHQudG98fCh0LnRvPXQuZnJvbSksZXx8KGU9MCk7dmFyIHI9dDtudWxsIT10LmZyb20ubGluZSYmKHRoaXMuY3VyT3Auc2Nyb2xsVG9Qb3M9e2Zyb206dC5mcm9tLHRvOnQudG8sbWFyZ2luOmV9LHI9e2Zyb206USh0aGlzLHQuZnJvbSksdG86USh0aGlzLHQudG8pfSk7dmFyIG49dXIodGhpcyxNYXRoLm1pbihyLmZyb20ubGVmdCxyLnRvLmxlZnQpLE1hdGgubWluKHIuZnJvbS50b3Asci50by50b3ApLWUsTWF0aC5tYXgoci5mcm9tLnJpZ2h0LHIudG8ucmlnaHQpLE1hdGgubWF4KHIuZnJvbS5ib3R0b20sci50by5ib3R0b20pK2UpO2NyKHRoaXMsbi5zY3JvbGxMZWZ0LG4uc2Nyb2xsVG9wKX0pLHNldFNpemU6bGUobnVsbCxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIHIodCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0fHwvXlxkKyQvLnRlc3QoU3RyaW5nKHQpKT90KyJweCI6dH1udWxsIT10JiYodGhpcy5kaXNwbGF5LndyYXBwZXIuc3R5bGUud2lkdGg9cih0KSksbnVsbCE9ZSYmKHRoaXMuZGlzcGxheS53cmFwcGVyLnN0eWxlLmhlaWdodD1yKGUpKSx0aGlzLm9wdGlvbnMubGluZVdyYXBwaW5nJiYodGhpcy5kaXNwbGF5Lm1lYXN1cmVMaW5lQ2FjaGUubGVuZ3RoPXRoaXMuZGlzcGxheS5tZWFzdXJlTGluZUNhY2hlUG9zPTApLHRoaXMuY3VyT3AuZm9yY2VVcGRhdGU9ITB9KSxvcGVyYXRpb246ZnVuY3Rpb24odCl7cmV0dXJuIGFlKHRoaXMsdCl9LHJlZnJlc2g6bGUobnVsbCxmdW5jdGlvbigpe3ZhciB0PW51bGw9PXRoaXMuZGlzcGxheS5jYWNoZWRUZXh0SGVpZ2h0O18odGhpcyksY3IodGhpcyx0aGlzLmRvYy5zY3JvbGxMZWZ0LHRoaXMuZG9jLnNjcm9sbFRvcCksdWUodGhpcyksdCYmbyh0aGlzKX0pLHN3YXBEb2M6bGUobnVsbCxmdW5jdGlvbih0KXt2YXIgZT10aGlzLmRvYztyZXR1cm4gZS5jbT1udWxsLHBuKHRoaXMsdCksXyh0aGlzKSxkZSh0aGlzLCEwKSxjcih0aGlzLHQuc2Nyb2xsTGVmdCx0LnNjcm9sbFRvcCksVW4odGhpcywic3dhcERvYyIsdGhpcyxlKSxlfSksZ2V0SW5wdXRGaWVsZDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmRpc3BsYXkuaW5wdXR9LGdldFdyYXBwZXJFbGVtZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGlzcGxheS53cmFwcGVyfSxnZXRTY3JvbGxlckVsZW1lbnQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kaXNwbGF5LnNjcm9sbGVyfSxnZXRHdXR0ZXJFbGVtZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGlzcGxheS5ndXR0ZXJzfX0sam4odCk7dmFyIHNvPXQub3B0aW9uSGFuZGxlcnM9e30sYW89dC5kZWZhdWx0cz17fSx1bz10LkluaXQ9e3RvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIkNvZGVNaXJyb3IuSW5pdCJ9fTt5cigidmFsdWUiLCIiLGZ1bmN0aW9uKHQsZSl7dC5zZXRWYWx1ZShlKX0sITApLHlyKCJtb2RlIixudWxsLGZ1bmN0aW9uKHQsZSl7dC5kb2MubW9kZU9wdGlvbj1lLHIodCl9LCEwKSx5cigiaW5kZW50VW5pdCIsMixyLCEwKSx5cigiaW5kZW50V2l0aFRhYnMiLCExKSx5cigic21hcnRJbmRlbnQiLCEwKSx5cigidGFiU2l6ZSIsNCxmdW5jdGlvbih0KXtyKHQpLF8odCksdWUodCl9LCEwKSx5cigic3BlY2lhbENoYXJzIiwvW1x0XHUwMDAwLVx1MDAxOVx1MDBhZFx1MjAwYlx1MjAyOFx1MjAyOVx1ZmVmZl0vZyxmdW5jdGlvbih0LGUpe3Qub3B0aW9ucy5zcGVjaWFsQ2hhcnM9bmV3IFJlZ0V4cChlLnNvdXJjZSsoZS50ZXN0KCIJIik/IiI6InwJIiksImciKSx0LnJlZnJlc2goKX0sITApLHlyKCJzcGVjaWFsQ2hhclBsYWNlaG9sZGVyIixubixmdW5jdGlvbih0KXt0LnJlZnJlc2goKX0sITApLHlyKCJlbGVjdHJpY0NoYXJzIiwhMCkseXIoInJ0bE1vdmVWaXN1YWxseSIsIVVpKSx5cigid2hvbGVMaW5lVXBkYXRlQmVmb3JlIiwhMCkseXIoInRoZW1lIiwiZGVmYXVsdCIsZnVuY3Rpb24odCl7cyh0KSxhKHQpfSwhMCkseXIoImtleU1hcCIsImRlZmF1bHQiLGwpLHlyKCJleHRyYUtleXMiLG51bGwpLHlyKCJvbktleUV2ZW50IixudWxsKSx5cigib25EcmFnRXZlbnQiLG51bGwpLHlyKCJsaW5lV3JhcHBpbmciLCExLG4sITApLHlyKCJndXR0ZXJzIixbXSxmdW5jdGlvbih0KXtoKHQub3B0aW9ucyksYSh0KX0sITApLHlyKCJmaXhlZEd1dHRlciIsITAsZnVuY3Rpb24odCxlKXt0LmRpc3BsYXkuZ3V0dGVycy5zdHlsZS5sZWZ0PWU/eSh0LmRpc3BsYXkpKyJweCI6IjAiLHQucmVmcmVzaCgpfSwhMCkseXIoImNvdmVyR3V0dGVyTmV4dFRvU2Nyb2xsYmFyIiwhMSxkLCEwKSx5cigibGluZU51bWJlcnMiLCExLGZ1bmN0aW9uKHQpe2godC5vcHRpb25zKSxhKHQpfSwhMCkseXIoImZpcnN0TGluZU51bWJlciIsMSxhLCEwKSx5cigibGluZU51bWJlckZvcm1hdHRlciIsZnVuY3Rpb24odCl7cmV0dXJuIHR9LGEsITApLHlyKCJzaG93Q3Vyc29yV2hlblNlbGVjdGluZyIsITEsQSwhMCkseXIoInJlc2V0U2VsZWN0aW9uT25Db250ZXh0TWVudSIsITApLHlyKCJyZWFkT25seSIsITEsZnVuY3Rpb24odCxlKXsibm9jdXJzb3IiPT1lPyh6ZSh0KSx0LmRpc3BsYXkuaW5wdXQuYmx1cigpLHQuZGlzcGxheS5kaXNhYmxlZD0hMCk6KHQuZGlzcGxheS5kaXNhYmxlZD0hMSxlfHxkZSh0LCEwKSl9KSx5cigiZHJhZ0Ryb3AiLCEwKSx5cigiY3Vyc29yQmxpbmtSYXRlIiw1MzApLHlyKCJjdXJzb3JTY3JvbGxNYXJnaW4iLDApLHlyKCJjdXJzb3JIZWlnaHQiLDEpLHlyKCJ3b3JrVGltZSIsMTAwKSx5cigid29ya0RlbGF5IiwxMDApLHlyKCJmbGF0dGVuU3BhbnMiLCEwKSx5cigicG9sbEludGVydmFsIiwxMDApLHlyKCJ1bmRvRGVwdGgiLDQwLGZ1bmN0aW9uKHQsZSl7dC5kb2MuaGlzdG9yeS51bmRvRGVwdGg9ZX0pLHlyKCJoaXN0b3J5RXZlbnREZWxheSIsNTAwKSx5cigidmlld3BvcnRNYXJnaW4iLDEwLGZ1bmN0aW9uKHQpe3QucmVmcmVzaCgpfSwhMCkseXIoIm1heEhpZ2hsaWdodExlbmd0aCIsMWU0LGZ1bmN0aW9uKHQpe3IodCksdC5yZWZyZXNoKCl9LCEwKSx5cigiY3J1ZGVNZWFzdXJpbmdGcm9tIiwxZTQpLHlyKCJtb3ZlSW5wdXRXaXRoQ3Vyc29yIiwhMCxmdW5jdGlvbih0LGUpe2V8fCh0LmRpc3BsYXkuaW5wdXREaXYuc3R5bGUudG9wPXQuZGlzcGxheS5pbnB1dERpdi5zdHlsZS5sZWZ0PTApfSkseXIoInRhYmluZGV4IixudWxsLGZ1bmN0aW9uKHQsZSl7dC5kaXNwbGF5LmlucHV0LnRhYkluZGV4PWV8fCIifSkseXIoImF1dG9mb2N1cyIsbnVsbCk7dmFyIGNvPXQubW9kZXM9e30sZm89dC5taW1lTW9kZXM9e307dC5kZWZpbmVNb2RlPWZ1bmN0aW9uKGUscil7aWYodC5kZWZhdWx0cy5tb2RlfHwibnVsbCI9PWV8fCh0LmRlZmF1bHRzLm1vZGU9ZSksYXJndW1lbnRzLmxlbmd0aD4yKXtyLmRlcGVuZGVuY2llcz1bXTtmb3IodmFyIG49MjtuPGFyZ3VtZW50cy5sZW5ndGg7KytuKXIuZGVwZW5kZW5jaWVzLnB1c2goYXJndW1lbnRzW25dKX1jb1tlXT1yfSx0LmRlZmluZU1JTUU9ZnVuY3Rpb24odCxlKXtmb1t0XT1lfSx0LnJlc29sdmVNb2RlPWZ1bmN0aW9uKGUpe2lmKCJzdHJpbmciPT10eXBlb2YgZSYmZm8uaGFzT3duUHJvcGVydHkoZSkpZT1mb1tlXTtlbHNlIGlmKGUmJiJzdHJpbmciPT10eXBlb2YgZS5uYW1lJiZmby5oYXNPd25Qcm9wZXJ0eShlLm5hbWUpKXt2YXIgcj1mb1tlLm5hbWVdO2U9ZWkocixlKSxlLm5hbWU9ci5uYW1lfWVsc2UgaWYoInN0cmluZyI9PXR5cGVvZiBlJiYvXltcd1wtXStcL1tcd1wtXStcK3htbCQvLnRlc3QoZSkpcmV0dXJuIHQucmVzb2x2ZU1vZGUoImFwcGxpY2F0aW9uL3htbCIpO3JldHVybiJzdHJpbmciPT10eXBlb2YgZT97bmFtZTplfTplfHx7bmFtZToibnVsbCJ9fSx0LmdldE1vZGU9ZnVuY3Rpb24oZSxyKXt2YXIgcj10LnJlc29sdmVNb2RlKHIpLG49Y29bci5uYW1lXTtpZighbilyZXR1cm4gdC5nZXRNb2RlKGUsInRleHQvcGxhaW4iKTt2YXIgaT1uKGUscik7aWYoaG8uaGFzT3duUHJvcGVydHkoci5uYW1lKSl7dmFyIG89aG9bci5uYW1lXTtmb3IodmFyIGwgaW4gbylvLmhhc093blByb3BlcnR5KGwpJiYoaS5oYXNPd25Qcm9wZXJ0eShsKSYmKGlbIl8iK2xdPWlbbF0pLGlbbF09b1tsXSl9cmV0dXJuIGkubmFtZT1yLm5hbWUsaX0sdC5kZWZpbmVNb2RlKCJudWxsIixmdW5jdGlvbigpe3JldHVybnt0b2tlbjpmdW5jdGlvbih0KXt0LnNraXBUb0VuZCgpfX19KSx0LmRlZmluZU1JTUUoInRleHQvcGxhaW4iLCJudWxsIik7dmFyIGhvPXQubW9kZUV4dGVuc2lvbnM9e307dC5leHRlbmRNb2RlPWZ1bmN0aW9uKHQsZSl7dmFyIHI9aG8uaGFzT3duUHJvcGVydHkodCk/aG9bdF06aG9bdF09e307cmkoZSxyKX0sdC5kZWZpbmVFeHRlbnNpb249ZnVuY3Rpb24oZSxyKXt0LnByb3RvdHlwZVtlXT1yfSx0LmRlZmluZURvY0V4dGVuc2lvbj1mdW5jdGlvbih0LGUpe3dvLnByb3RvdHlwZVt0XT1lfSx0LmRlZmluZU9wdGlvbj15cjt2YXIgcG89W107dC5kZWZpbmVJbml0SG9vaz1mdW5jdGlvbih0KXtwby5wdXNoKHQpfTt2YXIgZ289dC5oZWxwZXJzPXt9O3QucmVnaXN0ZXJIZWxwZXI9ZnVuY3Rpb24oZSxyLG4pe2dvLmhhc093blByb3BlcnR5KGUpfHwoZ29bZV09dFtlXT17fSksZ29bZV1bcl09bn0sdC5pc1dvcmRDaGFyPW9pLHQuY29weVN0YXRlPWJyLHQuc3RhcnRTdGF0ZT14cix0LmlubmVyTW9kZT1mdW5jdGlvbih0LGUpe2Zvcig7dC5pbm5lck1vZGU7KXt2YXIgcj10LmlubmVyTW9kZShlKTtpZighcnx8ci5tb2RlPT10KWJyZWFrO2U9ci5zdGF0ZSx0PXIubW9kZX1yZXR1cm4gcnx8e21vZGU6dCxzdGF0ZTplfX07dmFyIG1vPXQuY29tbWFuZHM9e3NlbGVjdEFsbDpmdW5jdGlvbih0KXt0LnNldFNlbGVjdGlvbihZZSh0LmZpcnN0TGluZSgpLDApLFllKHQubGFzdExpbmUoKSkpfSxraWxsTGluZTpmdW5jdGlvbih0KXt2YXIgZT10LmdldEN1cnNvcighMCkscj10LmdldEN1cnNvcighMSksbj0hamUoZSxyKTtufHx0LmdldExpbmUoZS5saW5lKS5sZW5ndGghPWUuY2g/dC5yZXBsYWNlUmFuZ2UoIiIsZSxuP3I6WWUoZS5saW5lKSwiK2RlbGV0ZSIpOnQucmVwbGFjZVJhbmdlKCIiLGUsWWUoZS5saW5lKzEsMCksIitkZWxldGUiKX0sZGVsZXRlTGluZTpmdW5jdGlvbih0KXt2YXIgZT10LmdldEN1cnNvcigpLmxpbmU7dC5yZXBsYWNlUmFuZ2UoIiIsWWUoZSwwKSxZZShlKSwiK2RlbGV0ZSIpfSxkZWxMaW5lTGVmdDpmdW5jdGlvbih0KXt2YXIgZT10LmdldEN1cnNvcigpO3QucmVwbGFjZVJhbmdlKCIiLFllKGUubGluZSwwKSxlLCIrZGVsZXRlIil9LHVuZG86ZnVuY3Rpb24odCl7dC51bmRvKCl9LHJlZG86ZnVuY3Rpb24odCl7dC5yZWRvKCl9LGdvRG9jU3RhcnQ6ZnVuY3Rpb24odCl7dC5leHRlbmRTZWxlY3Rpb24oWWUodC5maXJzdExpbmUoKSwwKSl9LGdvRG9jRW5kOmZ1bmN0aW9uKHQpe3QuZXh0ZW5kU2VsZWN0aW9uKFllKHQubGFzdExpbmUoKSkpfSxnb0xpbmVTdGFydDpmdW5jdGlvbih0KXt0LmV4dGVuZFNlbGVjdGlvbih4aSh0LHQuZ2V0Q3Vyc29yKCkubGluZSkpfSxnb0xpbmVTdGFydFNtYXJ0OmZ1bmN0aW9uKHQpe3ZhciBlPXQuZ2V0Q3Vyc29yKCkscj14aSh0LGUubGluZSksbj10LmdldExpbmVIYW5kbGUoci5saW5lKSxpPXduKG4pO2lmKGkmJjAhPWlbMF0ubGV2ZWwpdC5leHRlbmRTZWxlY3Rpb24ocik7ZWxzZXt2YXIgbz1NYXRoLm1heCgwLG4udGV4dC5zZWFyY2goL1xTLykpLGw9ZS5saW5lPT1yLmxpbmUmJmUuY2g8PW8mJmUuY2g7dC5leHRlbmRTZWxlY3Rpb24oWWUoci5saW5lLGw/MDpvKSl9fSxnb0xpbmVFbmQ6ZnVuY3Rpb24odCl7dC5leHRlbmRTZWxlY3Rpb24oQ2kodCx0LmdldEN1cnNvcigpLmxpbmUpKX0sZ29MaW5lUmlnaHQ6ZnVuY3Rpb24odCl7dmFyIGU9dC5jaGFyQ29vcmRzKHQuZ2V0Q3Vyc29yKCksImRpdiIpLnRvcCs1O3QuZXh0ZW5kU2VsZWN0aW9uKHQuY29vcmRzQ2hhcih7bGVmdDp0LmRpc3BsYXkubGluZURpdi5vZmZzZXRXaWR0aCsxMDAsdG9wOmV9LCJkaXYiKSl9LGdvTGluZUxlZnQ6ZnVuY3Rpb24odCl7dmFyIGU9dC5jaGFyQ29vcmRzKHQuZ2V0Q3Vyc29yKCksImRpdiIpLnRvcCs1O3QuZXh0ZW5kU2VsZWN0aW9uKHQuY29vcmRzQ2hhcih7bGVmdDowLHRvcDplfSwiZGl2IikpfSxnb0xpbmVVcDpmdW5jdGlvbih0KXt0Lm1vdmVWKC0xLCJsaW5lIil9LGdvTGluZURvd246ZnVuY3Rpb24odCl7dC5tb3ZlVigxLCJsaW5lIil9LGdvUGFnZVVwOmZ1bmN0aW9uKHQpe3QubW92ZVYoLTEsInBhZ2UiKX0sZ29QYWdlRG93bjpmdW5jdGlvbih0KXt0Lm1vdmVWKDEsInBhZ2UiKX0sZ29DaGFyTGVmdDpmdW5jdGlvbih0KXt0Lm1vdmVIKC0xLCJjaGFyIil9LGdvQ2hhclJpZ2h0OmZ1bmN0aW9uKHQpe3QubW92ZUgoMSwiY2hhciIpfSxnb0NvbHVtbkxlZnQ6ZnVuY3Rpb24odCl7dC5tb3ZlSCgtMSwiY29sdW1uIil9LGdvQ29sdW1uUmlnaHQ6ZnVuY3Rpb24odCl7dC5tb3ZlSCgxLCJjb2x1bW4iKX0sZ29Xb3JkTGVmdDpmdW5jdGlvbih0KXt0Lm1vdmVIKC0xLCJ3b3JkIil9LGdvR3JvdXBSaWdodDpmdW5jdGlvbih0KXt0Lm1vdmVIKDEsImdyb3VwIil9LGdvR3JvdXBMZWZ0OmZ1bmN0aW9uKHQpe3QubW92ZUgoLTEsImdyb3VwIil9LGdvV29yZFJpZ2h0OmZ1bmN0aW9uKHQpe3QubW92ZUgoMSwid29yZCIpfSxkZWxDaGFyQmVmb3JlOmZ1bmN0aW9uKHQpe3QuZGVsZXRlSCgtMSwiY2hhciIpfSxkZWxDaGFyQWZ0ZXI6ZnVuY3Rpb24odCl7dC5kZWxldGVIKDEsImNoYXIiKX0sZGVsV29yZEJlZm9yZTpmdW5jdGlvbih0KXt0LmRlbGV0ZUgoLTEsIndvcmQiKX0sZGVsV29yZEFmdGVyOmZ1bmN0aW9uKHQpe3QuZGVsZXRlSCgxLCJ3b3JkIil9LGRlbEdyb3VwQmVmb3JlOmZ1bmN0aW9uKHQpe3QuZGVsZXRlSCgtMSwiZ3JvdXAiKX0sZGVsR3JvdXBBZnRlcjpmdW5jdGlvbih0KXt0LmRlbGV0ZUgoMSwiZ3JvdXAiKX0saW5kZW50QXV0bzpmdW5jdGlvbih0KXt0LmluZGVudFNlbGVjdGlvbigic21hcnQiKX0saW5kZW50TW9yZTpmdW5jdGlvbih0KXt0LmluZGVudFNlbGVjdGlvbigiYWRkIil9LGluZGVudExlc3M6ZnVuY3Rpb24odCl7dC5pbmRlbnRTZWxlY3Rpb24oInN1YnRyYWN0Iil9LGluc2VydFRhYjpmdW5jdGlvbih0KXt0LnJlcGxhY2VTZWxlY3Rpb24oIgkiLCJlbmQiLCIraW5wdXQiKX0sZGVmYXVsdFRhYjpmdW5jdGlvbih0KXt0LnNvbWV0aGluZ1NlbGVjdGVkKCk/dC5pbmRlbnRTZWxlY3Rpb24oImFkZCIpOnQucmVwbGFjZVNlbGVjdGlvbigiCSIsImVuZCIsIitpbnB1dCIpfSx0cmFuc3Bvc2VDaGFyczpmdW5jdGlvbih0KXt2YXIgZT10LmdldEN1cnNvcigpLHI9dC5nZXRMaW5lKGUubGluZSk7ZS5jaD4wJiZlLmNoPHIubGVuZ3RoLTEmJnQucmVwbGFjZVJhbmdlKHIuY2hhckF0KGUuY2gpK3IuY2hhckF0KGUuY2gtMSksWWUoZS5saW5lLGUuY2gtMSksWWUoZS5saW5lLGUuY2grMSkpfSxuZXdsaW5lQW5kSW5kZW50OmZ1bmN0aW9uKHQpe2xlKHQsZnVuY3Rpb24oKXt0LnJlcGxhY2VTZWxlY3Rpb24oIlxuIiwiZW5kIiwiK2lucHV0IiksdC5pbmRlbnRMaW5lKHQuZ2V0Q3Vyc29yKCkubGluZSxudWxsLCEwKX0pKCl9LHRvZ2dsZU92ZXJ3cml0ZTpmdW5jdGlvbih0KXt0LnRvZ2dsZU92ZXJ3cml0ZSgpfX0sdm89dC5rZXlNYXA9e307dm8uYmFzaWM9e0xlZnQ6ImdvQ2hhckxlZnQiLFJpZ2h0OiJnb0NoYXJSaWdodCIsVXA6ImdvTGluZVVwIixEb3duOiJnb0xpbmVEb3duIixFbmQ6ImdvTGluZUVuZCIsSG9tZToiZ29MaW5lU3RhcnRTbWFydCIsUGFnZVVwOiJnb1BhZ2VVcCIsUGFnZURvd246ImdvUGFnZURvd24iLERlbGV0ZToiZGVsQ2hhckFmdGVyIixCYWNrc3BhY2U6ImRlbENoYXJCZWZvcmUiLCJTaGlmdC1CYWNrc3BhY2UiOiJkZWxDaGFyQmVmb3JlIixUYWI6ImRlZmF1bHRUYWIiLCJTaGlmdC1UYWIiOiJpbmRlbnRBdXRvIixFbnRlcjoibmV3bGluZUFuZEluZGVudCIsSW5zZXJ0OiJ0b2dnbGVPdmVyd3JpdGUifSx2by5wY0RlZmF1bHQ9eyJDdHJsLUEiOiJzZWxlY3RBbGwiLCJDdHJsLUQiOiJkZWxldGVMaW5lIiwiQ3RybC1aIjoidW5kbyIsIlNoaWZ0LUN0cmwtWiI6InJlZG8iLCJDdHJsLVkiOiJyZWRvIiwiQ3RybC1Ib21lIjoiZ29Eb2NTdGFydCIsIkFsdC1VcCI6ImdvRG9jU3RhcnQiLCJDdHJsLUVuZCI6ImdvRG9jRW5kIiwiQ3RybC1Eb3duIjoiZ29Eb2NFbmQiLCJDdHJsLUxlZnQiOiJnb0dyb3VwTGVmdCIsIkN0cmwtUmlnaHQiOiJnb0dyb3VwUmlnaHQiLCJBbHQtTGVmdCI6ImdvTGluZVN0YXJ0IiwiQWx0LVJpZ2h0IjoiZ29MaW5lRW5kIiwiQ3RybC1CYWNrc3BhY2UiOiJkZWxHcm91cEJlZm9yZSIsIkN0cmwtRGVsZXRlIjoiZGVsR3JvdXBBZnRlciIsIkN0cmwtUyI6InNhdmUiLCJDdHJsLUYiOiJmaW5kIiwiQ3RybC1HIjoiZmluZE5leHQiLCJTaGlmdC1DdHJsLUciOiJmaW5kUHJldiIsIlNoaWZ0LUN0cmwtRiI6InJlcGxhY2UiLCJTaGlmdC1DdHJsLVIiOiJyZXBsYWNlQWxsIiwiQ3RybC1bIjoiaW5kZW50TGVzcyIsIkN0cmwtXSI6ImluZGVudE1vcmUiLGZhbGx0aHJvdWdoOiJiYXNpYyJ9LHZvLm1hY0RlZmF1bHQ9eyJDbWQtQSI6InNlbGVjdEFsbCIsIkNtZC1EIjoiZGVsZXRlTGluZSIsIkNtZC1aIjoidW5kbyIsIlNoaWZ0LUNtZC1aIjoicmVkbyIsIkNtZC1ZIjoicmVkbyIsIkNtZC1VcCI6ImdvRG9jU3RhcnQiLCJDbWQtRW5kIjoiZ29Eb2NFbmQiLCJDbWQtRG93biI6ImdvRG9jRW5kIiwiQWx0LUxlZnQiOiJnb0dyb3VwTGVmdCIsIkFsdC1SaWdodCI6ImdvR3JvdXBSaWdodCIsIkNtZC1MZWZ0IjoiZ29MaW5lU3RhcnQiLCJDbWQtUmlnaHQiOiJnb0xpbmVFbmQiLCJBbHQtQmFja3NwYWNlIjoiZGVsR3JvdXBCZWZvcmUiLCJDdHJsLUFsdC1CYWNrc3BhY2UiOiJkZWxHcm91cEFmdGVyIiwiQWx0LURlbGV0ZSI6ImRlbEdyb3VwQWZ0ZXIiLCJDbWQtUyI6InNhdmUiLCJDbWQtRiI6ImZpbmQiLCJDbWQtRyI6ImZpbmROZXh0IiwiU2hpZnQtQ21kLUciOiJmaW5kUHJldiIsIkNtZC1BbHQtRiI6InJlcGxhY2UiLCJTaGlmdC1DbWQtQWx0LUYiOiJyZXBsYWNlQWxsIiwiQ21kLVsiOiJpbmRlbnRMZXNzIiwiQ21kLV0iOiJpbmRlbnRNb3JlIiwiQ21kLUJhY2tzcGFjZSI6ImRlbExpbmVMZWZ0IixmYWxsdGhyb3VnaDpbImJhc2ljIiwiZW1hY3N5Il19LHZvWyJkZWZhdWx0Il09S2k/dm8ubWFjRGVmYXVsdDp2by5wY0RlZmF1bHQsdm8uZW1hY3N5PXsiQ3RybC1GIjoiZ29DaGFyUmlnaHQiLCJDdHJsLUIiOiJnb0NoYXJMZWZ0IiwiQ3RybC1QIjoiZ29MaW5lVXAiLCJDdHJsLU4iOiJnb0xpbmVEb3duIiwiQWx0LUYiOiJnb1dvcmRSaWdodCIsIkFsdC1CIjoiZ29Xb3JkTGVmdCIsIkN0cmwtQSI6ImdvTGluZVN0YXJ0IiwiQ3RybC1FIjoiZ29MaW5lRW5kIiwiQ3RybC1WIjoiZ29QYWdlRG93biIsIlNoaWZ0LUN0cmwtViI6ImdvUGFnZVVwIiwiQ3RybC1EIjoiZGVsQ2hhckFmdGVyIiwiQ3RybC1IIjoiZGVsQ2hhckJlZm9yZSIsIkFsdC1EIjoiZGVsV29yZEFmdGVyIiwiQWx0LUJhY2tzcGFjZSI6ImRlbFdvcmRCZWZvcmUiLCJDdHJsLUsiOiJraWxsTGluZSIsIkN0cmwtVCI6InRyYW5zcG9zZUNoYXJzIn0sdC5sb29rdXBLZXk9d3IsdC5pc01vZGlmaWVyS2V5PUxyLHQua2V5TmFtZT1rcix0LmZyb21UZXh0QXJlYT1mdW5jdGlvbihlLHIpe2Z1bmN0aW9uIG4oKXtlLnZhbHVlPXUuZ2V0VmFsdWUoKX1pZihyfHwocj17fSksci52YWx1ZT1lLnZhbHVlLCFyLnRhYmluZGV4JiZlLnRhYmluZGV4JiYoci50YWJpbmRleD1lLnRhYmluZGV4KSwhci5wbGFjZWhvbGRlciYmZS5wbGFjZWhvbGRlciYmKHIucGxhY2Vob2xkZXI9ZS5wbGFjZWhvbGRlciksbnVsbD09ci5hdXRvZm9jdXMpe3ZhciBpPWRvY3VtZW50LmJvZHk7dHJ5e2k9ZG9jdW1lbnQuYWN0aXZlRWxlbWVudH1jYXRjaChvKXt9ci5hdXRvZm9jdXM9aT09ZXx8bnVsbCE9ZS5nZXRBdHRyaWJ1dGUoImF1dG9mb2N1cyIpJiZpPT1kb2N1bWVudC5ib2R5fWlmKGUuZm9ybSYmKEduKGUuZm9ybSwic3VibWl0IixuKSwhci5sZWF2ZVN1Ym1pdE1ldGhvZEFsb25lKSl7dmFyIGw9ZS5mb3JtLHM9bC5zdWJtaXQ7dHJ5e3ZhciBhPWwuc3VibWl0PWZ1bmN0aW9uKCl7bigpLGwuc3VibWl0PXMsbC5zdWJtaXQoKSxsLnN1Ym1pdD1hfX1jYXRjaChvKXt9fWUuc3R5bGUuZGlzcGxheT0ibm9uZSI7dmFyIHU9dChmdW5jdGlvbih0KXtlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHQsZS5uZXh0U2libGluZyl9LHIpO3JldHVybiB1LnNhdmU9bix1LmdldFRleHRBcmVhPWZ1bmN0aW9uKCl7cmV0dXJuIGV9LHUudG9UZXh0QXJlYT1mdW5jdGlvbigpe24oKSxlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodS5nZXRXcmFwcGVyRWxlbWVudCgpKSxlLnN0eWxlLmRpc3BsYXk9IiIsZS5mb3JtJiYoVm4oZS5mb3JtLCJzdWJtaXQiLG4pLCJmdW5jdGlvbiI9PXR5cGVvZiBlLmZvcm0uc3VibWl0JiYoZS5mb3JtLnN1Ym1pdD1zKSl9LHV9LFNyLnByb3RvdHlwZT17ZW9sOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLnN0cmluZy5sZW5ndGh9LHNvbDpmdW5jdGlvbigpe3JldHVybiAwPT10aGlzLnBvc30scGVlazpmdW5jdGlvbigpe3JldHVybiB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpfHx2b2lkIDB9LG5leHQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wb3M8dGhpcy5zdHJpbmcubGVuZ3RoP3RoaXMuc3RyaW5nLmNoYXJBdCh0aGlzLnBvcysrKTp2b2lkIDB9LGVhdDpmdW5jdGlvbih0KXt2YXIgZT10aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpO2lmKCJzdHJpbmciPT10eXBlb2YgdCl2YXIgcj1lPT10O2Vsc2UgdmFyIHI9ZSYmKHQudGVzdD90LnRlc3QoZSk6dChlKSk7cmV0dXJuIHI/KCsrdGhpcy5wb3MsZSk6dm9pZCAwfSxlYXRXaGlsZTpmdW5jdGlvbih0KXtmb3IodmFyIGU9dGhpcy5wb3M7dGhpcy5lYXQodCk7KTtyZXR1cm4gdGhpcy5wb3M+ZX0sZWF0U3BhY2U6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5wb3M7L1tcc1x1MDBhMF0vLnRlc3QodGhpcy5zdHJpbmcuY2hhckF0KHRoaXMucG9zKSk7KSsrdGhpcy5wb3M7cmV0dXJuIHRoaXMucG9zPnR9LHNraXBUb0VuZDpmdW5jdGlvbigpe3RoaXMucG9zPXRoaXMuc3RyaW5nLmxlbmd0aH0sc2tpcFRvOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuc3RyaW5nLmluZGV4T2YodCx0aGlzLnBvcyk7cmV0dXJuIGU+LTE/KHRoaXMucG9zPWUsITApOnZvaWQgMH0sYmFja1VwOmZ1bmN0aW9uKHQpe3RoaXMucG9zLT10fSxjb2x1bW46ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5sYXN0Q29sdW1uUG9zPHRoaXMuc3RhcnQmJih0aGlzLmxhc3RDb2x1bW5WYWx1ZT1abih0aGlzLnN0cmluZyx0aGlzLnN0YXJ0LHRoaXMudGFiU2l6ZSx0aGlzLmxhc3RDb2x1bW5Qb3MsdGhpcy5sYXN0Q29sdW1uVmFsdWUpLHRoaXMubGFzdENvbHVtblBvcz10aGlzLnN0YXJ0KSx0aGlzLmxhc3RDb2x1bW5WYWx1ZX0saW5kZW50YXRpb246ZnVuY3Rpb24oKXtyZXR1cm4gWm4odGhpcy5zdHJpbmcsbnVsbCx0aGlzLnRhYlNpemUpfSxtYXRjaDpmdW5jdGlvbih0LGUscil7aWYoInN0cmluZyIhPXR5cGVvZiB0KXt2YXIgbj10aGlzLnN0cmluZy5zbGljZSh0aGlzLnBvcykubWF0Y2godCk7cmV0dXJuIG4mJm4uaW5kZXg+MD9udWxsOihuJiZlIT09ITEmJih0aGlzLnBvcys9blswXS5sZW5ndGgpLG4pfXZhciBpPWZ1bmN0aW9uKHQpe3JldHVybiByP3QudG9Mb3dlckNhc2UoKTp0fSxvPXRoaXMuc3RyaW5nLnN1YnN0cih0aGlzLnBvcyx0Lmxlbmd0aCk7cmV0dXJuIGkobyk9PWkodCk/KGUhPT0hMSYmKHRoaXMucG9zKz10Lmxlbmd0aCksITApOnZvaWQgMH0sY3VycmVudDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnN0cmluZy5zbGljZSh0aGlzLnN0YXJ0LHRoaXMucG9zKX19LHQuU3RyaW5nU3RyZWFtPVNyLHQuVGV4dE1hcmtlcj1NcixqbihNciksTXIucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7aWYoIXRoaXMuZXhwbGljaXRseUNsZWFyZWQpe3ZhciB0PXRoaXMuZG9jLmNtLGU9dCYmIXQuY3VyT3A7aWYoZSYmaWUodCksWW4odGhpcywiY2xlYXIiKSl7dmFyIHI9dGhpcy5maW5kKCk7ciYmVW4odGhpcywiY2xlYXIiLHIuZnJvbSxyLnRvKX1mb3IodmFyIG49bnVsbCxpPW51bGwsbz0wO288dGhpcy5saW5lcy5sZW5ndGg7KytvKXt2YXIgbD10aGlzLmxpbmVzW29dLHM9TnIobC5tYXJrZWRTcGFucyx0aGlzKTtudWxsIT1zLnRvJiYoaT1ibihsKSksbC5tYXJrZWRTcGFucz1EcihsLm1hcmtlZFNwYW5zLHMpLG51bGwhPXMuZnJvbT9uPWJuKGwpOnRoaXMuY29sbGFwc2VkJiYhVnIodGhpcy5kb2MsbCkmJnQmJnluKGwscmUodC5kaXNwbGF5KSl9aWYodCYmdGhpcy5jb2xsYXBzZWQmJiF0Lm9wdGlvbnMubGluZVdyYXBwaW5nKWZvcih2YXIgbz0wO288dGhpcy5saW5lcy5sZW5ndGg7KytvKXt2YXIgYT1Hcih0LmRvYyx0aGlzLmxpbmVzW29dKSx1PWModC5kb2MsYSk7dT50LmRpc3BsYXkubWF4TGluZUxlbmd0aCYmKHQuZGlzcGxheS5tYXhMaW5lPWEsdC5kaXNwbGF5Lm1heExpbmVMZW5ndGg9dSx0LmRpc3BsYXkubWF4TGluZUNoYW5nZWQ9ITApfW51bGwhPW4mJnQmJnVlKHQsbixpKzEpLHRoaXMubGluZXMubGVuZ3RoPTAsdGhpcy5leHBsaWNpdGx5Q2xlYXJlZD0hMCx0aGlzLmF0b21pYyYmdGhpcy5kb2MuY2FudEVkaXQmJih0aGlzLmRvYy5jYW50RWRpdD0hMSx0JiZpcih0KSksZSYmb2UodCl9fSxNci5wcm90b3R5cGUuZmluZD1mdW5jdGlvbigpe2Zvcih2YXIgdCxlLHI9MDtyPHRoaXMubGluZXMubGVuZ3RoOysrcil7dmFyIG49dGhpcy5saW5lc1tyXSxpPU5yKG4ubWFya2VkU3BhbnMsdGhpcyk7aWYobnVsbCE9aS5mcm9tfHxudWxsIT1pLnRvKXt2YXIgbz1ibihuKTtudWxsIT1pLmZyb20mJih0PVllKG8saS5mcm9tKSksbnVsbCE9aS50byYmKGU9WWUobyxpLnRvKSl9fXJldHVybiJib29rbWFyayI9PXRoaXMudHlwZT90OnQmJntmcm9tOnQsdG86ZX19LE1yLnByb3RvdHlwZS5jaGFuZ2VkPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5maW5kKCksZT10aGlzLmRvYy5jbTtpZih0JiZlKXsiYm9va21hcmsiIT10aGlzLnR5cGUmJih0PXQuZnJvbSk7dmFyIHI9Z24odGhpcy5kb2MsdC5saW5lKTtpZihHKGUsciksdC5saW5lPj1lLmRpc3BsYXkuc2hvd2luZ0Zyb20mJnQubGluZTxlLmRpc3BsYXkuc2hvd2luZ1RvKXtmb3IodmFyIG49ZS5kaXNwbGF5LmxpbmVEaXYuZmlyc3RDaGlsZDtuO249bi5uZXh0U2libGluZylpZihuLmxpbmVPYmo9PXIpe24ub2Zmc2V0SGVpZ2h0IT1yLmhlaWdodCYmeW4ocixuLm9mZnNldEhlaWdodCk7CmJyZWFrfWFlKGUsZnVuY3Rpb24oKXtlLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQ9ZS5jdXJPcC5mb3JjZVVwZGF0ZT1lLmN1ck9wLnVwZGF0ZU1heExpbmU9ITB9KX19fSxNci5wcm90b3R5cGUuYXR0YWNoTGluZT1mdW5jdGlvbih0KXtpZighdGhpcy5saW5lcy5sZW5ndGgmJnRoaXMuZG9jLmNtKXt2YXIgZT10aGlzLmRvYy5jbS5jdXJPcDtlLm1heWJlSGlkZGVuTWFya2VycyYmLTEhPXRpKGUubWF5YmVIaWRkZW5NYXJrZXJzLHRoaXMpfHwoZS5tYXliZVVuaGlkZGVuTWFya2Vyc3x8KGUubWF5YmVVbmhpZGRlbk1hcmtlcnM9W10pKS5wdXNoKHRoaXMpfXRoaXMubGluZXMucHVzaCh0KX0sTXIucHJvdG90eXBlLmRldGFjaExpbmU9ZnVuY3Rpb24odCl7aWYodGhpcy5saW5lcy5zcGxpY2UodGkodGhpcy5saW5lcyx0KSwxKSwhdGhpcy5saW5lcy5sZW5ndGgmJnRoaXMuZG9jLmNtKXt2YXIgZT10aGlzLmRvYy5jbS5jdXJPcDsoZS5tYXliZUhpZGRlbk1hcmtlcnN8fChlLm1heWJlSGlkZGVuTWFya2Vycz1bXSkpLnB1c2godGhpcyl9fSx0LlNoYXJlZFRleHRNYXJrZXI9QXIsam4oQXIpLEFyLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe2lmKCF0aGlzLmV4cGxpY2l0bHlDbGVhcmVkKXt0aGlzLmV4cGxpY2l0bHlDbGVhcmVkPSEwO2Zvcih2YXIgdD0wO3Q8dGhpcy5tYXJrZXJzLmxlbmd0aDsrK3QpdGhpcy5tYXJrZXJzW3RdLmNsZWFyKCk7VW4odGhpcywiY2xlYXIiKX19LEFyLnByb3RvdHlwZS5maW5kPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJpbWFyeS5maW5kKCl9O3ZhciB5bz10LkxpbmVXaWRnZXQ9ZnVuY3Rpb24odCxlLHIpe2lmKHIpZm9yKHZhciBuIGluIHIpci5oYXNPd25Qcm9wZXJ0eShuKSYmKHRoaXNbbl09cltuXSk7dGhpcy5jbT10LHRoaXMubm9kZT1lfTtqbih5bykseW8ucHJvdG90eXBlLmNsZWFyPV9yKGZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5saW5lLndpZGdldHMsZT1ibih0aGlzLmxpbmUpO2lmKG51bGwhPWUmJnQpe2Zvcih2YXIgcj0wO3I8dC5sZW5ndGg7KytyKXRbcl09PXRoaXMmJnQuc3BsaWNlKHItLSwxKTt0Lmxlbmd0aHx8KHRoaXMubGluZS53aWRnZXRzPW51bGwpO3ZhciBuPUNuKHRoaXMuY20sdGhpcy5saW5lKTx0aGlzLmNtLmRvYy5zY3JvbGxUb3A7eW4odGhpcy5saW5lLE1hdGgubWF4KDAsdGhpcy5saW5lLmhlaWdodC1Zcih0aGlzKSkpLG4mJmZyKHRoaXMuY20sMCwtdGhpcy5oZWlnaHQpLHVlKHRoaXMuY20sZSxlKzEpfX0pLHlvLnByb3RvdHlwZS5jaGFuZ2VkPV9yKGZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5oZWlnaHQ7dGhpcy5oZWlnaHQ9bnVsbDt2YXIgZT1Zcih0aGlzKS10O2lmKGUpe3luKHRoaXMubGluZSx0aGlzLmxpbmUuaGVpZ2h0K2UpO3ZhciByPWJuKHRoaXMubGluZSk7dWUodGhpcy5jbSxyLHIrMSl9fSk7dmFyIGJvPXQuTGluZT1mdW5jdGlvbih0LGUscil7dGhpcy50ZXh0PXQsWHIodGhpcyxlKSx0aGlzLmhlaWdodD1yP3IodGhpcyk6MX07am4oYm8pLGJvLnByb3RvdHlwZS5saW5lTm89ZnVuY3Rpb24oKXtyZXR1cm4gYm4odGhpcyl9O3ZhciB4bz17fTtmbi5wcm90b3R5cGU9e2NodW5rU2l6ZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmxpbmVzLmxlbmd0aH0scmVtb3ZlSW5uZXI6ZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9dCxuPXQrZTtuPnI7KytyKXt2YXIgaT10aGlzLmxpbmVzW3JdO3RoaXMuaGVpZ2h0LT1pLmhlaWdodCxacihpKSxVbihpLCJkZWxldGUiKX10aGlzLmxpbmVzLnNwbGljZSh0LGUpfSxjb2xsYXBzZTpmdW5jdGlvbih0KXt0LnNwbGljZS5hcHBseSh0LFt0Lmxlbmd0aCwwXS5jb25jYXQodGhpcy5saW5lcykpfSxpbnNlcnRJbm5lcjpmdW5jdGlvbih0LGUscil7dGhpcy5oZWlnaHQrPXIsdGhpcy5saW5lcz10aGlzLmxpbmVzLnNsaWNlKDAsdCkuY29uY2F0KGUpLmNvbmNhdCh0aGlzLmxpbmVzLnNsaWNlKHQpKTtmb3IodmFyIG49MCxpPWUubGVuZ3RoO2k+bjsrK24pZVtuXS5wYXJlbnQ9dGhpc30saXRlck46ZnVuY3Rpb24odCxlLHIpe2Zvcih2YXIgbj10K2U7bj50OysrdClpZihyKHRoaXMubGluZXNbdF0pKXJldHVybiEwfX0saG4ucHJvdG90eXBlPXtjaHVua1NpemU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zaXplfSxyZW1vdmVJbm5lcjpmdW5jdGlvbih0LGUpe3RoaXMuc2l6ZS09ZTtmb3IodmFyIHI9MDtyPHRoaXMuY2hpbGRyZW4ubGVuZ3RoOysrcil7dmFyIG49dGhpcy5jaGlsZHJlbltyXSxpPW4uY2h1bmtTaXplKCk7aWYoaT50KXt2YXIgbz1NYXRoLm1pbihlLGktdCksbD1uLmhlaWdodDtpZihuLnJlbW92ZUlubmVyKHQsbyksdGhpcy5oZWlnaHQtPWwtbi5oZWlnaHQsaT09byYmKHRoaXMuY2hpbGRyZW4uc3BsaWNlKHItLSwxKSxuLnBhcmVudD1udWxsKSwwPT0oZS09bykpYnJlYWs7dD0wfWVsc2UgdC09aX1pZih0aGlzLnNpemUtZTwyNSl7dmFyIHM9W107dGhpcy5jb2xsYXBzZShzKSx0aGlzLmNoaWxkcmVuPVtuZXcgZm4ocyldLHRoaXMuY2hpbGRyZW5bMF0ucGFyZW50PXRoaXN9fSxjb2xsYXBzZTpmdW5jdGlvbih0KXtmb3IodmFyIGU9MCxyPXRoaXMuY2hpbGRyZW4ubGVuZ3RoO3I+ZTsrK2UpdGhpcy5jaGlsZHJlbltlXS5jb2xsYXBzZSh0KX0saW5zZXJ0SW5uZXI6ZnVuY3Rpb24odCxlLHIpe3RoaXMuc2l6ZSs9ZS5sZW5ndGgsdGhpcy5oZWlnaHQrPXI7Zm9yKHZhciBuPTAsaT10aGlzLmNoaWxkcmVuLmxlbmd0aDtpPm47KytuKXt2YXIgbz10aGlzLmNoaWxkcmVuW25dLGw9by5jaHVua1NpemUoKTtpZihsPj10KXtpZihvLmluc2VydElubmVyKHQsZSxyKSxvLmxpbmVzJiZvLmxpbmVzLmxlbmd0aD41MCl7Zm9yKDtvLmxpbmVzLmxlbmd0aD41MDspe3ZhciBzPW8ubGluZXMuc3BsaWNlKG8ubGluZXMubGVuZ3RoLTI1LDI1KSxhPW5ldyBmbihzKTtvLmhlaWdodC09YS5oZWlnaHQsdGhpcy5jaGlsZHJlbi5zcGxpY2UobisxLDAsYSksYS5wYXJlbnQ9dGhpc310aGlzLm1heWJlU3BpbGwoKX1icmVha310LT1sfX0sbWF5YmVTcGlsbDpmdW5jdGlvbigpe2lmKCEodGhpcy5jaGlsZHJlbi5sZW5ndGg8PTEwKSl7dmFyIHQ9dGhpcztkb3t2YXIgZT10LmNoaWxkcmVuLnNwbGljZSh0LmNoaWxkcmVuLmxlbmd0aC01LDUpLHI9bmV3IGhuKGUpO2lmKHQucGFyZW50KXt0LnNpemUtPXIuc2l6ZSx0LmhlaWdodC09ci5oZWlnaHQ7dmFyIG49dGkodC5wYXJlbnQuY2hpbGRyZW4sdCk7dC5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKG4rMSwwLHIpfWVsc2V7dmFyIGk9bmV3IGhuKHQuY2hpbGRyZW4pO2kucGFyZW50PXQsdC5jaGlsZHJlbj1baSxyXSx0PWl9ci5wYXJlbnQ9dC5wYXJlbnR9d2hpbGUodC5jaGlsZHJlbi5sZW5ndGg+MTApO3QucGFyZW50Lm1heWJlU3BpbGwoKX19LGl0ZXJOOmZ1bmN0aW9uKHQsZSxyKXtmb3IodmFyIG49MCxpPXRoaXMuY2hpbGRyZW4ubGVuZ3RoO2k+bjsrK24pe3ZhciBvPXRoaXMuY2hpbGRyZW5bbl0sbD1vLmNodW5rU2l6ZSgpO2lmKGw+dCl7dmFyIHM9TWF0aC5taW4oZSxsLXQpO2lmKG8uaXRlck4odCxzLHIpKXJldHVybiEwO2lmKDA9PShlLT1zKSlicmVhazt0PTB9ZWxzZSB0LT1sfX19O3ZhciBDbz0wLHdvPXQuRG9jPWZ1bmN0aW9uKHQsZSxyKXtpZighKHRoaXMgaW5zdGFuY2VvZiB3bykpcmV0dXJuIG5ldyB3byh0LGUscik7bnVsbD09ciYmKHI9MCksaG4uY2FsbCh0aGlzLFtuZXcgZm4oW25ldyBibygiIixudWxsKV0pXSksdGhpcy5maXJzdD1yLHRoaXMuc2Nyb2xsVG9wPXRoaXMuc2Nyb2xsTGVmdD0wLHRoaXMuY2FudEVkaXQ9ITEsdGhpcy5oaXN0b3J5PUxuKCksdGhpcy5jbGVhbkdlbmVyYXRpb249MSx0aGlzLmZyb250aWVyPXI7dmFyIG49WWUociwwKTt0aGlzLnNlbD17ZnJvbTpuLHRvOm4saGVhZDpuLGFuY2hvcjpuLHNoaWZ0OiExLGV4dGVuZDohMSxnb2FsQ29sdW1uOm51bGx9LHRoaXMuaWQ9KytDbyx0aGlzLm1vZGVPcHRpb249ZSwic3RyaW5nIj09dHlwZW9mIHQmJih0PXpvKHQpKSxjbih0aGlzLHtmcm9tOm4sdG86bix0ZXh0OnR9LG51bGwse2hlYWQ6bixhbmNob3I6bn0pfTt3by5wcm90b3R5cGU9ZWkoaG4ucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp3byxpdGVyOmZ1bmN0aW9uKHQsZSxyKXtyP3RoaXMuaXRlck4odC10aGlzLmZpcnN0LGUtdCxyKTp0aGlzLml0ZXJOKHRoaXMuZmlyc3QsdGhpcy5maXJzdCt0aGlzLnNpemUsdCl9LGluc2VydDpmdW5jdGlvbih0LGUpe2Zvcih2YXIgcj0wLG49MCxpPWUubGVuZ3RoO2k+bjsrK24pcis9ZVtuXS5oZWlnaHQ7dGhpcy5pbnNlcnRJbm5lcih0LXRoaXMuZmlyc3QsZSxyKX0scmVtb3ZlOmZ1bmN0aW9uKHQsZSl7dGhpcy5yZW1vdmVJbm5lcih0LXRoaXMuZmlyc3QsZSl9LGdldFZhbHVlOmZ1bmN0aW9uKHQpe3ZhciBlPXZuKHRoaXMsdGhpcy5maXJzdCx0aGlzLmZpcnN0K3RoaXMuc2l6ZSk7cmV0dXJuIHQ9PT0hMT9lOmUuam9pbih0fHwiXG4iKX0sc2V0VmFsdWU6ZnVuY3Rpb24odCl7dmFyIGU9WWUodGhpcy5maXJzdCwwKSxyPXRoaXMuZmlyc3QrdGhpcy5zaXplLTE7QmUodGhpcyx7ZnJvbTplLHRvOlllKHIsZ24odGhpcyxyKS50ZXh0Lmxlbmd0aCksdGV4dDp6byh0KSxvcmlnaW46InNldFZhbHVlIn0se2hlYWQ6ZSxhbmNob3I6ZX0sITApfSxyZXBsYWNlUmFuZ2U6ZnVuY3Rpb24odCxlLHIsbil7ZT1RZSh0aGlzLGUpLHI9cj9RZSh0aGlzLHIpOmUsX2UodGhpcyx0LGUscixuKX0sZ2V0UmFuZ2U6ZnVuY3Rpb24odCxlLHIpe3ZhciBuPW1uKHRoaXMsUWUodGhpcyx0KSxRZSh0aGlzLGUpKTtyZXR1cm4gcj09PSExP246bi5qb2luKHJ8fCJcbiIpfSxnZXRMaW5lOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuZ2V0TGluZUhhbmRsZSh0KTtyZXR1cm4gZSYmZS50ZXh0fSxzZXRMaW5lOmZ1bmN0aW9uKHQsZSl7dHIodGhpcyx0KSYmX2UodGhpcyxlLFllKHQsMCksUWUodGhpcyxZZSh0KSkpfSxyZW1vdmVMaW5lOmZ1bmN0aW9uKHQpe3Q/X2UodGhpcywiIixRZSh0aGlzLFllKHQtMSkpLFFlKHRoaXMsWWUodCkpKTpfZSh0aGlzLCIiLFllKDAsMCksUWUodGhpcyxZZSgxLDApKSl9LGdldExpbmVIYW5kbGU6ZnVuY3Rpb24odCl7cmV0dXJuIHRyKHRoaXMsdCk/Z24odGhpcyx0KTp2b2lkIDB9LGdldExpbmVOdW1iZXI6ZnVuY3Rpb24odCl7cmV0dXJuIGJuKHQpfSxnZXRMaW5lSGFuZGxlVmlzdWFsU3RhcnQ6ZnVuY3Rpb24odCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0JiYodD1nbih0aGlzLHQpKSxHcih0aGlzLHQpfSxsaW5lQ291bnQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zaXplfSxmaXJzdExpbmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5maXJzdH0sbGFzdExpbmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5maXJzdCt0aGlzLnNpemUtMX0sY2xpcFBvczpmdW5jdGlvbih0KXtyZXR1cm4gUWUodGhpcyx0KX0sZ2V0Q3Vyc29yOmZ1bmN0aW9uKHQpe3ZhciBlLHI9dGhpcy5zZWw7cmV0dXJuIGU9bnVsbD09dHx8ImhlYWQiPT10P3IuaGVhZDoiYW5jaG9yIj09dD9yLmFuY2hvcjoiZW5kIj09dHx8dD09PSExP3IudG86ci5mcm9tLFplKGUpfSxzb21ldGhpbmdTZWxlY3RlZDpmdW5jdGlvbigpe3JldHVybiFqZSh0aGlzLnNlbC5oZWFkLHRoaXMuc2VsLmFuY2hvcil9LHNldEN1cnNvcjpzZShmdW5jdGlvbih0LGUscil7dmFyIG49UWUodGhpcywibnVtYmVyIj09dHlwZW9mIHQ/WWUodCxlfHwwKTp0KTtyP2VyKHRoaXMsbik6bnIodGhpcyxuLG4pfSksc2V0U2VsZWN0aW9uOnNlKGZ1bmN0aW9uKHQsZSxyKXtucih0aGlzLFFlKHRoaXMsdCksUWUodGhpcyxlfHx0KSxyKX0pLGV4dGVuZFNlbGVjdGlvbjpzZShmdW5jdGlvbih0LGUscil7ZXIodGhpcyxRZSh0aGlzLHQpLGUmJlFlKHRoaXMsZSkscil9KSxnZXRTZWxlY3Rpb246ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuZ2V0UmFuZ2UodGhpcy5zZWwuZnJvbSx0aGlzLnNlbC50byx0KX0scmVwbGFjZVNlbGVjdGlvbjpmdW5jdGlvbih0LGUscil7QmUodGhpcyx7ZnJvbTp0aGlzLnNlbC5mcm9tLHRvOnRoaXMuc2VsLnRvLHRleHQ6em8odCksb3JpZ2luOnJ9LGV8fCJhcm91bmQiKX0sdW5kbzpzZShmdW5jdGlvbigpe1ZlKHRoaXMsInVuZG8iKX0pLHJlZG86c2UoZnVuY3Rpb24oKXtWZSh0aGlzLCJyZWRvIil9KSxzZXRFeHRlbmRpbmc6ZnVuY3Rpb24odCl7dGhpcy5zZWwuZXh0ZW5kPXR9LGhpc3RvcnlTaXplOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5oaXN0b3J5O3JldHVybnt1bmRvOnQuZG9uZS5sZW5ndGgscmVkbzp0LnVuZG9uZS5sZW5ndGh9fSxjbGVhckhpc3Rvcnk6ZnVuY3Rpb24oKXt0aGlzLmhpc3Rvcnk9TG4odGhpcy5oaXN0b3J5Lm1heEdlbmVyYXRpb24pfSxtYXJrQ2xlYW46ZnVuY3Rpb24oKXt0aGlzLmNsZWFuR2VuZXJhdGlvbj10aGlzLmNoYW5nZUdlbmVyYXRpb24oKX0sY2hhbmdlR2VuZXJhdGlvbjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmhpc3RvcnkubGFzdE9wPXRoaXMuaGlzdG9yeS5sYXN0T3JpZ2luPW51bGwsdGhpcy5oaXN0b3J5LmdlbmVyYXRpb259LGlzQ2xlYW46ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuaGlzdG9yeS5nZW5lcmF0aW9uPT0odHx8dGhpcy5jbGVhbkdlbmVyYXRpb24pfSxnZXRIaXN0b3J5OmZ1bmN0aW9uKCl7cmV0dXJue2RvbmU6SG4odGhpcy5oaXN0b3J5LmRvbmUpLHVuZG9uZTpIbih0aGlzLmhpc3RvcnkudW5kb25lKX19LHNldEhpc3Rvcnk6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5oaXN0b3J5PUxuKHRoaXMuaGlzdG9yeS5tYXhHZW5lcmF0aW9uKTtlLmRvbmU9dC5kb25lLnNsaWNlKDApLGUudW5kb25lPXQudW5kb25lLnNsaWNlKDApfSxtYXJrVGV4dDpmdW5jdGlvbih0LGUscil7cmV0dXJuIFRyKHRoaXMsUWUodGhpcyx0KSxRZSh0aGlzLGUpLHIsInJhbmdlIil9LHNldEJvb2ttYXJrOmZ1bmN0aW9uKHQsZSl7dmFyIHI9e3JlcGxhY2VkV2l0aDplJiYobnVsbD09ZS5ub2RlVHlwZT9lLndpZGdldDplKSxpbnNlcnRMZWZ0OmUmJmUuaW5zZXJ0TGVmdH07cmV0dXJuIHQ9UWUodGhpcyx0KSxUcih0aGlzLHQsdCxyLCJib29rbWFyayIpfSxmaW5kTWFya3NBdDpmdW5jdGlvbih0KXt0PVFlKHRoaXMsdCk7dmFyIGU9W10scj1nbih0aGlzLHQubGluZSkubWFya2VkU3BhbnM7aWYocilmb3IodmFyIG49MDtuPHIubGVuZ3RoOysrbil7dmFyIGk9cltuXTsobnVsbD09aS5mcm9tfHxpLmZyb208PXQuY2gpJiYobnVsbD09aS50b3x8aS50bz49dC5jaCkmJmUucHVzaChpLm1hcmtlci5wYXJlbnR8fGkubWFya2VyKX1yZXR1cm4gZX0sZ2V0QWxsTWFya3M6ZnVuY3Rpb24oKXt2YXIgdD1bXTtyZXR1cm4gdGhpcy5pdGVyKGZ1bmN0aW9uKGUpe3ZhciByPWUubWFya2VkU3BhbnM7aWYocilmb3IodmFyIG49MDtuPHIubGVuZ3RoOysrbiludWxsIT1yW25dLmZyb20mJnQucHVzaChyW25dLm1hcmtlcil9KSx0fSxwb3NGcm9tSW5kZXg6ZnVuY3Rpb24odCl7dmFyIGUscj10aGlzLmZpcnN0O3JldHVybiB0aGlzLml0ZXIoZnVuY3Rpb24obil7dmFyIGk9bi50ZXh0Lmxlbmd0aCsxO3JldHVybiBpPnQ/KGU9dCwhMCk6KHQtPWksKytyLHZvaWQgMCl9KSxRZSh0aGlzLFllKHIsZSkpfSxpbmRleEZyb21Qb3M6ZnVuY3Rpb24odCl7dD1RZSh0aGlzLHQpO3ZhciBlPXQuY2g7cmV0dXJuIHQubGluZTx0aGlzLmZpcnN0fHx0LmNoPDA/MDoodGhpcy5pdGVyKHRoaXMuZmlyc3QsdC5saW5lLGZ1bmN0aW9uKHQpe2UrPXQudGV4dC5sZW5ndGgrMX0pLGUpfSxjb3B5OmZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB3byh2bih0aGlzLHRoaXMuZmlyc3QsdGhpcy5maXJzdCt0aGlzLnNpemUpLHRoaXMubW9kZU9wdGlvbix0aGlzLmZpcnN0KTtyZXR1cm4gZS5zY3JvbGxUb3A9dGhpcy5zY3JvbGxUb3AsZS5zY3JvbGxMZWZ0PXRoaXMuc2Nyb2xsTGVmdCxlLnNlbD17ZnJvbTp0aGlzLnNlbC5mcm9tLHRvOnRoaXMuc2VsLnRvLGhlYWQ6dGhpcy5zZWwuaGVhZCxhbmNob3I6dGhpcy5zZWwuYW5jaG9yLHNoaWZ0OnRoaXMuc2VsLnNoaWZ0LGV4dGVuZDohMSxnb2FsQ29sdW1uOnRoaXMuc2VsLmdvYWxDb2x1bW59LHQmJihlLmhpc3RvcnkudW5kb0RlcHRoPXRoaXMuaGlzdG9yeS51bmRvRGVwdGgsZS5zZXRIaXN0b3J5KHRoaXMuZ2V0SGlzdG9yeSgpKSksZX0sbGlua2VkRG9jOmZ1bmN0aW9uKHQpe3R8fCh0PXt9KTt2YXIgZT10aGlzLmZpcnN0LHI9dGhpcy5maXJzdCt0aGlzLnNpemU7bnVsbCE9dC5mcm9tJiZ0LmZyb20+ZSYmKGU9dC5mcm9tKSxudWxsIT10LnRvJiZ0LnRvPHImJihyPXQudG8pO3ZhciBuPW5ldyB3byh2bih0aGlzLGUsciksdC5tb2RlfHx0aGlzLm1vZGVPcHRpb24sZSk7cmV0dXJuIHQuc2hhcmVkSGlzdCYmKG4uaGlzdG9yeT10aGlzLmhpc3RvcnkpLCh0aGlzLmxpbmtlZHx8KHRoaXMubGlua2VkPVtdKSkucHVzaCh7ZG9jOm4sc2hhcmVkSGlzdDp0LnNoYXJlZEhpc3R9KSxuLmxpbmtlZD1be2RvYzp0aGlzLGlzUGFyZW50OiEwLHNoYXJlZEhpc3Q6dC5zaGFyZWRIaXN0fV0sbn0sdW5saW5rRG9jOmZ1bmN0aW9uKGUpe2lmKGUgaW5zdGFuY2VvZiB0JiYoZT1lLmRvYyksdGhpcy5saW5rZWQpZm9yKHZhciByPTA7cjx0aGlzLmxpbmtlZC5sZW5ndGg7KytyKXt2YXIgbj10aGlzLmxpbmtlZFtyXTtpZihuLmRvYz09ZSl7dGhpcy5saW5rZWQuc3BsaWNlKHIsMSksZS51bmxpbmtEb2ModGhpcyk7YnJlYWt9fWlmKGUuaGlzdG9yeT09dGhpcy5oaXN0b3J5KXt2YXIgaT1bZS5pZF07ZG4oZSxmdW5jdGlvbih0KXtpLnB1c2godC5pZCl9LCEwKSxlLmhpc3Rvcnk9TG4oKSxlLmhpc3RvcnkuZG9uZT1Ibih0aGlzLmhpc3RvcnkuZG9uZSxpKSxlLmhpc3RvcnkudW5kb25lPUhuKHRoaXMuaGlzdG9yeS51bmRvbmUsaSl9fSxpdGVyTGlua2VkRG9jczpmdW5jdGlvbih0KXtkbih0aGlzLHQpfSxnZXRNb2RlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubW9kZX0sZ2V0RWRpdG9yOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY219fSksd28ucHJvdG90eXBlLmVhY2hMaW5lPXdvLnByb3RvdHlwZS5pdGVyO3ZhciBMbz0iaXRlciBpbnNlcnQgcmVtb3ZlIGNvcHkgZ2V0RWRpdG9yIi5zcGxpdCgiICIpO2Zvcih2YXIga28gaW4gd28ucHJvdG90eXBlKXdvLnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShrbykmJnRpKExvLGtvKTwwJiYodC5wcm90b3R5cGVba29dPWZ1bmN0aW9uKHQpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiB0LmFwcGx5KHRoaXMuZG9jLGFyZ3VtZW50cyl9fSh3by5wcm90b3R5cGVba29dKSk7am4od28pLHQuZV9zdG9wPVBuLHQuZV9wcmV2ZW50RGVmYXVsdD16bix0LmVfc3RvcFByb3BhZ2F0aW9uPUluO3ZhciBTbyxNbz0wO3Qub249R24sdC5vZmY9Vm4sdC5zaWduYWw9S247dmFyIFRvPTMwLEFvPXQuUGFzcz17dG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iQ29kZU1pcnJvci5QYXNzIn19OyRuLnByb3RvdHlwZT17c2V0OmZ1bmN0aW9uKHQsZSl7Y2xlYXJUaW1lb3V0KHRoaXMuaWQpLHRoaXMuaWQ9c2V0VGltZW91dChlLHQpfX0sdC5jb3VudENvbHVtbj1abjt2YXIgSG89WyIiXSxObz0vW1x1MzA0MC1cdTMwOWZcdTMwYTAtXHUzMGZmXHUzNDAwLVx1NGRiNVx1NGUwMC1cdTlmY2NcdWFjMDAtXHVkN2FmXS8sRG89L1tcdTAzMDAtXHUwMzZGXHUwNDgzLVx1MDQ4N1x1MDQ4OC1cdTA0ODlcdTA1OTEtXHUwNUJEXHUwNUJGXHUwNUMxLVx1MDVDMlx1MDVDNC1cdTA1QzVcdTA1QzdcdTA2MTAtXHUwNjFBXHUwNjRCLVx1MDY1Rlx1MDY3MFx1MDZENi1cdTA2RENcdTA2REYtXHUwNkU0XHUwNkU3LVx1MDZFOFx1MDZFQS1cdTA2RURcdUE2NkZcdTFEQzDigJNcdTFERkZcdTIwRDDigJNcdTIwRkZcdUE2NzAtXHVBNjcyXHVBNjc0LVx1QTY3RFx1QTY5Rlx1ZGMwMC1cdWRmZmZcdUZFMjDigJNcdUZFMkZdLzt0LnJlcGxhY2VHZXRSZWN0PWZ1bmN0aW9uKHQpe2ZpPXR9O3ZhciBXbz1mdW5jdGlvbigpe2lmKE5pKXJldHVybiExO3ZhciB0PXNpKCJkaXYiKTtyZXR1cm4iZHJhZ2dhYmxlImluIHR8fCJkcmFnRHJvcCJpbiB0fSgpO1RpP2hpPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIDM2PT10LmNoYXJDb2RlQXQoZS0xKSYmMzk9PXQuY2hhckNvZGVBdChlKX06SWkmJiEvVmVyc2lvblwvKFs2LTldfFxkXGQpXGIvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk/aGk9ZnVuY3Rpb24odCxlKXtyZXR1cm4vXC1bXiBcLT9dfFw/W14gIVwnXCJcKSwuXC1cLzo7XD9cXVx9XS8udGVzdCh0LnNsaWNlKGUtMSxlKzEpKX06V2kmJi9DaHJvbWVcLyg/OjI5fFszLTldXGR8XGRcZFxkKVwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpP2hpPWZ1bmN0aW9uKHQsZSl7dmFyIHI9dC5jaGFyQ29kZUF0KGUtMSk7cmV0dXJuIHI+PTgyMDgmJjgyMTI+PXJ9OldpJiYoaGk9ZnVuY3Rpb24odCxlKXtpZihlPjEmJjQ1PT10LmNoYXJDb2RlQXQoZS0xKSl7aWYoL1x3Ly50ZXN0KHQuY2hhckF0KGUtMikpJiYvW15cLT9cLl0vLnRlc3QodC5jaGFyQXQoZSkpKXJldHVybiEwO2lmKGU+MiYmL1tcZFwuLF0vLnRlc3QodC5jaGFyQXQoZS0yKSkmJi9bXGRcLixdLy50ZXN0KHQuY2hhckF0KGUpKSlyZXR1cm4hMX1yZXR1cm4vW34hIyUmKik9K31cXVxcfFwiXC4+LDo7XVsoe1s8XXwtW15cLT9cLlx1MjAxMC1cdTIwMWZcdTIwMjZdfFw/W1x3fmBAIyQlXF4mKihfPSt7W3w+PF184oCmW1x3fmBAIyQlXF4mKihfPSt7Wz48XS8udGVzdCh0LnNsaWNlKGUtMSxlKzEpKX0pO3ZhciBPbyxFbyx6bz0zIT0iXG5cbmIiLnNwbGl0KC9cbi8pLmxlbmd0aD9mdW5jdGlvbih0KXtmb3IodmFyIGU9MCxyPVtdLG49dC5sZW5ndGg7bj49ZTspe3ZhciBpPXQuaW5kZXhPZigiXG4iLGUpOy0xPT1pJiYoaT10Lmxlbmd0aCk7dmFyIG89dC5zbGljZShlLCJcciI9PXQuY2hhckF0KGktMSk/aS0xOmkpLGw9by5pbmRleE9mKCJcciIpOy0xIT1sPyhyLnB1c2goby5zbGljZSgwLGwpKSxlKz1sKzEpOihyLnB1c2gobyksZT1pKzEpfXJldHVybiByfTpmdW5jdGlvbih0KXtyZXR1cm4gdC5zcGxpdCgvXHJcbj98XG4vKX07dC5zcGxpdExpbmVzPXpvO3ZhciBJbz13aW5kb3cuZ2V0U2VsZWN0aW9uP2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdC5zZWxlY3Rpb25TdGFydCE9dC5zZWxlY3Rpb25FbmR9Y2F0Y2goZSl7cmV0dXJuITF9fTpmdW5jdGlvbih0KXt0cnl7dmFyIGU9dC5vd25lckRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpfWNhdGNoKHIpe31yZXR1cm4gZSYmZS5wYXJlbnRFbGVtZW50KCk9PXQ/MCE9ZS5jb21wYXJlRW5kUG9pbnRzKCJTdGFydFRvRW5kIixlKTohMX0sRm89ZnVuY3Rpb24oKXt2YXIgdD1zaSgiZGl2Iik7cmV0dXJuIm9uY29weSJpbiB0PyEwOih0LnNldEF0dHJpYnV0ZSgib25jb3B5IiwicmV0dXJuOyIpLCJmdW5jdGlvbiI9PXR5cGVvZiB0Lm9uY29weSl9KCksUG89ezM6IkVudGVyIiw4OiJCYWNrc3BhY2UiLDk6IlRhYiIsMTM6IkVudGVyIiwxNjoiU2hpZnQiLDE3OiJDdHJsIiwxODoiQWx0IiwxOToiUGF1c2UiLDIwOiJDYXBzTG9jayIsMjc6IkVzYyIsMzI6IlNwYWNlIiwzMzoiUGFnZVVwIiwzNDoiUGFnZURvd24iLDM1OiJFbmQiLDM2OiJIb21lIiwzNzoiTGVmdCIsMzg6IlVwIiwzOToiUmlnaHQiLDQwOiJEb3duIiw0NDoiUHJpbnRTY3JuIiw0NToiSW5zZXJ0Iiw0NjoiRGVsZXRlIiw1OToiOyIsOTE6Ik1vZCIsOTI6Ik1vZCIsOTM6Ik1vZCIsMTA5OiItIiwxMDc6Ij0iLDEyNzoiRGVsZXRlIiwxODY6IjsiLDE4NzoiPSIsMTg4OiIsIiwxODk6Ii0iLDE5MDoiLiIsMTkxOiIvIiwxOTI6ImAiLDIxOToiWyIsMjIwOiJcXCIsMjIxOiJdIiwyMjI6IiciLDYzMjc2OiJQYWdlVXAiLDYzMjc3OiJQYWdlRG93biIsNjMyNzU6IkVuZCIsNjMyNzM6IkhvbWUiLDYzMjM0OiJMZWZ0Iiw2MzIzMjoiVXAiLDYzMjM1OiJSaWdodCIsNjMyMzM6IkRvd24iLDYzMzAyOiJJbnNlcnQiLDYzMjcyOiJEZWxldGUifTt0LmtleU5hbWVzPVBvLGZ1bmN0aW9uKCl7Zm9yKHZhciB0PTA7MTA+dDt0KyspUG9bdCs0OF09U3RyaW5nKHQpO2Zvcih2YXIgdD02NTs5MD49dDt0KyspUG9bdF09U3RyaW5nLmZyb21DaGFyQ29kZSh0KTtmb3IodmFyIHQ9MTsxMj49dDt0KyspUG9bdCsxMTFdPVBvW3QrNjMyMzVdPSJGIit0fSgpO3ZhciBSbyxCbz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7cmV0dXJuIDI1NT49dD9lLmNoYXJBdCh0KTp0Pj0xNDI0JiYxNTI0Pj10PyJSIjp0Pj0xNTM2JiYxNzkxPj10P3IuY2hhckF0KHQtMTUzNik6dD49MTc5MiYmMjIyMD49dD8iciI6IkwifXZhciBlPSJiYmJiYmJiYmJ0c3R3c2JiYmJiYmJiYmJiYmJic3NzdHdOTiUlJU5OTk5OTixOLE4xMTExMTExMTExTk5OTk5OTkxMTExMTExMTExMTExMTExMTExMTExMTExMTk5OTk5OTExMTExMTExMTExMTExMTExMTExMTExMTExOTk5OYmJiYmJic2JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiLE4lJSUlTk5OTkxOTk5OTiUlMTFOTE5OTjFMTk5OTk5MTExMTExMTExMTExMTExMTExMTExMTE5MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTkxMTExMTExMIixyPSJycnJycnJycnJycnIsck5ObW1tbW1tcnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJtbW1tbW1tbW1tbW1tbXJycnJycnJubm5ubm5ubm5uJW5ucnJybXJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJybW1tbW1tbW1tbW1tbW1tbW1tbU5tbW1tcnJycnJycnJycnJycnJycnJyIixuPS9bXHUwNTkwLVx1MDVmNFx1MDYwMC1cdTA2ZmZcdTA3MDAtXHUwOGFjXS8saT0vW3N0d05dLyxvPS9bTFJyXS8sbD0vW0xiMW5dLyxzPS9bMW5dLyxhPSJMIjtyZXR1cm4gZnVuY3Rpb24oZSl7aWYoIW4udGVzdChlKSlyZXR1cm4hMTtmb3IodmFyIHIsdT1lLmxlbmd0aCxjPVtdLGY9MDt1PmY7KytmKWMucHVzaChyPXQoZS5jaGFyQ29kZUF0KGYpKSk7Zm9yKHZhciBmPTAsaD1hO3U+ZjsrK2Ype3ZhciByPWNbZl07Im0iPT1yP2NbZl09aDpoPXJ9Zm9yKHZhciBmPTAsZD1hO3U+ZjsrK2Ype3ZhciByPWNbZl07IjEiPT1yJiYiciI9PWQ/Y1tmXT0ibiI6by50ZXN0KHIpJiYoZD1yLCJyIj09ciYmKGNbZl09IlIiKSl9Zm9yKHZhciBmPTEsaD1jWzBdO3UtMT5mOysrZil7dmFyIHI9Y1tmXTsiKyI9PXImJiIxIj09aCYmIjEiPT1jW2YrMV0/Y1tmXT0iMSI6IiwiIT1yfHxoIT1jW2YrMV18fCIxIiE9aCYmIm4iIT1ofHwoY1tmXT1oKSxoPXJ9Zm9yKHZhciBmPTA7dT5mOysrZil7dmFyIHI9Y1tmXTtpZigiLCI9PXIpY1tmXT0iTiI7ZWxzZSBpZigiJSI9PXIpe2Zvcih2YXIgcD1mKzE7dT5wJiYiJSI9PWNbcF07KytwKTtmb3IodmFyIGc9ZiYmIiEiPT1jW2YtMV18fHUtMT5wJiYiMSI9PWNbcF0/IjEiOiJOIixtPWY7cD5tOysrbSljW21dPWc7Zj1wLTF9fWZvcih2YXIgZj0wLGQ9YTt1PmY7KytmKXt2YXIgcj1jW2ZdOyJMIj09ZCYmIjEiPT1yP2NbZl09IkwiOm8udGVzdChyKSYmKGQ9cil9Zm9yKHZhciBmPTA7dT5mOysrZilpZihpLnRlc3QoY1tmXSkpe2Zvcih2YXIgcD1mKzE7dT5wJiZpLnRlc3QoY1twXSk7KytwKTtmb3IodmFyIHY9IkwiPT0oZj9jW2YtMV06YSkseT0iTCI9PSh1LTE+cD9jW3BdOmEpLGc9dnx8eT8iTCI6IlIiLG09ZjtwPm07KyttKWNbbV09ZztmPXAtMX1mb3IodmFyIGIseD1bXSxmPTA7dT5mOylpZihsLnRlc3QoY1tmXSkpe3ZhciBDPWY7Zm9yKCsrZjt1PmYmJmwudGVzdChjW2ZdKTsrK2YpO3gucHVzaCh7ZnJvbTpDLHRvOmYsbGV2ZWw6MH0pfWVsc2V7dmFyIHc9ZixMPXgubGVuZ3RoO2ZvcigrK2Y7dT5mJiYiTCIhPWNbZl07KytmKTtmb3IodmFyIG09dztmPm07KWlmKHMudGVzdChjW21dKSl7bT53JiZ4LnNwbGljZShMLDAse2Zyb206dyx0bzptLGxldmVsOjF9KTt2YXIgaz1tO2ZvcigrK207Zj5tJiZzLnRlc3QoY1ttXSk7KyttKTt4LnNwbGljZShMLDAse2Zyb206ayx0bzptLGxldmVsOjJ9KSx3PW19ZWxzZSsrbTtmPncmJnguc3BsaWNlKEwsMCx7ZnJvbTp3LHRvOmYsbGV2ZWw6MX0pfXJldHVybiAxPT14WzBdLmxldmVsJiYoYj1lLm1hdGNoKC9eXHMrLykpJiYoeFswXS5mcm9tPWJbMF0ubGVuZ3RoLHgudW5zaGlmdCh7ZnJvbTowLHRvOmJbMF0ubGVuZ3RoLGxldmVsOjB9KSksMT09UW4oeCkubGV2ZWwmJihiPWUubWF0Y2goL1xzKyQvKSkmJihRbih4KS50by09YlswXS5sZW5ndGgseC5wdXNoKHtmcm9tOnUtYlswXS5sZW5ndGgsdG86dSxsZXZlbDowfSkpLHhbMF0ubGV2ZWwhPVFuKHgpLmxldmVsJiZ4LnB1c2goe2Zyb206dSx0bzp1LGxldmVsOnhbMF0ubGV2ZWx9KSx4fX0oKTtyZXR1cm4gdC52ZXJzaW9uPSIzLjIwLjAiLHR9KCk7UEsHCMZckbC/rwEAv68BAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAHN0YXRpY1xsaWJcaGlnaGxpZ2h0Lm1pbi5qc3ZhciBobGpzPW5ldyBmdW5jdGlvbigpe2Z1bmN0aW9uIGwobyl7cmV0dXJuIG8ucmVwbGFjZSgvJi9nbSwiJmFtcDsiKS5yZXBsYWNlKC88L2dtLCImbHQ7IikucmVwbGFjZSgvPi9nbSwiJmd0OyIpfWZ1bmN0aW9uIGIocCl7Zm9yKHZhciBvPXAuZmlyc3RDaGlsZDtvO289by5uZXh0U2libGluZyl7aWYoby5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpPT0iQ09ERSIpe3JldHVybiBvfWlmKCEoby5ub2RlVHlwZT09MyYmby5ub2RlVmFsdWUubWF0Y2goL1xzKy8pKSl7YnJlYWt9fX1mdW5jdGlvbiBoKHAsbyl7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChwLmNoaWxkTm9kZXMsZnVuY3Rpb24ocSl7aWYocS5ub2RlVHlwZT09Myl7cmV0dXJuIG8/cS5ub2RlVmFsdWUucmVwbGFjZSgvXG4vZywiIik6cS5ub2RlVmFsdWV9aWYocS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpPT0iQlIiKXtyZXR1cm4iXG4ifXJldHVybiBoKHEsbyl9KS5qb2luKCIiKX1mdW5jdGlvbiBhKHEpe3ZhciBwPShxLmNsYXNzTmFtZSsiICIrKHEucGFyZW50Tm9kZT9xLnBhcmVudE5vZGUuY2xhc3NOYW1lOiIiKSkuc3BsaXQoL1xzKy8pO3A9cC5tYXAoZnVuY3Rpb24ocil7cmV0dXJuIHIucmVwbGFjZSgvXmxhbmd1YWdlLS8sIiIpfSk7Zm9yKHZhciBvPTA7bzxwLmxlbmd0aDtvKyspe2lmKGVbcFtvXV18fHBbb109PSJuby1oaWdobGlnaHQiKXtyZXR1cm4gcFtvXX19fWZ1bmN0aW9uIGMocSl7dmFyIG89W107KGZ1bmN0aW9uIHAocixzKXtmb3IodmFyIHQ9ci5maXJzdENoaWxkO3Q7dD10Lm5leHRTaWJsaW5nKXtpZih0Lm5vZGVUeXBlPT0zKXtzKz10Lm5vZGVWYWx1ZS5sZW5ndGh9ZWxzZXtpZih0Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCk9PSJCUiIpe3MrPTF9ZWxzZXtpZih0Lm5vZGVUeXBlPT0xKXtvLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnMsbm9kZTp0fSk7cz1wKHQscyk7by5wdXNoKHtldmVudDoic3RvcCIsb2Zmc2V0OnMsbm9kZTp0fSl9fX19cmV0dXJuIHN9KShxLDApO3JldHVybiBvfWZ1bmN0aW9uIGoocCxyLHYpe3ZhciBxPTA7dmFyIHk9IiI7dmFyIHM9W107ZnVuY3Rpb24gdSgpe2lmKCFwLmxlbmd0aHx8IXIubGVuZ3RoKXtyZXR1cm4gcC5sZW5ndGg/cDpyfWlmKHBbMF0ub2Zmc2V0IT1yWzBdLm9mZnNldCl7cmV0dXJuKHBbMF0ub2Zmc2V0PHJbMF0ub2Zmc2V0KT9wOnJ9cmV0dXJuIHJbMF0uZXZlbnQ9PSJzdGFydCI/cDpyfWZ1bmN0aW9uIHQoQSl7ZnVuY3Rpb24geihCKXtyZXR1cm4iICIrQi5ub2RlTmFtZSsnPSInK2woQi52YWx1ZSkrJyInfXkrPSI8IitBLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkrQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKEEuYXR0cmlidXRlcyx6KS5qb2luKCIiKSsiPiJ9ZnVuY3Rpb24geCh6KXt5Kz0iPC8iK3oubm9kZU5hbWUudG9Mb3dlckNhc2UoKSsiPiJ9ZnVuY3Rpb24gbyh6KXsoei5ldmVudD09InN0YXJ0Ij90OngpKHoubm9kZSl9d2hpbGUocC5sZW5ndGh8fHIubGVuZ3RoKXt2YXIgdz11KCk7eSs9bCh2LnN1YnN0cihxLHdbMF0ub2Zmc2V0LXEpKTtxPXdbMF0ub2Zmc2V0O2lmKHc9PXApe3MucmV2ZXJzZSgpLmZvckVhY2goeCk7ZG97byh3LnNwbGljZSgwLDEpWzBdKTt3PXUoKX13aGlsZSh3PT1wJiZ3Lmxlbmd0aCYmd1swXS5vZmZzZXQ9PXEpO3MucmV2ZXJzZSgpLmZvckVhY2godCl9ZWxzZXtpZih3WzBdLmV2ZW50PT0ic3RhcnQiKXtzLnB1c2god1swXS5ub2RlKX1lbHNle3MucG9wKCl9byh3LnNwbGljZSgwLDEpWzBdKX19cmV0dXJuIHkrbCh2LnN1YnN0cihxKSl9ZnVuY3Rpb24gZihyKXtmdW5jdGlvbiBvKHMpe3JldHVybihzJiZzLnNvdXJjZSl8fHN9ZnVuY3Rpb24gcCh0LHMpe3JldHVybiBSZWdFeHAobyh0KSwibSIrKHIuY0k/ImkiOiIiKSsocz8iZyI6IiIpKX1mdW5jdGlvbiBxKHoseCl7aWYoei5jb21waWxlZCl7cmV0dXJufXouY29tcGlsZWQ9dHJ1ZTt2YXIgdT1bXTtpZih6Lmspe3ZhciBzPXt9O2Z1bmN0aW9uIEEoQix0KXtpZihyLmNJKXt0PXQudG9Mb3dlckNhc2UoKX10LnNwbGl0KCIgIikuZm9yRWFjaChmdW5jdGlvbihDKXt2YXIgRD1DLnNwbGl0KCJ8Iik7c1tEWzBdXT1bQixEWzFdP051bWJlcihEWzFdKToxXTt1LnB1c2goRFswXSl9KX16LmxSPXAoei5sfHwiXFxiIitobGpzLklSKyJcXGIoPyFcXC4pIix0cnVlKTtpZih0eXBlb2Ygei5rPT0ic3RyaW5nIil7QSgia2V5d29yZCIsei5rKX1lbHNle2Zvcih2YXIgeSBpbiB6Lmspe2lmKCF6LmsuaGFzT3duUHJvcGVydHkoeSkpe2NvbnRpbnVlfUEoeSx6LmtbeV0pfX16Lms9c31pZih4KXtpZih6LmJXSyl7ei5iPSJcXGIoIit1LmpvaW4oInwiKSsiKVxcYig/IVxcLilcXHMqIn16LmJSPXAoei5iP3ouYjoiXFxCfFxcYiIpO2lmKCF6LmUmJiF6LmVXKXt6LmU9IlxcQnxcXGIifWlmKHouZSl7ei5lUj1wKHouZSl9ei50RT1vKHouZSl8fCIiO2lmKHouZVcmJngudEUpe3oudEUrPSh6LmU/InwiOiIiKSt4LnRFfX1pZih6Lmkpe3ouaVI9cCh6LmkpfWlmKHoucj09PXVuZGVmaW5lZCl7ei5yPTF9aWYoIXouYyl7ei5jPVtdfWZvcih2YXIgdz0wO3c8ei5jLmxlbmd0aDt3Kyspe2lmKHouY1t3XT09InNlbGYiKXt6LmNbd109en1xKHouY1t3XSx6KX1pZih6LnN0YXJ0cyl7cSh6LnN0YXJ0cyx4KX12YXIgdj1bXTtmb3IodmFyIHc9MDt3PHouYy5sZW5ndGg7dysrKXt2LnB1c2gobyh6LmNbd10uYikpfWlmKHoudEUpe3YucHVzaChvKHoudEUpKX1pZih6Lmkpe3YucHVzaChvKHouaSkpfXoudD12Lmxlbmd0aD9wKHYuam9pbigifCIpLHRydWUpOntleGVjOmZ1bmN0aW9uKHQpe3JldHVybiBudWxsfX19cShyKX1mdW5jdGlvbiBkKEUsRyxDLE0pe2Z1bmN0aW9uIG8ocixQKXtmb3IodmFyIE89MDtPPFAuYy5sZW5ndGg7TysrKXt2YXIgTj1QLmNbT10uYlIuZXhlYyhyKTtpZihOJiZOLmluZGV4PT0wKXtyZXR1cm4gUC5jW09dfX19ZnVuY3Rpb24gcyhOLHIpe2lmKE4uZSYmTi5lUi50ZXN0KHIpKXtyZXR1cm4gTn1pZihOLmVXKXtyZXR1cm4gcyhOLnBhcmVudCxyKX19ZnVuY3Rpb24gdChyLE4pe3JldHVybiAhQyYmTi5pJiZOLmlSLnRlc3Qocil9ZnVuY3Rpb24geShPLHIpe3ZhciBOPUguY0k/clswXS50b0xvd2VyQ2FzZSgpOnJbMF07cmV0dXJuIE8uay5oYXNPd25Qcm9wZXJ0eShOKSYmTy5rW05dfWZ1bmN0aW9uIEkoKXt2YXIgTj1sKHcpO2lmKCFCLmspe3JldHVybiBOfXZhciByPSIiO3ZhciBRPTA7Qi5sUi5sYXN0SW5kZXg9MDt2YXIgTz1CLmxSLmV4ZWMoTik7d2hpbGUoTyl7cis9Ti5zdWJzdHIoUSxPLmluZGV4LVEpO3ZhciBQPXkoQixPKTtpZihQKXt2Kz1QWzFdO3IrPSc8c3BhbiBjbGFzcz0iJytQWzBdKyciPicrT1swXSsiPC9zcGFuPiJ9ZWxzZXtyKz1PWzBdfVE9Qi5sUi5sYXN0SW5kZXg7Tz1CLmxSLmV4ZWMoTil9cmV0dXJuIHIrTi5zdWJzdHIoUSl9ZnVuY3Rpb24geigpe2lmKEIuc0wmJiFlW0Iuc0xdKXtyZXR1cm4gbCh3KX12YXIgTj1CLnN1Ykxhbmd1YWdlTW9kZT09ImNvbnRpbnVvdXMiP0IudG9wOnVuZGVmaW5lZDt2YXIgcj1CLnNMP2QoQi5zTCx3LHRydWUsTik6Zyh3KTtpZihCLnI+MCl7dis9ci5rZXl3b3JkX2NvdW50O0ErPXIucn1CLnRvcD1yLnRvcDtyZXR1cm4nPHNwYW4gY2xhc3M9Iicrci5sYW5ndWFnZSsnIj4nK3IudmFsdWUrIjwvc3Bhbj4ifWZ1bmN0aW9uIEwoKXtyZXR1cm4gQi5zTCE9PXVuZGVmaW5lZD96KCk6SSgpfWZ1bmN0aW9uIEsoTyxyKXt2YXIgTj1PLmNOPyc8c3BhbiBjbGFzcz0iJytPLmNOKyciPic6IiI7aWYoTy5yQil7eCs9Tjt3PSIifWVsc2V7aWYoTy5lQil7eCs9bChyKStOO3c9IiJ9ZWxzZXt4Kz1OO3c9cn19Qj1PYmplY3QuY3JlYXRlKE8se3BhcmVudDp7dmFsdWU6Qn19KX1mdW5jdGlvbiBEKE4scil7dys9TjtpZihyPT09dW5kZWZpbmVkKXt4Kz1MKCk7cmV0dXJuIDB9dmFyIFA9byhyLEIpO2lmKFApe3grPUwoKTtLKFAscik7cmV0dXJuIFAuckI/MDpyLmxlbmd0aH12YXIgUT1zKEIscik7aWYoUSl7dmFyIE89QjtpZighKE8uckV8fE8uZUUpKXt3Kz1yfXgrPUwoKTtkb3tpZihCLmNOKXt4Kz0iPC9zcGFuPiJ9QSs9Qi5yO0I9Qi5wYXJlbnR9d2hpbGUoQiE9US5wYXJlbnQpO2lmKE8uZUUpe3grPWwocil9dz0iIjtpZihRLnN0YXJ0cyl7SyhRLnN0YXJ0cywiIil9cmV0dXJuIE8uckU/MDpyLmxlbmd0aH1pZih0KHIsQikpe3Rocm93IG5ldyBFcnJvcignSWxsZWdhbCBsZXhlbSAiJytyKyciIGZvciBtb2RlICInKyhCLmNOfHwiPHVubmFtZWQ+IikrJyInKX13Kz1yO3JldHVybiByLmxlbmd0aHx8MX12YXIgSD1lW0VdO2lmKCFIKXt0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK0UrJyInKX1mKEgpO3ZhciBCPU18fEg7dmFyIHg9IiI7Zm9yKHZhciBGPUI7RiE9SDtGPUYucGFyZW50KXtpZihGLmNOKXt4PSc8c3BhbiBjbGFzcz0iJytGLmNOKyciPicreH19dmFyIHc9IiI7dmFyIEE9MDt2YXIgdj0wO3RyeXt2YXIgdSxxLHA9MDt3aGlsZSh0cnVlKXtCLnQubGFzdEluZGV4PXA7dT1CLnQuZXhlYyhHKTtpZighdSl7YnJlYWt9cT1EKEcuc3Vic3RyKHAsdS5pbmRleC1wKSx1WzBdKTtwPXUuaW5kZXgrcX1EKEcuc3Vic3RyKHApKTtmb3IodmFyIEY9QjtGLnBhcmVudDtGPUYucGFyZW50KXtpZihGLmNOKXt4Kz0iPC9zcGFuPiJ9fXJldHVybntyOkEsa2V5d29yZF9jb3VudDp2LHZhbHVlOngsbGFuZ3VhZ2U6RSx0b3A6Qn19Y2F0Y2goSil7aWYoSi5tZXNzYWdlLmluZGV4T2YoIklsbGVnYWwiKSE9LTEpe3JldHVybntyOjAsa2V5d29yZF9jb3VudDowLHZhbHVlOmwoRyl9fWVsc2V7dGhyb3cgSn19fWZ1bmN0aW9uIGcocyl7dmFyIG89e2tleXdvcmRfY291bnQ6MCxyOjAsdmFsdWU6bChzKX07dmFyIHE9bztmb3IodmFyIHAgaW4gZSl7aWYoIWUuaGFzT3duUHJvcGVydHkocCkpe2NvbnRpbnVlfXZhciByPWQocCxzLGZhbHNlKTtyLmxhbmd1YWdlPXA7aWYoci5rZXl3b3JkX2NvdW50K3Iucj5xLmtleXdvcmRfY291bnQrcS5yKXtxPXJ9aWYoci5rZXl3b3JkX2NvdW50K3Iucj5vLmtleXdvcmRfY291bnQrby5yKXtxPW87bz1yfX1pZihxLmxhbmd1YWdlKXtvLnNlY29uZF9iZXN0PXF9cmV0dXJuIG99ZnVuY3Rpb24gaShxLHAsbyl7aWYocCl7cT1xLnJlcGxhY2UoL14oKDxbXj5dKz58XHQpKykvZ20sZnVuY3Rpb24ocix2LHUsdCl7cmV0dXJuIHYucmVwbGFjZSgvXHQvZyxwKX0pfWlmKG8pe3E9cS5yZXBsYWNlKC9cbi9nLCI8YnI+Iil9cmV0dXJuIHF9ZnVuY3Rpb24gbShyLHUscCl7dmFyIHY9aChyLHApO3ZhciB0PWEocik7aWYodD09Im5vLWhpZ2hsaWdodCIpe3JldHVybn12YXIgdz10P2QodCx2LHRydWUpOmcodik7dD13Lmxhbmd1YWdlO3ZhciBvPWMocik7aWYoby5sZW5ndGgpe3ZhciBxPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsInByZSIpO3EuaW5uZXJIVE1MPXcudmFsdWU7dy52YWx1ZT1qKG8sYyhxKSx2KX13LnZhbHVlPWkody52YWx1ZSx1LHApO3ZhciBzPXIuY2xhc3NOYW1lO2lmKCFzLm1hdGNoKCIoXFxzfF4pKGxhbmd1YWdlLSk/Iit0KyIoXFxzfCQpIikpe3M9cz8ocysiICIrdCk6dH1yLmlubmVySFRNTD13LnZhbHVlO3IuY2xhc3NOYW1lPXM7ci5yZXN1bHQ9e2xhbmd1YWdlOnQsa3c6dy5rZXl3b3JkX2NvdW50LHJlOncucn07aWYody5zZWNvbmRfYmVzdCl7ci5zZWNvbmRfYmVzdD17bGFuZ3VhZ2U6dy5zZWNvbmRfYmVzdC5sYW5ndWFnZSxrdzp3LnNlY29uZF9iZXN0LmtleXdvcmRfY291bnQscmU6dy5zZWNvbmRfYmVzdC5yfX19ZnVuY3Rpb24gbigpe2lmKG4uY2FsbGVkKXtyZXR1cm59bi5jYWxsZWQ9dHJ1ZTtBcnJheS5wcm90b3R5cGUubWFwLmNhbGwoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsInByZSIpLGIpLmZpbHRlcihCb29sZWFuKS5mb3JFYWNoKGZ1bmN0aW9uKG8pe20obyxobGpzLnRhYlJlcGxhY2UpfSl9ZnVuY3Rpb24gaygpe3dpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIixuLGZhbHNlKTt3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsbixmYWxzZSl9dmFyIGU9e307dGhpcy5MQU5HVUFHRVM9ZTt0aGlzLmhpZ2hsaWdodD1kO3RoaXMuaGlnaGxpZ2h0QXV0bz1nO3RoaXMuZml4TWFya3VwPWk7dGhpcy5oaWdobGlnaHRCbG9jaz1tO3RoaXMuaW5pdEhpZ2hsaWdodGluZz1uO3RoaXMuaW5pdEhpZ2hsaWdodGluZ09uTG9hZD1rO3RoaXMuSVI9IlthLXpBLVpdW2EtekEtWjAtOV9dKiI7dGhpcy5VSVI9IlthLXpBLVpfXVthLXpBLVowLTlfXSoiO3RoaXMuTlI9IlxcYlxcZCsoXFwuXFxkKyk/Ijt0aGlzLkNOUj0iKFxcYjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQrKT8pIjt0aGlzLkJOUj0iXFxiKDBiWzAxXSspIjt0aGlzLlJTUj0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8XFwufC18LT18L3wvPXw6fDt8PDx8PDw9fDw9fDx8PT09fD09fD18Pj4+PXw+Pj18Pj18Pj4+fD4+fD58XFw/fFxcW3xcXHt8XFwofFxcXnxcXF49fFxcfHxcXHw9fFxcfFxcfHx+Ijt0aGlzLkJFPXtiOiJcXFxcW1xcc1xcU10iLHI6MH07dGhpcy5BU009e2NOOiJzdHJpbmciLGI6IiciLGU6IiciLGk6IlxcbiIsYzpbdGhpcy5CRV0scjowfTt0aGlzLlFTTT17Y046InN0cmluZyIsYjonIicsZTonIicsaToiXFxuIixjOlt0aGlzLkJFXSxyOjB9O3RoaXMuQ0xDTT17Y046ImNvbW1lbnQiLGI6Ii8vIixlOiIkIn07dGhpcy5DQkxDTE09e2NOOiJjb21tZW50IixiOiIvXFwqIixlOiJcXCovIn07dGhpcy5IQ009e2NOOiJjb21tZW50IixiOiIjIixlOiIkIn07dGhpcy5OTT17Y046Im51bWJlciIsYjp0aGlzLk5SLHI6MH07dGhpcy5DTk09e2NOOiJudW1iZXIiLGI6dGhpcy5DTlIscjowfTt0aGlzLkJOTT17Y046Im51bWJlciIsYjp0aGlzLkJOUixyOjB9O3RoaXMuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxlOi9cL1tnaW1dKi8saTovXG4vLGM6W3RoaXMuQkUse2I6L1xbLyxlOi9cXS8scjowLGM6W3RoaXMuQkVdfV19O3RoaXMuaW5oZXJpdD1mdW5jdGlvbihxLHIpe3ZhciBvPXt9O2Zvcih2YXIgcCBpbiBxKXtvW3BdPXFbcF19aWYocil7Zm9yKHZhciBwIGluIHIpe29bcF09cltwXX19cmV0dXJuIG99fSgpO2hsanMuTEFOR1VBR0VTLmJhc2g9ZnVuY3Rpb24oYSl7dmFyIGM9e2NOOiJ2YXJpYWJsZSIsYjovXCRbXHdcZCNAXVtcd1xkX10qL307dmFyIGI9e2NOOiJ2YXJpYWJsZSIsYjovXCRceyguKj8pXH0vfTt2YXIgZT17Y046InN0cmluZyIsYjovIi8sZTovIi8sYzpbYS5CRSxjLGIse2NOOiJ2YXJpYWJsZSIsYjovXCRcKC8sZTovXCkvLGM6YS5CRX1dLHI6MH07dmFyIGQ9e2NOOiJzdHJpbmciLGI6LycvLGU6LycvLHI6MH07cmV0dXJue2w6Ly0/W2Etel0rLyxrOntrZXl3b3JkOiJpZiB0aGVuIGVsc2UgZWxpZiBmaSBmb3IgYnJlYWsgY29udGludWUgd2hpbGUgaW4gZG8gZG9uZSBleGl0IHJldHVybiBzZXQgZGVjbGFyZSBjYXNlIGVzYWMgZXhwb3J0IGV4ZWMiLGxpdGVyYWw6InRydWUgZmFsc2UiLGJ1aWx0X2luOiJwcmludGYgZWNobyByZWFkIGNkIHB3ZCBwdXNoZCBwb3BkIGRpcnMgbGV0IGV2YWwgdW5zZXQgdHlwZXNldCByZWFkb25seSBnZXRvcHRzIHNvdXJjZSBzaG9wdCBjYWxsZXIgdHlwZSBoYXNoIGJpbmQgaGVscCBzdWRvIixvcGVyYXRvcjoiLW5lIC1lcSAtbHQgLWd0IC1mIC1kIC1lIC1zIC1sIC1hIn0sYzpbe2NOOiJzaGViYW5nIixiOi9eIyFbXlxuXStzaFxzKiQvLHI6MTB9LHtjTjoiZnVuY3Rpb24iLGI6L1x3W1x3XGRfXSpccypcKFxzKlwpXHMqXHsvLHJCOnRydWUsYzpbe2NOOiJ0aXRsZSIsYjovXHdbXHdcZF9dKi99XSxyOjB9LGEuSENNLGEuTk0sZSxkLGMsYl19fShobGpzKTtobGpzLkxBTkdVQUdFUy5jcz1mdW5jdGlvbihhKXtyZXR1cm57azoiYWJzdHJhY3QgYXMgYmFzZSBib29sIGJyZWFrIGJ5dGUgY2FzZSBjYXRjaCBjaGFyIGNoZWNrZWQgY2xhc3MgY29uc3QgY29udGludWUgZGVjaW1hbCBkZWZhdWx0IGRlbGVnYXRlIGRvIGRvdWJsZSBlbHNlIGVudW0gZXZlbnQgZXhwbGljaXQgZXh0ZXJuIGZhbHNlIGZpbmFsbHkgZml4ZWQgZmxvYXQgZm9yIGZvcmVhY2ggZ290byBpZiBpbXBsaWNpdCBpbiBpbnQgaW50ZXJmYWNlIGludGVybmFsIGlzIGxvY2sgbG9uZyBuYW1lc3BhY2UgbmV3IG51bGwgb2JqZWN0IG9wZXJhdG9yIG91dCBvdmVycmlkZSBwYXJhbXMgcHJpdmF0ZSBwcm90ZWN0ZWQgcHVibGljIHJlYWRvbmx5IHJlZiByZXR1cm4gc2J5dGUgc2VhbGVkIHNob3J0IHNpemVvZiBzdGFja2FsbG9jIHN0YXRpYyBzdHJpbmcgc3RydWN0IHN3aXRjaCB0aGlzIHRocm93IHRydWUgdHJ5IHR5cGVvZiB1aW50IHVsb25nIHVuY2hlY2tlZCB1bnNhZmUgdXNob3J0IHVzaW5nIHZpcnR1YWwgdm9sYXRpbGUgdm9pZCB3aGlsZSBhc3luYyBhd2FpdCBhc2NlbmRpbmcgZGVzY2VuZGluZyBmcm9tIGdldCBncm91cCBpbnRvIGpvaW4gbGV0IG9yZGVyYnkgcGFydGlhbCBzZWxlY3Qgc2V0IHZhbHVlIHZhciB3aGVyZSB5aWVsZCIsYzpbe2NOOiJjb21tZW50IixiOiIvLy8iLGU6IiQiLHJCOnRydWUsYzpbe2NOOiJ4bWxEb2NUYWciLGI6Ii8vL3w8IS0tfC0tPiJ9LHtjTjoieG1sRG9jVGFnIixiOiI8Lz8iLGU6Ij4ifV19LGEuQ0xDTSxhLkNCTENMTSx7Y046InByZXByb2Nlc3NvciIsYjoiIyIsZToiJCIsazoiaWYgZWxzZSBlbGlmIGVuZGlmIGRlZmluZSB1bmRlZiB3YXJuaW5nIGVycm9yIGxpbmUgcmVnaW9uIGVuZHJlZ2lvbiBwcmFnbWEgY2hlY2tzdW0ifSx7Y046InN0cmluZyIsYjonQCInLGU6JyInLGM6W3tiOiciIid9XX0sYS5BU00sYS5RU00sYS5DTk1dfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMucnVieT1mdW5jdGlvbihlKXt2YXIgYT0iW2EtekEtWl9dW2EtekEtWjAtOV9dKihcXCF8XFw/KT8iO3ZhciBqPSJbYS16QS1aX11cXHcqWyE/PV0/fFstK35dXFxAfDw8fD4+fD1+fD09PT98PD0+fFs8Pl09P3xcXCpcXCp8Wy0vKyVeJip+YHxdfFxcW1xcXT0/Ijt2YXIgZz17a2V5d29yZDoiYW5kIGZhbHNlIHRoZW4gZGVmaW5lZCBtb2R1bGUgaW4gcmV0dXJuIHJlZG8gaWYgQkVHSU4gcmV0cnkgZW5kIGZvciB0cnVlIHNlbGYgd2hlbiBuZXh0IHVudGlsIGRvIGJlZ2luIHVubGVzcyBFTkQgcmVzY3VlIG5pbCBlbHNlIGJyZWFrIHVuZGVmIG5vdCBzdXBlciBjbGFzcyBjYXNlIHJlcXVpcmUgeWllbGQgYWxpYXMgd2hpbGUgZW5zdXJlIGVsc2lmIG9yIGluY2x1ZGUifTt2YXIgYz17Y046InlhcmRvY3RhZyIsYjoiQFtBLVphLXpdKyJ9O3ZhciBrPVt7Y046ImNvbW1lbnQiLGI6IiMiLGU6IiQiLGM6W2NdfSx7Y046ImNvbW1lbnQiLGI6Il5cXD1iZWdpbiIsZToiXlxcPWVuZCIsYzpbY10scjoxMH0se2NOOiJjb21tZW50IixiOiJeX19FTkRfXyIsZToiXFxuJCJ9XTt2YXIgZD17Y046InN1YnN0IixiOiIjXFx7IixlOiJ9IixsOmEsazpnfTt2YXIgaT1bZS5CRSxkXTt2YXIgYj1be2NOOiJzdHJpbmciLGI6IiciLGU6IiciLGM6aSxyOjB9LHtjTjoic3RyaW5nIixiOiciJyxlOiciJyxjOmkscjowfSx7Y046InN0cmluZyIsYjoiJVtxd10/XFwoIixlOiJcXCkiLGM6aX0se2NOOiJzdHJpbmciLGI6IiVbcXddP1xcWyIsZToiXFxdIixjOml9LHtjTjoic3RyaW5nIixiOiIlW3F3XT97IixlOiJ9IixjOml9LHtjTjoic3RyaW5nIixiOiIlW3F3XT88IixlOiI+IixjOmkscjoxMH0se2NOOiJzdHJpbmciLGI6IiVbcXddPy8iLGU6Ii8iLGM6aSxyOjEwfSx7Y046InN0cmluZyIsYjoiJVtxd10/JSIsZToiJSIsYzppLHI6MTB9LHtjTjoic3RyaW5nIixiOiIlW3F3XT8tIixlOiItIixjOmkscjoxMH0se2NOOiJzdHJpbmciLGI6IiVbcXddP1xcfCIsZToiXFx8IixjOmkscjoxMH0se2NOOiJzdHJpbmciLGI6L1xCXD8oXFxcZHsxLDN9fFxceFtBLUZhLWYwLTldezEsMn18XFx1W0EtRmEtZjAtOV17NH18XFw/XFMpXGIvfV07dmFyIGg9e2NOOiJmdW5jdGlvbiIsYldLOnRydWUsZToiIHwkfDsiLGs6ImRlZiIsYzpbe2NOOiJ0aXRsZSIsYjpqLGw6YSxrOmd9LHtjTjoicGFyYW1zIixiOiJcXCgiLGU6IlxcKSIsbDphLGs6Z31dLmNvbmNhdChrKX07dmFyIGY9ay5jb25jYXQoYi5jb25jYXQoW3tjTjoiY2xhc3MiLGJXSzp0cnVlLGU6IiR8OyIsazoiY2xhc3MgbW9kdWxlIixjOlt7Y046InRpdGxlIixiOiJbQS1aYS16X11cXHcqKDo6XFx3KykqKFxcP3xcXCEpPyIscjowfSx7Y046ImluaGVyaXRhbmNlIixiOiI8XFxzKiIsYzpbe2NOOiJwYXJlbnQiLGI6IigiK2UuSVIrIjo6KT8iK2UuSVJ9XX1dLmNvbmNhdChrKX0saCx7Y046ImNvbnN0YW50IixiOiIoOjopPyhcXGJbQS1aXVxcdyooOjopPykrIixyOjB9LHtjTjoic3ltYm9sIixiOiI6IixjOmIuY29uY2F0KFt7YjpqfV0pLHI6MH0se2NOOiJzeW1ib2wiLGI6YSsiOiIscjowfSx7Y046Im51bWJlciIsYjoiKFxcYjBbMC03X10rKXwoXFxiMHhbMC05YS1mQS1GX10rKXwoXFxiWzEtOV1bMC05X10qKFxcLlswLTlfXSspPyl8WzBfXVxcYiIscjowfSx7Y046InZhcmlhYmxlIixiOiIoXFwkXFxXKXwoKFxcJHxcXEBcXEA/KShcXHcrKSkifSx7YjoiKCIrZS5SU1IrIilcXHMqIixjOmsuY29uY2F0KFt7Y046InJlZ2V4cCIsYjoiLyIsZToiL1thLXpdKiIsaToiXFxuIixjOltlLkJFLGRdfSx7Y046InJlZ2V4cCIsYjoiJXJ7IixlOiJ9W2Etel0qIixpOiJcXG4iLGM6W2UuQkUsZF19LHtjTjoicmVnZXhwIixiOiIlclxcKCIsZToiXFwpW2Etel0qIixpOiJcXG4iLGM6W2UuQkUsZF19LHtjTjoicmVnZXhwIixiOiIlciEiLGU6IiFbYS16XSoiLGk6IlxcbiIsYzpbZS5CRSxkXX0se2NOOiJyZWdleHAiLGI6IiVyXFxbIixlOiJcXF1bYS16XSoiLGk6IlxcbiIsYzpbZS5CRSxkXX1dKSxyOjB9XSkpO2QuYz1mO2guY1sxXS5jPWY7cmV0dXJue2w6YSxrOmcsYzpmfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMuZGlmZj1mdW5jdGlvbihhKXtyZXR1cm57Yzpbe2NOOiJjaHVuayIsYjoiXlxcQFxcQCArXFwtXFxkKyxcXGQrICtcXCtcXGQrLFxcZCsgK1xcQFxcQCQiLHI6MTB9LHtjTjoiY2h1bmsiLGI6Il5cXCpcXCpcXCogK1xcZCssXFxkKyArXFwqXFwqXFwqXFwqJCIscjoxMH0se2NOOiJjaHVuayIsYjoiXlxcLVxcLVxcLSArXFxkKyxcXGQrICtcXC1cXC1cXC1cXC0kIixyOjEwfSx7Y046ImhlYWRlciIsYjoiSW5kZXg6ICIsZToiJCJ9LHtjTjoiaGVhZGVyIixiOiI9PT09PSIsZToiPT09PT0kIn0se2NOOiJoZWFkZXIiLGI6Il5cXC1cXC1cXC0iLGU6IiQifSx7Y046ImhlYWRlciIsYjoiXlxcKnszfSAiLGU6IiQifSx7Y046ImhlYWRlciIsYjoiXlxcK1xcK1xcKyIsZToiJCJ9LHtjTjoiaGVhZGVyIixiOiJcXCp7NX0iLGU6IlxcKns1fSQifSx7Y046ImFkZGl0aW9uIixiOiJeXFwrIixlOiIkIn0se2NOOiJkZWxldGlvbiIsYjoiXlxcLSIsZToiJCJ9LHtjTjoiY2hhbmdlIixiOiJeXFwhIixlOiIkIn1dfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMuamF2YXNjcmlwdD1mdW5jdGlvbihhKXtyZXR1cm57azp7a2V5d29yZDoiaW4gaWYgZm9yIHdoaWxlIGZpbmFsbHkgdmFyIG5ldyBmdW5jdGlvbiBkbyByZXR1cm4gdm9pZCBlbHNlIGJyZWFrIGNhdGNoIGluc3RhbmNlb2Ygd2l0aCB0aHJvdyBjYXNlIGRlZmF1bHQgdHJ5IHRoaXMgc3dpdGNoIGNvbnRpbnVlIHR5cGVvZiBkZWxldGUgbGV0IHlpZWxkIGNvbnN0IixsaXRlcmFsOiJ0cnVlIGZhbHNlIG51bGwgdW5kZWZpbmVkIE5hTiBJbmZpbml0eSJ9LGM6W2EuQVNNLGEuUVNNLGEuQ0xDTSxhLkNCTENMTSxhLkNOTSx7YjoiKCIrYS5SU1IrInxcXGIoY2FzZXxyZXR1cm58dGhyb3cpXFxiKVxccyoiLGs6InJldHVybiB0aHJvdyBjYXNlIixjOlthLkNMQ00sYS5DQkxDTE0sYS5SRUdFWFBfTU9ERSx7YjovPC8sZTovPjsvLHNMOiJ4bWwifV0scjowfSx7Y046ImZ1bmN0aW9uIixiV0s6dHJ1ZSxlOi97LyxrOiJmdW5jdGlvbiIsYzpbe2NOOiJ0aXRsZSIsYjovW0EtWmEteiRfXVswLTlBLVphLXokX10qL30se2NOOiJwYXJhbXMiLGI6L1woLyxlOi9cKS8sYzpbYS5DTENNLGEuQ0JMQ0xNXSxpOi9bIidcKF0vfV0saTovXFt8JS99XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLnhtbD1mdW5jdGlvbihhKXt2YXIgYz0iW0EtWmEtejAtOVxcLl86LV0rIjt2YXIgYj17ZVc6dHJ1ZSxyOjAsYzpbe2NOOiJhdHRyaWJ1dGUiLGI6YyxyOjB9LHtiOic9IicsckI6dHJ1ZSxlOiciJyxjOlt7Y046InZhbHVlIixiOiciJyxlVzp0cnVlfV19LHtiOiI9JyIsckI6dHJ1ZSxlOiInIixjOlt7Y046InZhbHVlIixiOiInIixlVzp0cnVlfV19LHtiOiI9IixjOlt7Y046InZhbHVlIixiOiJbXlxccy8+XSsifV19XX07cmV0dXJue2NJOnRydWUsYzpbe2NOOiJwaSIsYjoiPFxcPyIsZToiXFw/PiIscjoxMH0se2NOOiJkb2N0eXBlIixiOiI8IURPQ1RZUEUiLGU6Ij4iLHI6MTAsYzpbe2I6IlxcWyIsZToiXFxdIn1dfSx7Y046ImNvbW1lbnQiLGI6IjwhLS0iLGU6Ii0tPiIscjoxMH0se2NOOiJjZGF0YSIsYjoiPFxcIVxcW0NEQVRBXFxbIixlOiJcXF1cXF0+IixyOjEwfSx7Y046InRhZyIsYjoiPHN0eWxlKD89XFxzfD58JCkiLGU6Ij4iLGs6e3RpdGxlOiJzdHlsZSJ9LGM6W2JdLHN0YXJ0czp7ZToiPC9zdHlsZT4iLHJFOnRydWUsc0w6ImNzcyJ9fSx7Y046InRhZyIsYjoiPHNjcmlwdCg/PVxcc3w+fCQpIixlOiI+IixrOnt0aXRsZToic2NyaXB0In0sYzpbYl0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTp0cnVlLHNMOiJqYXZhc2NyaXB0In19LHtiOiI8JSIsZToiJT4iLHNMOiJ2YnNjcmlwdCJ9LHtjTjoidGFnIixiOiI8Lz8iLGU6Ii8/PiIscjowLGM6W3tjTjoidGl0bGUiLGI6IlteIC8+PF0rIn0sYl19XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLm1hcmtkb3duPWZ1bmN0aW9uKGEpe3JldHVybntjOlt7Y046ImhlYWRlciIsYjoiXiN7MSwzfSIsZToiJCJ9LHtjTjoiaGVhZGVyIixiOiJeLis/XFxuWz0tXXsyLH0kIn0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxsZXQiLGI6Il4oWyorLV18KFxcZCtcXC4pKVxccysifSx7Y046InN0cm9uZyIsYjoiWypfXXsyfS4rP1sqX117Mn0ifSx7Y046ImVtcGhhc2lzIixiOiJcXCouKz9cXCoifSx7Y046ImVtcGhhc2lzIixiOiJfLis/XyIscjowfSx7Y046ImJsb2NrcXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsYjoiYC4rP2AifSx7Y046ImNvZGUiLGI6Il4gICAgIixlOiIkIixyOjB9LHtjTjoiaG9yaXpvbnRhbF9ydWxlIixiOiJeLXszLH0iLGU6IiQifSx7YjoiXFxbLis/XFxdXFwoLis/XFwpIixyQjp0cnVlLGM6W3tjTjoibGlua19sYWJlbCIsYjoiXFxbLitcXF0ifSx7Y046ImxpbmtfdXJsIixiOiJcXCgiLGU6IlxcKSIsZUI6dHJ1ZSxlRTp0cnVlfV19XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLmNzcz1mdW5jdGlvbihhKXt2YXIgYj0iW2EtekEtWi1dW2EtekEtWjAtOV8tXSoiO3ZhciBjPXtjTjoiZnVuY3Rpb24iLGI6YisiXFwoIixlOiJcXCkiLGM6WyJzZWxmIixhLk5NLGEuQVNNLGEuUVNNXX07cmV0dXJue2NJOnRydWUsaToiWz0vfCddIixjOlthLkNCTENMTSx7Y046ImlkIixiOiJcXCNbQS1aYS16MC05Xy1dKyJ9LHtjTjoiY2xhc3MiLGI6IlxcLltBLVphLXowLTlfLV0rIixyOjB9LHtjTjoiYXR0cl9zZWxlY3RvciIsYjoiXFxbIixlOiJcXF0iLGk6IiQifSx7Y046InBzZXVkbyIsYjoiOig6KT9bYS16QS1aMC05XFxfXFwtXFwrXFwoXFwpXFxcIlxcJ10rIn0se2NOOiJhdF9ydWxlIixiOiJAKGZvbnQtZmFjZXxwYWdlKSIsbDoiW2Etei1dKyIsazoiZm9udC1mYWNlIHBhZ2UifSx7Y046ImF0X3J1bGUiLGI6IkAiLGU6Ilt7O10iLGM6W3tjTjoia2V5d29yZCIsYjovXFMrL30se2I6L1xzLyxlVzp0cnVlLGVFOnRydWUscjowLGM6W2MsYS5BU00sYS5RU00sYS5OTV19XX0se2NOOiJ0YWciLGI6YixyOjB9LHtjTjoicnVsZXMiLGI6InsiLGU6In0iLGk6IlteXFxzXSIscjowLGM6W2EuQ0JMQ0xNLHtjTjoicnVsZSIsYjoiW15cXHNdIixyQjp0cnVlLGU6IjsiLGVXOnRydWUsYzpbe2NOOiJhdHRyaWJ1dGUiLGI6IltBLVpcXF9cXC5cXC1dKyIsZToiOiIsZUU6dHJ1ZSxpOiJbXlxcc10iLHN0YXJ0czp7Y046InZhbHVlIixlVzp0cnVlLGVFOnRydWUsYzpbYyxhLk5NLGEuUVNNLGEuQVNNLGEuQ0JMQ0xNLHtjTjoiaGV4Y29sb3IiLGI6IiNbMC05QS1GYS1mXSsifSx7Y046ImltcG9ydGFudCIsYjoiIWltcG9ydGFudCJ9XX19XX1dfV19fShobGpzKTtobGpzLkxBTkdVQUdFUy5odHRwPWZ1bmN0aW9uKGEpe3JldHVybntpOiJcXFMiLGM6W3tjTjoic3RhdHVzIixiOiJeSFRUUC9bMC05XFwuXSsiLGU6IiQiLGM6W3tjTjoibnVtYmVyIixiOiJcXGJcXGR7M31cXGIifV19LHtjTjoicmVxdWVzdCIsYjoiXltBLVpdKyAoLio/KSBIVFRQL1swLTlcXC5dKyQiLHJCOnRydWUsZToiJCIsYzpbe2NOOiJzdHJpbmciLGI6IiAiLGU6IiAiLGVCOnRydWUsZUU6dHJ1ZX1dfSx7Y046ImF0dHJpYnV0ZSIsYjoiXlxcdyIsZToiOiAiLGVFOnRydWUsaToiXFxufFxcc3w9IixzdGFydHM6e2NOOiJzdHJpbmciLGU6IiQifX0se2I6IlxcblxcbiIsc3RhcnRzOntzTDoiIixlVzp0cnVlfX1dfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMuamF2YT1mdW5jdGlvbihhKXtyZXR1cm57azoiZmFsc2Ugc3luY2hyb25pemVkIGludCBhYnN0cmFjdCBmbG9hdCBwcml2YXRlIGNoYXIgYm9vbGVhbiBzdGF0aWMgbnVsbCBpZiBjb25zdCBmb3IgdHJ1ZSB3aGlsZSBsb25nIHRocm93IHN0cmljdGZwIGZpbmFsbHkgcHJvdGVjdGVkIGltcG9ydCBuYXRpdmUgZmluYWwgcmV0dXJuIHZvaWQgZW51bSBlbHNlIGJyZWFrIHRyYW5zaWVudCBuZXcgY2F0Y2ggaW5zdGFuY2VvZiBieXRlIHN1cGVyIHZvbGF0aWxlIGNhc2UgYXNzZXJ0IHNob3J0IHBhY2thZ2UgZGVmYXVsdCBkb3VibGUgcHVibGljIHRyeSB0aGlzIHN3aXRjaCBjb250aW51ZSB0aHJvd3MiLGM6W3tjTjoiamF2YWRvYyIsYjoiL1xcKlxcKiIsZToiXFwqLyIsYzpbe2NOOiJqYXZhZG9jdGFnIixiOiIoXnxcXHMpQFtBLVphLXpdKyJ9XSxyOjEwfSxhLkNMQ00sYS5DQkxDTE0sYS5BU00sYS5RU00se2NOOiJjbGFzcyIsYldLOnRydWUsZToieyIsazoiY2xhc3MgaW50ZXJmYWNlIixlRTp0cnVlLGk6IjoiLGM6W3tiV0s6dHJ1ZSxrOiJleHRlbmRzIGltcGxlbWVudHMiLHI6MTB9LHtjTjoidGl0bGUiLGI6YS5VSVJ9XX0sYS5DTk0se2NOOiJhbm5vdGF0aW9uIixiOiJAW0EtWmEtel0rIn1dfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMucGhwPWZ1bmN0aW9uKGEpe3ZhciBlPXtjTjoidmFyaWFibGUiLGI6IlxcJCtbYS16QS1aX1x4N2YtXHhmZl1bYS16QS1aMC05X1x4N2YtXHhmZl0qIn07dmFyIGI9W2EuaW5oZXJpdChhLkFTTSx7aTpudWxsfSksYS5pbmhlcml0KGEuUVNNLHtpOm51bGx9KSx7Y046InN0cmluZyIsYjonYiInLGU6JyInLGM6W2EuQkVdfSx7Y046InN0cmluZyIsYjoiYiciLGU6IiciLGM6W2EuQkVdfV07dmFyIGM9W2EuQk5NLGEuQ05NXTt2YXIgZD17Y046InRpdGxlIixiOmEuVUlSfTtyZXR1cm57Y0k6dHJ1ZSxsOmEuVUlSLGs6ImFuZCBpbmNsdWRlX29uY2UgbGlzdCBhYnN0cmFjdCBnbG9iYWwgcHJpdmF0ZSBlY2hvIGludGVyZmFjZSBhcyBzdGF0aWMgZW5kc3dpdGNoIGFycmF5IG51bGwgaWYgZW5kd2hpbGUgb3IgY29uc3QgZm9yIGVuZGZvcmVhY2ggc2VsZiB2YXIgd2hpbGUgaXNzZXQgcHVibGljIHByb3RlY3RlZCBleGl0IGZvcmVhY2ggdGhyb3cgZWxzZWlmIGluY2x1ZGUgX19GSUxFX18gZW1wdHkgcmVxdWlyZV9vbmNlIGRvIHhvciByZXR1cm4gaW1wbGVtZW50cyBwYXJlbnQgY2xvbmUgdXNlIF9fQ0xBU1NfXyBfX0xJTkVfXyBlbHNlIGJyZWFrIHByaW50IGV2YWwgbmV3IGNhdGNoIF9fTUVUSE9EX18gY2FzZSBleGNlcHRpb24gZGVmYXVsdCBkaWUgcmVxdWlyZSBfX0ZVTkNUSU9OX18gZW5kZGVjbGFyZSBmaW5hbCB0cnkgdGhpcyBzd2l0Y2ggY29udGludWUgZW5kZm9yIGVuZGlmIGRlY2xhcmUgdW5zZXQgdHJ1ZSBmYWxzZSBuYW1lc3BhY2UgdHJhaXQgZ290byBpbnN0YW5jZW9mIGluc3RlYWRvZiBfX0RJUl9fIF9fTkFNRVNQQUNFX18geWllbGQgZmluYWxseSIsYzpbYS5DTENNLGEuSENNLHtjTjoiY29tbWVudCIsYjoiL1xcKiIsZToiXFwqLyIsYzpbe2NOOiJwaHBkb2MiLGI6Ilxcc0BbQS1aYS16XSsifV19LHtjTjoiY29tbWVudCIsYjoiX19oYWx0X2NvbXBpbGVyLis/OyIsZVc6dHJ1ZSxrOiJfX2hhbHRfY29tcGlsZXIiLGw6YS5VSVJ9LHtjTjoic3RyaW5nIixiOiI8PDxbJ1wiXT9cXHcrWydcIl0/JCIsZToiXlxcdys7IixjOlthLkJFXX0se2NOOiJwcmVwcm9jZXNzb3IiLGI6IjxcXD9waHAiLHI6MTB9LHtjTjoicHJlcHJvY2Vzc29yIixiOiJcXD8+In0sZSx7Y046ImZ1bmN0aW9uIixiV0s6dHJ1ZSxlOiJ7IixrOiJmdW5jdGlvbiIsaToiXFwkfFxcW3wlIixjOltkLHtjTjoicGFyYW1zIixiOiJcXCgiLGU6IlxcKSIsYzpbInNlbGYiLGUsYS5DQkxDTE1dLmNvbmNhdChiKS5jb25jYXQoYyl9XX0se2NOOiJjbGFzcyIsYldLOnRydWUsZToieyIsazoiY2xhc3MiLGk6Ils6XFwoXFwkXSIsYzpbe2JXSzp0cnVlLGVXOnRydWUsazoiZXh0ZW5kcyIsYzpbZF19LGRdfSx7YjoiPT4ifV0uY29uY2F0KGIpLmNvbmNhdChjKX19KGhsanMpO2hsanMuTEFOR1VBR0VTLnB5dGhvbj1mdW5jdGlvbihhKXt2YXIgZj17Y046InByb21wdCIsYjovXig+Pj58XC5cLlwuKSAvfTt2YXIgYz1be2NOOiJzdHJpbmciLGI6Lyh1fGIpP3I/JycnLyxlOi8nJycvLGM6W2ZdLHI6MTB9LHtjTjoic3RyaW5nIixiOi8odXxiKT9yPyIiIi8sZTovIiIiLyxjOltmXSxyOjEwfSx7Y046InN0cmluZyIsYjovKHV8cnx1ciknLyxlOi8nLyxjOlthLkJFXSxyOjEwfSx7Y046InN0cmluZyIsYjovKHV8cnx1cikiLyxlOi8iLyxjOlthLkJFXSxyOjEwfSx7Y046InN0cmluZyIsYjovKGJ8YnIpJy8sZTovJy8sYzpbYS5CRV19LHtjTjoic3RyaW5nIixiOi8oYnxicikiLyxlOi8iLyxjOlthLkJFXX1dLmNvbmNhdChbYS5BU00sYS5RU01dKTt2YXIgZT17Y046InRpdGxlIixiOmEuVUlSfTt2YXIgZD17Y046InBhcmFtcyIsYjovXCgvLGU6L1wpLyxjOlsic2VsZiIsYS5DTk0sZl0uY29uY2F0KGMpfTt2YXIgYj17YldLOnRydWUsZTovOi8saTovWyR7PTtcbl0vLGM6W2UsZF0scjoxMH07cmV0dXJue2s6e2tleXdvcmQ6ImFuZCBlbGlmIGlzIGdsb2JhbCBhcyBpbiBpZiBmcm9tIHJhaXNlIGZvciBleGNlcHQgZmluYWxseSBwcmludCBpbXBvcnQgcGFzcyByZXR1cm4gZXhlYyBlbHNlIGJyZWFrIG5vdCB3aXRoIGNsYXNzIGFzc2VydCB5aWVsZCB0cnkgd2hpbGUgY29udGludWUgZGVsIG9yIGRlZiBsYW1iZGEgbm9ubG9jYWx8MTAgTm9uZSBUcnVlIEZhbHNlIixidWlsdF9pbjoiRWxsaXBzaXMgTm90SW1wbGVtZW50ZWQifSxpOi8oPFwvfC0+fFw/KS8sYzpjLmNvbmNhdChbZixhLkhDTSxhLmluaGVyaXQoYix7Y046ImZ1bmN0aW9uIixrOiJkZWYifSksYS5pbmhlcml0KGIse2NOOiJjbGFzcyIsazoiY2xhc3MifSksYS5DTk0se2NOOiJkZWNvcmF0b3IiLGI6L0AvLGU6LyQvfSx7YjovXGIocHJpbnR8ZXhlYylcKC99XSl9fShobGpzKTtobGpzLkxBTkdVQUdFUy5zcWw9ZnVuY3Rpb24oYSl7cmV0dXJue2NJOnRydWUsYzpbe2NOOiJvcGVyYXRvciIsYjoiKGJlZ2lufGVuZHxzdGFydHxjb21taXR8cm9sbGJhY2t8c2F2ZXBvaW50fGxvY2t8YWx0ZXJ8Y3JlYXRlfGRyb3B8cmVuYW1lfGNhbGx8ZGVsZXRlfGRvfGhhbmRsZXJ8aW5zZXJ0fGxvYWR8cmVwbGFjZXxzZWxlY3R8dHJ1bmNhdGV8dXBkYXRlfHNldHxzaG93fHByYWdtYXxncmFudClcXGIoPyE6KSIsZToiOyIsZVc6dHJ1ZSxrOntrZXl3b3JkOiJhbGwgcGFydGlhbCBnbG9iYWwgbW9udGggY3VycmVudF90aW1lc3RhbXAgdXNpbmcgZ28gcmV2b2tlIHNtYWxsaW50IGluZGljYXRvciBlbmQtZXhlYyBkaXNjb25uZWN0IHpvbmUgd2l0aCBjaGFyYWN0ZXIgYXNzZXJ0aW9uIHRvIGFkZCBjdXJyZW50X3VzZXIgdXNhZ2UgaW5wdXQgbG9jYWwgYWx0ZXIgbWF0Y2ggY29sbGF0ZSByZWFsIHRoZW4gcm9sbGJhY2sgZ2V0IHJlYWQgdGltZXN0YW1wIHNlc3Npb25fdXNlciBub3QgaW50ZWdlciBiaXQgdW5pcXVlIGRheSBtaW51dGUgZGVzYyBpbnNlcnQgZXhlY3V0ZSBsaWtlIGlsaWtlfDIgbGV2ZWwgZGVjaW1hbCBkcm9wIGNvbnRpbnVlIGlzb2xhdGlvbiBmb3VuZCB3aGVyZSBjb25zdHJhaW50cyBkb21haW4gcmlnaHQgbmF0aW9uYWwgc29tZSBtb2R1bGUgdHJhbnNhY3Rpb24gcmVsYXRpdmUgc2Vjb25kIGNvbm5lY3QgZXNjYXBlIGNsb3NlIHN5c3RlbV91c2VyIGZvciBkZWZlcnJlZCBzZWN0aW9uIGNhc3QgY3VycmVudCBzcWxzdGF0ZSBhbGxvY2F0ZSBpbnRlcnNlY3QgZGVhbGxvY2F0ZSBudW1lcmljIHB1YmxpYyBwcmVzZXJ2ZSBmdWxsIGdvdG8gaW5pdGlhbGx5IGFzYyBubyBrZXkgb3V0cHV0IGNvbGxhdGlvbiBncm91cCBieSB1bmlvbiBzZXNzaW9uIGJvdGggbGFzdCBsYW5ndWFnZSBjb25zdHJhaW50IGNvbHVtbiBvZiBzcGFjZSBmb3JlaWduIGRlZmVycmFibGUgcHJpb3IgY29ubmVjdGlvbiB1bmtub3duIGFjdGlvbiBjb21taXQgdmlldyBvciBmaXJzdCBpbnRvIGZsb2F0IHllYXIgcHJpbWFyeSBjYXNjYWRlZCBleGNlcHQgcmVzdHJpY3Qgc2V0IHJlZmVyZW5jZXMgbmFtZXMgdGFibGUgb3V0ZXIgb3BlbiBzZWxlY3Qgc2l6ZSBhcmUgcm93cyBmcm9tIHByZXBhcmUgZGlzdGluY3QgbGVhZGluZyBjcmVhdGUgb25seSBuZXh0IGlubmVyIGF1dGhvcml6YXRpb24gc2NoZW1hIGNvcnJlc3BvbmRpbmcgb3B0aW9uIGRlY2xhcmUgcHJlY2lzaW9uIGltbWVkaWF0ZSBlbHNlIHRpbWV6b25lX21pbnV0ZSBleHRlcm5hbCB2YXJ5aW5nIHRyYW5zbGF0aW9uIHRydWUgY2FzZSBleGNlcHRpb24gam9pbiBob3VyIGRlZmF1bHQgZG91YmxlIHNjcm9sbCB2YWx1ZSBjdXJzb3IgZGVzY3JpcHRvciB2YWx1ZXMgZGVjIGZldGNoIHByb2NlZHVyZSBkZWxldGUgYW5kIGZhbHNlIGludCBpcyBkZXNjcmliZSBjaGFyIGFzIGF0IGluIHZhcmNoYXIgbnVsbCB0cmFpbGluZyBhbnkgYWJzb2x1dGUgY3VycmVudF90aW1lIGVuZCBncmFudCBwcml2aWxlZ2VzIHdoZW4gY3Jvc3MgY2hlY2sgd3JpdGUgY3VycmVudF9kYXRlIHBhZCBiZWdpbiB0ZW1wb3JhcnkgZXhlYyB0aW1lIHVwZGF0ZSBjYXRhbG9nIHVzZXIgc3FsIGRhdGUgb24gaWRlbnRpdHkgdGltZXpvbmVfaG91ciBuYXR1cmFsIHdoZW5ldmVyIGludGVydmFsIHdvcmsgb3JkZXIgY2FzY2FkZSBkaWFnbm9zdGljcyBuY2hhciBoYXZpbmcgbGVmdCBjYWxsIGRvIGhhbmRsZXIgbG9hZCByZXBsYWNlIHRydW5jYXRlIHN0YXJ0IGxvY2sgc2hvdyBwcmFnbWEgZXhpc3RzIG51bWJlciB0cmlnZ2VyIGlmIGJlZm9yZSBhZnRlciBlYWNoIHJvdyIsYWdncmVnYXRlOiJjb3VudCBzdW0gbWluIG1heCBhdmcifSxjOlt7Y046InN0cmluZyIsYjoiJyIsZToiJyIsYzpbYS5CRSx7YjoiJycifV0scjowfSx7Y046InN0cmluZyIsYjonIicsZTonIicsYzpbYS5CRSx7YjonIiInfV0scjowfSx7Y046InN0cmluZyIsYjoiYCIsZToiYCIsYzpbYS5CRV19LGEuQ05NXX0sYS5DQkxDTE0se2NOOiJjb21tZW50IixiOiItLSIsZToiJCJ9XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLmluaT1mdW5jdGlvbihhKXtyZXR1cm57Y0k6dHJ1ZSxpOiJbXlxcc10iLGM6W3tjTjoiY29tbWVudCIsYjoiOyIsZToiJCJ9LHtjTjoidGl0bGUiLGI6Il5cXFsiLGU6IlxcXSJ9LHtjTjoic2V0dGluZyIsYjoiXlthLXowLTlcXFtcXF1fLV0rWyBcXHRdKj1bIFxcdF0qIixlOiIkIixjOlt7Y046InZhbHVlIixlVzp0cnVlLGs6Im9uIG9mZiB0cnVlIGZhbHNlIHllcyBubyIsYzpbYS5RU00sYS5OTV0scjowfV19XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLnBlcmw9ZnVuY3Rpb24oZSl7dmFyIGE9ImdldHB3ZW50IGdldHNlcnZlbnQgcXVvdGVtZXRhIG1zZ3JjdiBzY2FsYXIga2lsbCBkYm1jbG9zZSB1bmRlZiBsYyBtYSBzeXN3cml0ZSB0ciBzZW5kIHVtYXNrIHN5c29wZW4gc2htd3JpdGUgdmVjIHF4IHV0aW1lIGxvY2FsIG9jdCBzZW1jdGwgbG9jYWx0aW1lIHJlYWRwaXBlIGRvIHJldHVybiBmb3JtYXQgcmVhZCBzcHJpbnRmIGRibW9wZW4gcG9wIGdldHBncnAgbm90IGdldHB3bmFtIHJld2luZGRpciBxcWZpbGVubyBxdyBlbmRwcm90b2VudCB3YWl0IHNldGhvc3RlbnQgYmxlc3Mgc3wwIG9wZW5kaXIgY29udGludWUgZWFjaCBzbGVlcCBlbmRncmVudCBzaHV0ZG93biBkdW1wIGNob21wIGNvbm5lY3QgZ2V0c29ja25hbWUgZGllIHNvY2tldHBhaXIgY2xvc2UgZmxvY2sgZXhpc3RzIGluZGV4IHNobWdldHN1YiBmb3IgZW5kcHdlbnQgcmVkbyBsc3RhdCBtc2djdGwgc2V0cGdycCBhYnMgZXhpdCBzZWxlY3QgcHJpbnQgcmVmIGdldGhvc3RieWFkZHIgdW5zaGlmdCBmY250bCBzeXNjYWxsIGdvdG8gZ2V0bmV0YnlhZGRyIGpvaW4gZ210aW1lIHN5bWxpbmsgc2VtZ2V0IHNwbGljZSB4fDAgZ2V0cGVlcm5hbWUgcmVjdiBsb2cgc2V0c29ja29wdCBjb3MgbGFzdCByZXZlcnNlIGdldGhvc3RieW5hbWUgZ2V0Z3JuYW0gc3R1ZHkgZm9ybWxpbmUgZW5kaG9zdGVudCB0aW1lcyBjaG9wIGxlbmd0aCBnZXRob3N0ZW50IGdldG5ldGVudCBwYWNrIGdldHByb3RvZW50IGdldHNlcnZieW5hbWUgcmFuZCBta2RpciBwb3MgY2htb2QgeXwwIHN1YnN0ciBlbmRuZXRlbnQgcHJpbnRmIG5leHQgb3BlbiBtc2dzbmQgcmVhZGRpciB1c2UgdW5saW5rIGdldHNvY2tvcHQgZ2V0cHJpb3JpdHkgcmluZGV4IHdhbnRhcnJheSBoZXggc3lzdGVtIGdldHNlcnZieXBvcnQgZW5kc2VydmVudCBpbnQgY2hyIHVudGllIHJtZGlyIHByb3RvdHlwZSB0ZWxsIGxpc3RlbiBmb3JrIHNobXJlYWQgdWNmaXJzdCBzZXRwcm90b2VudCBlbHNlIHN5c3NlZWsgbGluayBnZXRncmdpZCBzaG1jdGwgd2FpdHBpZCB1bnBhY2sgZ2V0bmV0YnluYW1lIHJlc2V0IGNoZGlyIGdyZXAgc3BsaXQgcmVxdWlyZSBjYWxsZXIgbGNmaXJzdCB1bnRpbCB3YXJuIHdoaWxlIHZhbHVlcyBzaGlmdCB0ZWxsZGlyIGdldHB3dWlkIG15IGdldHByb3RvYnludW1iZXIgZGVsZXRlIGFuZCBzb3J0IHVjIGRlZmluZWQgc3JhbmQgYWNjZXB0IHBhY2thZ2Ugc2Vla2RpciBnZXRwcm90b2J5bmFtZSBzZW1vcCBvdXIgcmVuYW1lIHNlZWsgaWYgcXwwIGNocm9vdCBzeXNyZWFkIHNldHB3ZW50IG5vIGNyeXB0IGdldGMgY2hvd24gc3FydCB3cml0ZSBzZXRuZXRlbnQgc2V0cHJpb3JpdHkgZm9yZWFjaCB0aWUgc2luIG1zZ2dldCBtYXAgc3RhdCBnZXRsb2dpbiB1bmxlc3MgZWxzaWYgdHJ1bmNhdGUgZXhlYyBrZXlzIGdsb2IgdGllZCBjbG9zZWRpcmlvY3RsIHNvY2tldCByZWFkbGluayBldmFsIHhvciByZWFkbGluZSBiaW5tb2RlIHNldHNlcnZlbnQgZW9mIG9yZCBiaW5kIGFsYXJtIHBpcGUgYXRhbjIgZ2V0Z3JlbnQgZXhwIHRpbWUgcHVzaCBzZXRncmVudCBndCBsdCBvciBuZSBtfDAgYnJlYWsgZ2l2ZW4gc2F5IHN0YXRlIHdoZW4iO3ZhciBkPXtjTjoic3Vic3QiLGI6IlskQF1cXHsiLGU6IlxcfSIsazphLHI6MTB9O3ZhciBiPXtjTjoidmFyaWFibGUiLGI6IlxcJFxcZCJ9O3ZhciBpPXtjTjoidmFyaWFibGUiLGI6IltcXCRcXCVcXEBcXCpdKFxcXlxcd1xcYnwjXFx3KyhcXDpcXDpcXHcrKSp8W15cXHNcXHd7XXx7XFx3K318XFx3KyhcXDpcXDpcXHcqKSopIn07dmFyIGY9W2UuQkUsZCxiLGldO3ZhciBoPXtiOiItPiIsYzpbe2I6ZS5JUn0se2I6InsiLGU6In0ifV19O3ZhciBnPXtjTjoiY29tbWVudCIsYjoiXihfX0VORF9ffF9fREFUQV9fKSIsZToiXFxuJCIscjo1fTt2YXIgYz1bYixpLGUuSENNLGcse2NOOiJjb21tZW50IixiOiJeXFw9XFx3IixlOiJcXD1jdXQiLGVXOnRydWV9LGgse2NOOiJzdHJpbmciLGI6InFbcXd4cl0/XFxzKlxcKCIsZToiXFwpIixjOmYscjo1fSx7Y046InN0cmluZyIsYjoicVtxd3hyXT9cXHMqXFxbIixlOiJcXF0iLGM6ZixyOjV9LHtjTjoic3RyaW5nIixiOiJxW3F3eHJdP1xccypcXHsiLGU6IlxcfSIsYzpmLHI6NX0se2NOOiJzdHJpbmciLGI6InFbcXd4cl0/XFxzKlxcfCIsZToiXFx8IixjOmYscjo1fSx7Y046InN0cmluZyIsYjoicVtxd3hyXT9cXHMqXFw8IixlOiJcXD4iLGM6ZixyOjV9LHtjTjoic3RyaW5nIixiOiJxd1xccytxIixlOiJxIixjOmYscjo1fSx7Y046InN0cmluZyIsYjoiJyIsZToiJyIsYzpbZS5CRV0scjowfSx7Y046InN0cmluZyIsYjonIicsZTonIicsYzpmLHI6MH0se2NOOiJzdHJpbmciLGI6ImAiLGU6ImAiLGM6W2UuQkVdfSx7Y046InN0cmluZyIsYjoie1xcdyt9IixyOjB9LHtjTjoic3RyaW5nIixiOiItP1xcdytcXHMqXFw9XFw+IixyOjB9LHtjTjoibnVtYmVyIixiOiIoXFxiMFswLTdfXSspfChcXGIweFswLTlhLWZBLUZfXSspfChcXGJbMS05XVswLTlfXSooXFwuWzAtOV9dKyk/KXxbMF9dXFxiIixyOjB9LHtiOiIoIitlLlJTUisifFxcYihzcGxpdHxyZXR1cm58cHJpbnR8cmV2ZXJzZXxncmVwKVxcYilcXHMqIixrOiJzcGxpdCByZXR1cm4gcHJpbnQgcmV2ZXJzZSBncmVwIixyOjAsYzpbZS5IQ00sZyx7Y046InJlZ2V4cCIsYjoiKHN8dHJ8eSkvKFxcXFwufFteL10pKi8oXFxcXC58W14vXSkqL1thLXpdKiIscjoxMH0se2NOOiJyZWdleHAiLGI6IihtfHFyKT8vIixlOiIvW2Etel0qIixjOltlLkJFXSxyOjB9XX0se2NOOiJzdWIiLGJXSzp0cnVlLGU6IihcXHMqXFwoLio/XFwpKT9bO3tdIixrOiJzdWIiLHI6NX0se2NOOiJvcGVyYXRvciIsYjoiLVxcd1xcYiIscjowfV07ZC5jPWM7aC5jWzFdLmM9YztyZXR1cm57azphLGM6Y319KGhsanMpO2hsanMuTEFOR1VBR0VTLm9iamVjdGl2ZWM9ZnVuY3Rpb24oYSl7dmFyIGI9e2tleXdvcmQ6ImludCBmbG9hdCB3aGlsZSBwcml2YXRlIGNoYXIgY2F0Y2ggZXhwb3J0IHNpemVvZiB0eXBlZGVmIGNvbnN0IHN0cnVjdCBmb3IgdW5pb24gdW5zaWduZWQgbG9uZyB2b2xhdGlsZSBzdGF0aWMgcHJvdGVjdGVkIGJvb2wgbXV0YWJsZSBpZiBwdWJsaWMgZG8gcmV0dXJuIGdvdG8gdm9pZCBlbnVtIGVsc2UgYnJlYWsgZXh0ZXJuIGFzbSBjYXNlIHNob3J0IGRlZmF1bHQgZG91YmxlIHRocm93IHJlZ2lzdGVyIGV4cGxpY2l0IHNpZ25lZCB0eXBlbmFtZSB0cnkgdGhpcyBzd2l0Y2ggY29udGludWUgd2NoYXJfdCBpbmxpbmUgcmVhZG9ubHkgYXNzaWduIHByb3BlcnR5IHNlbGYgc3luY2hyb25pemVkIGVuZCBzeW50aGVzaXplIGlkIG9wdGlvbmFsIHJlcXVpcmVkIG5vbmF0b21pYyBzdXBlciB1bmljaGFyIGZpbmFsbHkgZHluYW1pYyBJQk91dGxldCBJQkFjdGlvbiBzZWxlY3RvciBzdHJvbmcgd2VhayByZWFkb25seSIsbGl0ZXJhbDoiZmFsc2UgdHJ1ZSBGQUxTRSBUUlVFIG5pbCBZRVMgTk8gTlVMTCIsYnVpbHRfaW46Ik5TU3RyaW5nIE5TRGljdGlvbmFyeSBDR1JlY3QgQ0dQb2ludCBVSUJ1dHRvbiBVSUxhYmVsIFVJVGV4dFZpZXcgVUlXZWJWaWV3IE1LTWFwVmlldyBVSVNlZ21lbnRlZENvbnRyb2wgTlNPYmplY3QgVUlUYWJsZVZpZXdEZWxlZ2F0ZSBVSVRhYmxlVmlld0RhdGFTb3VyY2UgTlNUaHJlYWQgVUlBY3Rpdml0eUluZGljYXRvciBVSVRhYmJhciBVSVRvb2xCYXIgVUlCYXJCdXR0b25JdGVtIFVJSW1hZ2VWaWV3IE5TQXV0b3JlbGVhc2VQb29sIFVJVGFibGVWaWV3IEJPT0wgTlNJbnRlZ2VyIENHRmxvYXQgTlNFeGNlcHRpb24gTlNMb2cgTlNNdXRhYmxlU3RyaW5nIE5TTXV0YWJsZUFycmF5IE5TTXV0YWJsZURpY3Rpb25hcnkgTlNVUkwgTlNJbmRleFBhdGggQ0dTaXplIFVJVGFibGVWaWV3Q2VsbCBVSVZpZXcgVUlWaWV3Q29udHJvbGxlciBVSU5hdmlnYXRpb25CYXIgVUlOYXZpZ2F0aW9uQ29udHJvbGxlciBVSVRhYkJhckNvbnRyb2xsZXIgVUlQb3BvdmVyQ29udHJvbGxlciBVSVBvcG92ZXJDb250cm9sbGVyRGVsZWdhdGUgVUlJbWFnZSBOU051bWJlciBVSVNlYXJjaEJhciBOU0ZldGNoZWRSZXN1bHRzQ29udHJvbGxlciBOU0ZldGNoZWRSZXN1bHRzQ2hhbmdlVHlwZSBVSVNjcm9sbFZpZXcgVUlTY3JvbGxWaWV3RGVsZWdhdGUgVUlFZGdlSW5zZXRzIFVJQ29sb3IgVUlGb250IFVJQXBwbGljYXRpb24gTlNOb3RGb3VuZCBOU05vdGlmaWNhdGlvbkNlbnRlciBOU05vdGlmaWNhdGlvbiBVSUxvY2FsTm90aWZpY2F0aW9uIE5TQnVuZGxlIE5TRmlsZU1hbmFnZXIgTlNUaW1lSW50ZXJ2YWwgTlNEYXRlIE5TQ2FsZW5kYXIgTlNVc2VyRGVmYXVsdHMgVUlXaW5kb3cgTlNSYW5nZSBOU0FycmF5IE5TRXJyb3IgTlNVUkxSZXF1ZXN0IE5TVVJMQ29ubmVjdGlvbiBVSUludGVyZmFjZU9yaWVudGF0aW9uIE1QTW92aWVQbGF5ZXJDb250cm9sbGVyIGRpc3BhdGNoX29uY2VfdCBkaXNwYXRjaF9xdWV1ZV90IGRpc3BhdGNoX3N5bmMgZGlzcGF0Y2hfYXN5bmMgZGlzcGF0Y2hfb25jZSJ9O3JldHVybntrOmIsaToiPC8iLGM6W2EuQ0xDTSxhLkNCTENMTSxhLkNOTSxhLlFTTSx7Y046InN0cmluZyIsYjoiJyIsZToiW15cXFxcXSciLGk6IlteXFxcXF1bXiddIn0se2NOOiJwcmVwcm9jZXNzb3IiLGI6IiNpbXBvcnQiLGU6IiQiLGM6W3tjTjoidGl0bGUiLGI6JyInLGU6JyInfSx7Y046InRpdGxlIixiOiI8IixlOiI+In1dfSx7Y046InByZXByb2Nlc3NvciIsYjoiIyIsZToiJCJ9LHtjTjoiY2xhc3MiLGJXSzp0cnVlLGU6Iih7fCQpIixrOiJpbnRlcmZhY2UgY2xhc3MgcHJvdG9jb2wgaW1wbGVtZW50YXRpb24iLGM6W3tjTjoiaWQiLGI6YS5VSVJ9XX0se2NOOiJ2YXJpYWJsZSIsYjoiXFwuIithLlVJUixyOjB9XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLmNvZmZlZXNjcmlwdD1mdW5jdGlvbihjKXt2YXIgYj17a2V5d29yZDoiaW4gaWYgZm9yIHdoaWxlIGZpbmFsbHkgbmV3IGRvIHJldHVybiBlbHNlIGJyZWFrIGNhdGNoIGluc3RhbmNlb2YgdGhyb3cgdHJ5IHRoaXMgc3dpdGNoIGNvbnRpbnVlIHR5cGVvZiBkZWxldGUgZGVidWdnZXIgc3VwZXIgdGhlbiB1bmxlc3MgdW50aWwgbG9vcCBvZiBieSB3aGVuIGFuZCBvciBpcyBpc250IG5vdCIsbGl0ZXJhbDoidHJ1ZSBmYWxzZSBudWxsIHVuZGVmaW5lZCB5ZXMgbm8gb24gb2ZmIixyZXNlcnZlZDoiY2FzZSBkZWZhdWx0IGZ1bmN0aW9uIHZhciB2b2lkIHdpdGggY29uc3QgbGV0IGVudW0gZXhwb3J0IGltcG9ydCBuYXRpdmUgX19oYXNQcm9wIF9fZXh0ZW5kcyBfX3NsaWNlIF9fYmluZCBfX2luZGV4T2YiLGJ1aWx0X2luOiJucG0gcmVxdWlyZSBjb25zb2xlIHByaW50IG1vZHVsZSBleHBvcnRzIGdsb2JhbCB3aW5kb3cgZG9jdW1lbnQifTt2YXIgYT0iW0EtWmEteiRfXVswLTlBLVphLXokX10qIjt2YXIgZj17Y046InRpdGxlIixiOmF9O3ZhciBlPXtjTjoic3Vic3QiLGI6IiNcXHsiLGU6In0iLGs6Yix9O3ZhciBkPVtjLkJOTSxjLmluaGVyaXQoYy5DTk0se3N0YXJ0czp7ZToiKFxccyovKT8iLHI6MH19KSx7Y046InN0cmluZyIsYjoiJycnIixlOiInJyciLGM6W2MuQkVdfSx7Y046InN0cmluZyIsYjoiJyIsZToiJyIsYzpbYy5CRV0scjowfSx7Y046InN0cmluZyIsYjonIiIiJyxlOiciIiInLGM6W2MuQkUsZV19LHtjTjoic3RyaW5nIixiOiciJyxlOiciJyxjOltjLkJFLGVdLHI6MH0se2NOOiJyZWdleHAiLGI6Ii8vLyIsZToiLy8vIixjOltjLkhDTV19LHtjTjoicmVnZXhwIixiOiIvL1tnaW1dKiIscjowfSx7Y046InJlZ2V4cCIsYjoiL1xcUyhcXFxcLnxbXlxcbl0pKj8vW2dpbV0qKD89XFxzfFxcV3wkKSJ9LHtjTjoicHJvcGVydHkiLGI6IkAiK2F9LHtiOiJgIixlOiJgIixlQjp0cnVlLGVFOnRydWUsc0w6ImphdmFzY3JpcHQifV07ZS5jPWQ7cmV0dXJue2s6YixjOmQuY29uY2F0KFt7Y046ImNvbW1lbnQiLGI6IiMjIyIsZToiIyMjIn0sYy5IQ00se2NOOiJmdW5jdGlvbiIsYjoiKCIrYSsiXFxzKj1cXHMqKT8oXFwoLipcXCkpP1xccypbLT1dPiIsZToiWy09XT4iLHJCOnRydWUsYzpbZix7Y046InBhcmFtcyIsYjoiXFwoIixyQjp0cnVlLGM6W3tiOi9cKC8sZTovXCkvLGs6YixjOlsic2VsZiJdLmNvbmNhdChkKX1dfV19LHtjTjoiY2xhc3MiLGJXSzp0cnVlLGs6ImNsYXNzIixlOiIkIixpOiJbOlxcW1xcXV0iLGM6W3tiV0s6dHJ1ZSxrOiJleHRlbmRzIixlVzp0cnVlLGk6IjoiLGM6W2ZdfSxmXX0se2NOOiJhdHRyaWJ1dGUiLGI6YSsiOiIsZToiOiIsckI6dHJ1ZSxlRTp0cnVlfV0pfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMubmdpbng9ZnVuY3Rpb24oYil7dmFyIGM9W3tjTjoidmFyaWFibGUiLGI6IlxcJFxcZCsifSx7Y046InZhcmlhYmxlIixiOiJcXCR7IixlOiJ9In0se2NOOiJ2YXJpYWJsZSIsYjoiW1xcJFxcQF0iK2IuVUlSfV07dmFyIGE9e2VXOnRydWUsbDoiW2Etei9fXSsiLGs6e2J1aWx0X2luOiJvbiBvZmYgeWVzIG5vIHRydWUgZmFsc2Ugbm9uZSBibG9ja2VkIGRlYnVnIGluZm8gbm90aWNlIHdhcm4gZXJyb3IgY3JpdCBzZWxlY3QgYnJlYWsgbGFzdCBwZXJtYW5lbnQgcmVkaXJlY3Qga3F1ZXVlIHJ0c2lnIGVwb2xsIHBvbGwgL2Rldi9wb2xsIn0scjowLGk6Ij0+IixjOltiLkhDTSx7Y046InN0cmluZyIsYjonIicsZTonIicsYzpbYi5CRV0uY29uY2F0KGMpLHI6MH0se2NOOiJzdHJpbmciLGI6IiciLGU6IiciLGM6W2IuQkVdLmNvbmNhdChjKSxyOjB9LHtjTjoidXJsIixiOiIoW2Etel0rKTovIixlOiJcXHMiLGVXOnRydWUsZUU6dHJ1ZX0se2NOOiJyZWdleHAiLGI6Ilxcc1xcXiIsZToiXFxzfHt8OyIsckU6dHJ1ZSxjOltiLkJFXS5jb25jYXQoYyl9LHtjTjoicmVnZXhwIixiOiJ+XFwqP1xccysiLGU6Ilxcc3x7fDsiLHJFOnRydWUsYzpbYi5CRV0uY29uY2F0KGMpfSx7Y046InJlZ2V4cCIsYjoiXFwqKFxcLlthLXpcXC1dKykrIixjOltiLkJFXS5jb25jYXQoYyl9LHtjTjoicmVnZXhwIixiOiIoW2EtelxcLV0rXFwuKStcXCoiLGM6W2IuQkVdLmNvbmNhdChjKX0se2NOOiJudW1iZXIiLGI6IlxcYlxcZHsxLDN9XFwuXFxkezEsM31cXC5cXGR7MSwzfVxcLlxcZHsxLDN9KDpcXGR7MSw1fSk/XFxiIn0se2NOOiJudW1iZXIiLGI6IlxcYlxcZCtba0ttTWdHZHNoZHd5XSpcXGIiLHI6MH1dLmNvbmNhdChjKX07cmV0dXJue2M6W2IuSENNLHtiOmIuVUlSKyJcXHMiLGU6Ijt8eyIsckI6dHJ1ZSxjOlt7Y046InRpdGxlIixiOmIuVUlSLHN0YXJ0czphfV0scjowfV0saToiW15cXHNcXH1dIn19KGhsanMpO2hsanMuTEFOR1VBR0VTLmpzb249ZnVuY3Rpb24oYSl7dmFyIGU9e2xpdGVyYWw6InRydWUgZmFsc2UgbnVsbCJ9O3ZhciBkPVthLlFTTSxhLkNOTV07dmFyIGM9e2NOOiJ2YWx1ZSIsZToiLCIsZVc6dHJ1ZSxlRTp0cnVlLGM6ZCxrOmV9O3ZhciBiPXtiOiJ7IixlOiJ9IixjOlt7Y046ImF0dHJpYnV0ZSIsYjonXFxzKiInLGU6JyJcXHMqOlxccyonLGVCOnRydWUsZUU6dHJ1ZSxjOlthLkJFXSxpOiJcXG4iLHN0YXJ0czpjfV0saToiXFxTIn07dmFyIGY9e2I6IlxcWyIsZToiXFxdIixjOlthLmluaGVyaXQoYyx7Y046bnVsbH0pXSxpOiJcXFMifTtkLnNwbGljZShkLmxlbmd0aCwwLGIsZik7cmV0dXJue2M6ZCxrOmUsaToiXFxTIn19KGhsanMpO2hsanMuTEFOR1VBR0VTLmFwYWNoZT1mdW5jdGlvbihhKXt2YXIgYj17Y046Im51bWJlciIsYjoiW1xcJCVdXFxkKyJ9O3JldHVybntjSTp0cnVlLGM6W2EuSENNLHtjTjoidGFnIixiOiI8Lz8iLGU6Ij4ifSx7Y046ImtleXdvcmQiLGI6L1x3Ky8scjowLGs6e2NvbW1vbjoib3JkZXIgZGVueSBhbGxvdyBzZXRlbnYgcmV3cml0ZXJ1bGUgcmV3cml0ZWVuZ2luZSByZXdyaXRlY29uZCBkb2N1bWVudHJvb3Qgc2V0aGFuZGxlciBlcnJvcmRvY3VtZW50IGxvYWRtb2R1bGUgb3B0aW9ucyBoZWFkZXIgbGlzdGVuIHNlcnZlcnJvb3Qgc2VydmVybmFtZSJ9LHN0YXJ0czp7ZTovJC8scjowLGs6e2xpdGVyYWw6Im9uIG9mZiBhbGwifSxjOlt7Y046InNxYnJhY2tldCIsYjoiXFxzXFxbIixlOiJcXF0kIn0se2NOOiJjYnJhY2tldCIsYjoiW1xcJCVdXFx7IixlOiJcXH0iLGM6WyJzZWxmIixiXX0sYixhLlFTTV19fV0saTovXFMvfX0oaGxqcyk7aGxqcy5MQU5HVUFHRVMuY3BwPWZ1bmN0aW9uKGEpe3ZhciBiPXtrZXl3b3JkOiJmYWxzZSBpbnQgZmxvYXQgd2hpbGUgcHJpdmF0ZSBjaGFyIGNhdGNoIGV4cG9ydCB2aXJ0dWFsIG9wZXJhdG9yIHNpemVvZiBkeW5hbWljX2Nhc3R8MTAgdHlwZWRlZiBjb25zdF9jYXN0fDEwIGNvbnN0IHN0cnVjdCBmb3Igc3RhdGljX2Nhc3R8MTAgdW5pb24gbmFtZXNwYWNlIHVuc2lnbmVkIGxvbmcgdGhyb3cgdm9sYXRpbGUgc3RhdGljIHByb3RlY3RlZCBib29sIHRlbXBsYXRlIG11dGFibGUgaWYgcHVibGljIGZyaWVuZCBkbyByZXR1cm4gZ290byBhdXRvIHZvaWQgZW51bSBlbHNlIGJyZWFrIG5ldyBleHRlcm4gdXNpbmcgdHJ1ZSBjbGFzcyBhc20gY2FzZSB0eXBlaWQgc2hvcnQgcmVpbnRlcnByZXRfY2FzdHwxMCBkZWZhdWx0IGRvdWJsZSByZWdpc3RlciBleHBsaWNpdCBzaWduZWQgdHlwZW5hbWUgdHJ5IHRoaXMgc3dpdGNoIGNvbnRpbnVlIHdjaGFyX3QgaW5saW5lIGRlbGV0ZSBhbGlnbm9mIGNoYXIxNl90IGNoYXIzMl90IGNvbnN0ZXhwciBkZWNsdHlwZSBub2V4Y2VwdCBudWxscHRyIHN0YXRpY19hc3NlcnQgdGhyZWFkX2xvY2FsIHJlc3RyaWN0IF9Cb29sIGNvbXBsZXgiLGJ1aWx0X2luOiJzdGQgc3RyaW5nIGNpbiBjb3V0IGNlcnIgY2xvZyBzdHJpbmdzdHJlYW0gaXN0cmluZ3N0cmVhbSBvc3RyaW5nc3RyZWFtIGF1dG9fcHRyIGRlcXVlIGxpc3QgcXVldWUgc3RhY2sgdmVjdG9yIG1hcCBzZXQgYml0c2V0IG11bHRpc2V0IG11bHRpbWFwIHVub3JkZXJlZF9zZXQgdW5vcmRlcmVkX21hcCB1bm9yZGVyZWRfbXVsdGlzZXQgdW5vcmRlcmVkX211bHRpbWFwIGFycmF5IHNoYXJlZF9wdHIifTtyZXR1cm57azpiLGk6IjwvIixjOlthLkNMQ00sYS5DQkxDTE0sYS5RU00se2NOOiJzdHJpbmciLGI6IidcXFxcPy4iLGU6IiciLGk6Ii4ifSx7Y046Im51bWJlciIsYjoiXFxiKFxcZCsoXFwuXFxkKik/fFxcLlxcZCspKHV8VXxsfEx8dWx8VUx8ZnxGKSJ9LGEuQ05NLHtjTjoicHJlcHJvY2Vzc29yIixiOiIjIixlOiIkIixjOlt7YjoiPCIsZToiPiIsaToiXFxuIn0sYS5DTENNXX0se2NOOiJzdGxfY29udGFpbmVyIixiOiJcXGIoZGVxdWV8bGlzdHxxdWV1ZXxzdGFja3x2ZWN0b3J8bWFwfHNldHxiaXRzZXR8bXVsdGlzZXR8bXVsdGltYXB8dW5vcmRlcmVkX21hcHx1bm9yZGVyZWRfc2V0fHVub3JkZXJlZF9tdWx0aXNldHx1bm9yZGVyZWRfbXVsdGltYXB8YXJyYXkpXFxzKjwiLGU6Ij4iLGs6YixyOjEwLGM6WyJzZWxmIl19XX19KGhsanMpO2hsanMuTEFOR1VBR0VTLm1ha2VmaWxlPWZ1bmN0aW9uKGEpe3ZhciBiPXtjTjoidmFyaWFibGUiLGI6L1wkXCgvLGU6L1wpLyxjOmEuQkV9O3JldHVybntjOlthLkhDTSx7YjovXlx3K1xzKlxXKj0vLHJCOnRydWUscjowLHN0YXJ0czp7Y046ImNvbnN0YW50IixlOi9ccypcVyo9LyxlRTp0cnVlLHN0YXJ0czp7ZTovJC8scjowLGM6W2JdLH19fSx7Y046InRpdGxlIixiOi9eW1x3XSs6XHMqJC99LHtjTjoicGhvbnkiLGI6L15cLlBIT05ZOi8sZTovJC8sazoiLlBIT05ZIixsOi9bXC5cd10rL30se2I6L15cdCsvLGU6LyQvLGM6W2EuUVNNLGJdfV19fShobGpzKTtobGpzLkxBTkdVQUdFUy5nbz1mdW5jdGlvbihhKXt2YXIgYj17a2V5d29yZDoiYnJlYWsgZGVmYXVsdCBmdW5jIGludGVyZmFjZSBzZWxlY3QgY2FzZSBtYXAgc3RydWN0IGNoYW4gZWxzZSBnb3RvIHBhY2thZ2Ugc3dpdGNoIGNvbnN0IGZhbGx0aHJvdWdoIGlmIHJhbmdlIHR5cGUgY29udGludWUgZm9yIGltcG9ydCByZXR1cm4gdmFyIGdvIGRlZmVyIixjb25zdGFudDoidHJ1ZSBmYWxzZSBpb3RhIG5pbCIsdHlwZW5hbWU6ImJvb2wgYnl0ZSBjb21wbGV4NjQgY29tcGxleDEyOCBmbG9hdDMyIGZsb2F0NjQgaW50OCBpbnQxNiBpbnQzMiBpbnQ2NCBzdHJpbmcgdWludDggdWludDE2IHVpbnQzMiB1aW50NjQgaW50IHVpbnQgdWludHB0ciBydW5lIixidWlsdF9pbjoiYXBwZW5kIGNhcCBjbG9zZSBjb21wbGV4IGNvcHkgaW1hZyBsZW4gbWFrZSBuZXcgcGFuaWMgcHJpbnQgcHJpbnRsbiByZWFsIHJlY292ZXIgZGVsZXRlIn07cmV0dXJue2s6YixpOiI8LyIsYzpbYS5DTENNLGEuQ0JMQ0xNLGEuUVNNLHtjTjoic3RyaW5nIixiOiInIixlOiJbXlxcXFxdJyIscjowfSx7Y046InN0cmluZyIsYjoiYCIsZToiYCJ9LHtjTjoibnVtYmVyIixiOiJbXmEtekEtWl8wLTldKFxcLXxcXCspP1xcZCsoXFwuXFxkK3xcXC9cXGQrKT8oKGR8ZXxmfGx8cykoXFwrfFxcLSk/XFxkKyk/IixyOjB9LGEuQ05NXX19KGhsanMpO1BLBwgVWW1O9nUAAPZ1AABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAB0AAABzdGF0aWNcbGliXGpxdWVyeS5mb3JtLm1pbi5qcyFmdW5jdGlvbihlKXsidXNlIHN0cmljdCI7ImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoWyJqcXVlcnkiXSxlKTplKCJ1bmRlZmluZWQiIT10eXBlb2YgalF1ZXJ5P2pRdWVyeTp3aW5kb3cuWmVwdG8pfShmdW5jdGlvbihlKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gdCh0KXt2YXIgcj10LmRhdGE7dC5pc0RlZmF1bHRQcmV2ZW50ZWQoKXx8KHQucHJldmVudERlZmF1bHQoKSxlKHQudGFyZ2V0KS5hamF4U3VibWl0KHIpKX1mdW5jdGlvbiByKHQpe3ZhciByPXQudGFyZ2V0LGE9ZShyKTtpZighYS5pcygiW3R5cGU9c3VibWl0XSxbdHlwZT1pbWFnZV0iKSl7dmFyIG49YS5jbG9zZXN0KCJbdHlwZT1zdWJtaXRdIik7aWYoMD09PW4ubGVuZ3RoKXJldHVybjtyPW5bMF19dmFyIGk9dGhpcztpZihpLmNsaz1yLCJpbWFnZSI9PXIudHlwZSlpZih2b2lkIDAhPT10Lm9mZnNldFgpaS5jbGtfeD10Lm9mZnNldFgsaS5jbGtfeT10Lm9mZnNldFk7ZWxzZSBpZigiZnVuY3Rpb24iPT10eXBlb2YgZS5mbi5vZmZzZXQpe3ZhciBvPWEub2Zmc2V0KCk7aS5jbGtfeD10LnBhZ2VYLW8ubGVmdCxpLmNsa195PXQucGFnZVktby50b3B9ZWxzZSBpLmNsa194PXQucGFnZVgtci5vZmZzZXRMZWZ0LGkuY2xrX3k9dC5wYWdlWS1yLm9mZnNldFRvcDtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aS5jbGs9aS5jbGtfeD1pLmNsa195PW51bGx9LDEwMCl9ZnVuY3Rpb24gYSgpe2lmKGUuZm4uYWpheFN1Ym1pdC5kZWJ1Zyl7dmFyIHQ9IltqcXVlcnkuZm9ybV0gIitBcnJheS5wcm90b3R5cGUuam9pbi5jYWxsKGFyZ3VtZW50cywiIik7d2luZG93LmNvbnNvbGUmJndpbmRvdy5jb25zb2xlLmxvZz93aW5kb3cuY29uc29sZS5sb2codCk6d2luZG93Lm9wZXJhJiZ3aW5kb3cub3BlcmEucG9zdEVycm9yJiZ3aW5kb3cub3BlcmEucG9zdEVycm9yKHQpfX12YXIgbj17fTtuLmZpbGVhcGk9dm9pZCAwIT09ZSgiPGlucHV0IHR5cGU9J2ZpbGUnLz4iKS5nZXQoMCkuZmlsZXMsbi5mb3JtZGF0YT12b2lkIDAhPT13aW5kb3cuRm9ybURhdGE7dmFyIGk9ISFlLmZuLnByb3A7ZS5mbi5hdHRyMj1mdW5jdGlvbigpe2lmKCFpKXJldHVybiB0aGlzLmF0dHIuYXBwbHkodGhpcyxhcmd1bWVudHMpO3ZhciBlPXRoaXMucHJvcC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7cmV0dXJuIGUmJmUuanF1ZXJ5fHwic3RyaW5nIj09dHlwZW9mIGU/ZTp0aGlzLmF0dHIuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxlLmZuLmFqYXhTdWJtaXQ9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gcihyKXt2YXIgYSxuLGk9ZS5wYXJhbShyLHQudHJhZGl0aW9uYWwpLnNwbGl0KCImIiksbz1pLmxlbmd0aCxzPVtdO2ZvcihhPTA7bz5hO2ErKylpW2FdPWlbYV0ucmVwbGFjZSgvXCsvZywiICIpLG49aVthXS5zcGxpdCgiPSIpLHMucHVzaChbZGVjb2RlVVJJQ29tcG9uZW50KG5bMF0pLGRlY29kZVVSSUNvbXBvbmVudChuWzFdKV0pO3JldHVybiBzfWZ1bmN0aW9uIG8oYSl7Zm9yKHZhciBuPW5ldyBGb3JtRGF0YSxpPTA7aTxhLmxlbmd0aDtpKyspbi5hcHBlbmQoYVtpXS5uYW1lLGFbaV0udmFsdWUpO2lmKHQuZXh0cmFEYXRhKXt2YXIgbz1yKHQuZXh0cmFEYXRhKTtmb3IoaT0wO2k8by5sZW5ndGg7aSsrKW9baV0mJm4uYXBwZW5kKG9baV1bMF0sb1tpXVsxXSl9dC5kYXRhPW51bGw7dmFyIHM9ZS5leHRlbmQoITAse30sZS5hamF4U2V0dGluZ3MsdCx7Y29udGVudFR5cGU6ITEscHJvY2Vzc0RhdGE6ITEsY2FjaGU6ITEsdHlwZTp1fHwiUE9TVCJ9KTt0LnVwbG9hZFByb2dyZXNzJiYocy54aHI9ZnVuY3Rpb24oKXt2YXIgcj1lLmFqYXhTZXR0aW5ncy54aHIoKTtyZXR1cm4gci51cGxvYWQmJnIudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoInByb2dyZXNzIixmdW5jdGlvbihlKXt2YXIgcj0wLGE9ZS5sb2FkZWR8fGUucG9zaXRpb24sbj1lLnRvdGFsO2UubGVuZ3RoQ29tcHV0YWJsZSYmKHI9TWF0aC5jZWlsKDEwMCooYS9uKSkpLHQudXBsb2FkUHJvZ3Jlc3MoZSxhLG4scil9LCExKSxyfSkscy5kYXRhPW51bGw7dmFyIGM9cy5iZWZvcmVTZW5kO3JldHVybiBzLmJlZm9yZVNlbmQ9ZnVuY3Rpb24oZSxyKXtyLmRhdGE9dC5mb3JtRGF0YT90LmZvcm1EYXRhOm4sYyYmYy5jYWxsKHRoaXMsZSxyKX0sZS5hamF4KHMpfWZ1bmN0aW9uIHMocil7ZnVuY3Rpb24gbihlKXt2YXIgdD1udWxsO3RyeXtlLmNvbnRlbnRXaW5kb3cmJih0PWUuY29udGVudFdpbmRvdy5kb2N1bWVudCl9Y2F0Y2gocil7YSgiY2Fubm90IGdldCBpZnJhbWUuY29udGVudFdpbmRvdyBkb2N1bWVudDogIityKX1pZih0KXJldHVybiB0O3RyeXt0PWUuY29udGVudERvY3VtZW50P2UuY29udGVudERvY3VtZW50OmUuZG9jdW1lbnR9Y2F0Y2gocil7YSgiY2Fubm90IGdldCBpZnJhbWUuY29udGVudERvY3VtZW50OiAiK3IpLHQ9ZS5kb2N1bWVudH1yZXR1cm4gdH1mdW5jdGlvbiBvKCl7ZnVuY3Rpb24gdCgpe3RyeXt2YXIgZT1uKGcpLnJlYWR5U3RhdGU7YSgic3RhdGUgPSAiK2UpLGUmJiJ1bmluaXRpYWxpemVkIj09ZS50b0xvd2VyQ2FzZSgpJiZzZXRUaW1lb3V0KHQsNTApfWNhdGNoKHIpe2EoIlNlcnZlciBhYm9ydDogIixyLCIgKCIsci5uYW1lLCIpIikscyhrKSxqJiZjbGVhclRpbWVvdXQoaiksaj12b2lkIDB9fXZhciByPWYuYXR0cjIoInRhcmdldCIpLGk9Zi5hdHRyMigiYWN0aW9uIiksbz0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSIsYz1mLmF0dHIoImVuY3R5cGUiKXx8Zi5hdHRyKCJlbmNvZGluZyIpfHxvO3cuc2V0QXR0cmlidXRlKCJ0YXJnZXQiLGQpLCghdXx8L3Bvc3QvaS50ZXN0KHUpKSYmdy5zZXRBdHRyaWJ1dGUoIm1ldGhvZCIsIlBPU1QiKSxpIT1tLnVybCYmdy5zZXRBdHRyaWJ1dGUoImFjdGlvbiIsbS51cmwpLG0uc2tpcEVuY29kaW5nT3ZlcnJpZGV8fHUmJiEvcG9zdC9pLnRlc3QodSl8fGYuYXR0cih7ZW5jb2Rpbmc6Im11bHRpcGFydC9mb3JtLWRhdGEiLGVuY3R5cGU6Im11bHRpcGFydC9mb3JtLWRhdGEifSksbS50aW1lb3V0JiYoaj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7VD0hMCxzKEQpfSxtLnRpbWVvdXQpKTt2YXIgbD1bXTt0cnl7aWYobS5leHRyYURhdGEpZm9yKHZhciBwIGluIG0uZXh0cmFEYXRhKW0uZXh0cmFEYXRhLmhhc093blByb3BlcnR5KHApJiYoZS5pc1BsYWluT2JqZWN0KG0uZXh0cmFEYXRhW3BdKSYmbS5leHRyYURhdGFbcF0uaGFzT3duUHJvcGVydHkoIm5hbWUiKSYmbS5leHRyYURhdGFbcF0uaGFzT3duUHJvcGVydHkoInZhbHVlIik/bC5wdXNoKGUoJzxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IicrbS5leHRyYURhdGFbcF0ubmFtZSsnIj4nKS52YWwobS5leHRyYURhdGFbcF0udmFsdWUpLmFwcGVuZFRvKHcpWzBdKTpsLnB1c2goZSgnPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iJytwKyciPicpLnZhbChtLmV4dHJhRGF0YVtwXSkuYXBwZW5kVG8odylbMF0pKTttLmlmcmFtZVRhcmdldHx8di5hcHBlbmRUbygiYm9keSIpLGcuYXR0YWNoRXZlbnQ/Zy5hdHRhY2hFdmVudCgib25sb2FkIixzKTpnLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLHMsITEpLHNldFRpbWVvdXQodCwxNSk7dHJ5e3cuc3VibWl0KCl9Y2F0Y2goaCl7dmFyIHg9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZm9ybSIpLnN1Ym1pdDt4LmFwcGx5KHcpfX1maW5hbGx5e3cuc2V0QXR0cmlidXRlKCJhY3Rpb24iLGkpLHcuc2V0QXR0cmlidXRlKCJlbmN0eXBlIixjKSxyP3cuc2V0QXR0cmlidXRlKCJ0YXJnZXQiLHIpOmYucmVtb3ZlQXR0cigidGFyZ2V0IiksZShsKS5yZW1vdmUoKX19ZnVuY3Rpb24gcyh0KXtpZigheC5hYm9ydGVkJiYhRil7aWYoTT1uKGcpLE18fChhKCJjYW5ub3QgYWNjZXNzIHJlc3BvbnNlIGRvY3VtZW50IiksdD1rKSx0PT09RCYmeClyZXR1cm4geC5hYm9ydCgidGltZW91dCIpLFMucmVqZWN0KHgsInRpbWVvdXQiKSx2b2lkIDA7aWYodD09ayYmeClyZXR1cm4geC5hYm9ydCgic2VydmVyIGFib3J0IiksUy5yZWplY3QoeCwiZXJyb3IiLCJzZXJ2ZXIgYWJvcnQiKSx2b2lkIDA7aWYoTSYmTS5sb2NhdGlvbi5ocmVmIT1tLmlmcmFtZVNyY3x8VCl7Zy5kZXRhY2hFdmVudD9nLmRldGFjaEV2ZW50KCJvbmxvYWQiLHMpOmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIscywhMSk7dmFyIHIsaT0ic3VjY2VzcyI7dHJ5e2lmKFQpdGhyb3cidGltZW91dCI7dmFyIG89InhtbCI9PW0uZGF0YVR5cGV8fE0uWE1MRG9jdW1lbnR8fGUuaXNYTUxEb2MoTSk7aWYoYSgiaXNYbWw9IitvKSwhbyYmd2luZG93Lm9wZXJhJiYobnVsbD09PU0uYm9keXx8IU0uYm9keS5pbm5lckhUTUwpJiYtLU8pcmV0dXJuIGEoInJlcXVlaW5nIG9uTG9hZCBjYWxsYmFjaywgRE9NIG5vdCBhdmFpbGFibGUiKSxzZXRUaW1lb3V0KHMsMjUwKSx2b2lkIDA7dmFyIHU9TS5ib2R5P00uYm9keTpNLmRvY3VtZW50RWxlbWVudDt4LnJlc3BvbnNlVGV4dD11P3UuaW5uZXJIVE1MOm51bGwseC5yZXNwb25zZVhNTD1NLlhNTERvY3VtZW50P00uWE1MRG9jdW1lbnQ6TSxvJiYobS5kYXRhVHlwZT0ieG1sIikseC5nZXRSZXNwb25zZUhlYWRlcj1mdW5jdGlvbihlKXt2YXIgdD17ImNvbnRlbnQtdHlwZSI6bS5kYXRhVHlwZX07cmV0dXJuIHRbZS50b0xvd2VyQ2FzZSgpXX0sdSYmKHguc3RhdHVzPU51bWJlcih1LmdldEF0dHJpYnV0ZSgic3RhdHVzIikpfHx4LnN0YXR1cyx4LnN0YXR1c1RleHQ9dS5nZXRBdHRyaWJ1dGUoInN0YXR1c1RleHQiKXx8eC5zdGF0dXNUZXh0KTt2YXIgYz0obS5kYXRhVHlwZXx8IiIpLnRvTG93ZXJDYXNlKCksbD0vKGpzb258c2NyaXB0fHRleHQpLy50ZXN0KGMpO2lmKGx8fG0udGV4dGFyZWEpe3ZhciBmPU0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoInRleHRhcmVhIilbMF07aWYoZil4LnJlc3BvbnNlVGV4dD1mLnZhbHVlLHguc3RhdHVzPU51bWJlcihmLmdldEF0dHJpYnV0ZSgic3RhdHVzIikpfHx4LnN0YXR1cyx4LnN0YXR1c1RleHQ9Zi5nZXRBdHRyaWJ1dGUoInN0YXR1c1RleHQiKXx8eC5zdGF0dXNUZXh0O2Vsc2UgaWYobCl7dmFyIGQ9TS5nZXRFbGVtZW50c0J5VGFnTmFtZSgicHJlIilbMF0saD1NLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07ZD94LnJlc3BvbnNlVGV4dD1kLnRleHRDb250ZW50P2QudGV4dENvbnRlbnQ6ZC5pbm5lclRleHQ6aCYmKHgucmVzcG9uc2VUZXh0PWgudGV4dENvbnRlbnQ/aC50ZXh0Q29udGVudDpoLmlubmVyVGV4dCl9fWVsc2UieG1sIj09YyYmIXgucmVzcG9uc2VYTUwmJngucmVzcG9uc2VUZXh0JiYoeC5yZXNwb25zZVhNTD1YKHgucmVzcG9uc2VUZXh0KSk7dHJ5e0U9Xyh4LGMsbSl9Y2F0Y2goeSl7aT0icGFyc2VyZXJyb3IiLHguZXJyb3I9cj15fHxpfX1jYXRjaCh5KXthKCJlcnJvciBjYXVnaHQ6ICIseSksaT0iZXJyb3IiLHguZXJyb3I9cj15fHxpfXguYWJvcnRlZCYmKGEoInVwbG9hZCBhYm9ydGVkIiksaT1udWxsKSx4LnN0YXR1cyYmKGk9eC5zdGF0dXM+PTIwMCYmeC5zdGF0dXM8MzAwfHwzMDQ9PT14LnN0YXR1cz8ic3VjY2VzcyI6ImVycm9yIiksInN1Y2Nlc3MiPT09aT8obS5zdWNjZXNzJiZtLnN1Y2Nlc3MuY2FsbChtLmNvbnRleHQsRSwic3VjY2VzcyIseCksUy5yZXNvbHZlKHgucmVzcG9uc2VUZXh0LCJzdWNjZXNzIix4KSxwJiZlLmV2ZW50LnRyaWdnZXIoImFqYXhTdWNjZXNzIixbeCxtXSkpOmkmJih2b2lkIDA9PT1yJiYocj14LnN0YXR1c1RleHQpLG0uZXJyb3ImJm0uZXJyb3IuY2FsbChtLmNvbnRleHQseCxpLHIpLFMucmVqZWN0KHgsImVycm9yIixyKSxwJiZlLmV2ZW50LnRyaWdnZXIoImFqYXhFcnJvciIsW3gsbSxyXSkpLHAmJmUuZXZlbnQudHJpZ2dlcigiYWpheENvbXBsZXRlIixbeCxtXSkscCYmIS0tZS5hY3RpdmUmJmUuZXZlbnQudHJpZ2dlcigiYWpheFN0b3AiKSxtLmNvbXBsZXRlJiZtLmNvbXBsZXRlLmNhbGwobS5jb250ZXh0LHgsaSksRj0hMCxtLnRpbWVvdXQmJmNsZWFyVGltZW91dChqKSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bS5pZnJhbWVUYXJnZXQ/di5hdHRyKCJzcmMiLG0uaWZyYW1lU3JjKTp2LnJlbW92ZSgpLHgucmVzcG9uc2VYTUw9bnVsbH0sMTAwKX19fXZhciBjLGwsbSxwLGQsdixnLHgseSxiLFQsaix3PWZbMF0sUz1lLkRlZmVycmVkKCk7aWYoUy5hYm9ydD1mdW5jdGlvbihlKXt4LmFib3J0KGUpfSxyKWZvcihsPTA7bDxoLmxlbmd0aDtsKyspYz1lKGhbbF0pLGk/Yy5wcm9wKCJkaXNhYmxlZCIsITEpOmMucmVtb3ZlQXR0cigiZGlzYWJsZWQiKTtpZihtPWUuZXh0ZW5kKCEwLHt9LGUuYWpheFNldHRpbmdzLHQpLG0uY29udGV4dD1tLmNvbnRleHR8fG0sZD0ianFGb3JtSU8iKyhuZXcgRGF0ZSkuZ2V0VGltZSgpLG0uaWZyYW1lVGFyZ2V0Pyh2PWUobS5pZnJhbWVUYXJnZXQpLGI9di5hdHRyMigibmFtZSIpLGI/ZD1iOnYuYXR0cjIoIm5hbWUiLGQpKToodj1lKCc8aWZyYW1lIG5hbWU9IicrZCsnIiBzcmM9IicrbS5pZnJhbWVTcmMrJyIgLz4nKSx2LmNzcyh7cG9zaXRpb246ImFic29sdXRlIix0b3A6Ii0xMDAwcHgiLGxlZnQ6Ii0xMDAwcHgifSkpLGc9dlswXSx4PXthYm9ydGVkOjAscmVzcG9uc2VUZXh0Om51bGwscmVzcG9uc2VYTUw6bnVsbCxzdGF0dXM6MCxzdGF0dXNUZXh0OiJuL2EiLGdldEFsbFJlc3BvbnNlSGVhZGVyczpmdW5jdGlvbigpe30sZ2V0UmVzcG9uc2VIZWFkZXI6ZnVuY3Rpb24oKXt9LHNldFJlcXVlc3RIZWFkZXI6ZnVuY3Rpb24oKXt9LGFib3J0OmZ1bmN0aW9uKHQpe3ZhciByPSJ0aW1lb3V0Ij09PXQ/InRpbWVvdXQiOiJhYm9ydGVkIjthKCJhYm9ydGluZyB1cGxvYWQuLi4gIityKSx0aGlzLmFib3J0ZWQ9MTt0cnl7Zy5jb250ZW50V2luZG93LmRvY3VtZW50LmV4ZWNDb21tYW5kJiZnLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQuZXhlY0NvbW1hbmQoIlN0b3AiKX1jYXRjaChuKXt9di5hdHRyKCJzcmMiLG0uaWZyYW1lU3JjKSx4LmVycm9yPXIsbS5lcnJvciYmbS5lcnJvci5jYWxsKG0uY29udGV4dCx4LHIsdCkscCYmZS5ldmVudC50cmlnZ2VyKCJhamF4RXJyb3IiLFt4LG0scl0pLG0uY29tcGxldGUmJm0uY29tcGxldGUuY2FsbChtLmNvbnRleHQseCxyKX19LHA9bS5nbG9iYWwscCYmMD09PWUuYWN0aXZlKysmJmUuZXZlbnQudHJpZ2dlcigiYWpheFN0YXJ0IikscCYmZS5ldmVudC50cmlnZ2VyKCJhamF4U2VuZCIsW3gsbV0pLG0uYmVmb3JlU2VuZCYmbS5iZWZvcmVTZW5kLmNhbGwobS5jb250ZXh0LHgsbSk9PT0hMSlyZXR1cm4gbS5nbG9iYWwmJmUuYWN0aXZlLS0sUy5yZWplY3QoKSxTO2lmKHguYWJvcnRlZClyZXR1cm4gUy5yZWplY3QoKSxTO3k9dy5jbGsseSYmKGI9eS5uYW1lLGImJiF5LmRpc2FibGVkJiYobS5leHRyYURhdGE9bS5leHRyYURhdGF8fHt9LG0uZXh0cmFEYXRhW2JdPXkudmFsdWUsImltYWdlIj09eS50eXBlJiYobS5leHRyYURhdGFbYisiLngiXT13LmNsa194LG0uZXh0cmFEYXRhW2IrIi55Il09dy5jbGtfeSkpKTt2YXIgRD0xLGs9MixBPWUoIm1ldGFbbmFtZT1jc3JmLXRva2VuXSIpLmF0dHIoImNvbnRlbnQiKSxMPWUoIm1ldGFbbmFtZT1jc3JmLXBhcmFtXSIpLmF0dHIoImNvbnRlbnQiKTtMJiZBJiYobS5leHRyYURhdGE9bS5leHRyYURhdGF8fHt9LG0uZXh0cmFEYXRhW0xdPUEpLG0uZm9yY2VTeW5jP28oKTpzZXRUaW1lb3V0KG8sMTApO3ZhciBFLE0sRixPPTUwLFg9ZS5wYXJzZVhNTHx8ZnVuY3Rpb24oZSx0KXtyZXR1cm4gd2luZG93LkFjdGl2ZVhPYmplY3Q/KHQ9bmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxET00iKSx0LmFzeW5jPSJmYWxzZSIsdC5sb2FkWE1MKGUpKTp0PShuZXcgRE9NUGFyc2VyKS5wYXJzZUZyb21TdHJpbmcoZSwidGV4dC94bWwiKSx0JiZ0LmRvY3VtZW50RWxlbWVudCYmInBhcnNlcmVycm9yIiE9dC5kb2N1bWVudEVsZW1lbnQubm9kZU5hbWU/dDpudWxsfSxDPWUucGFyc2VKU09OfHxmdW5jdGlvbihlKXtyZXR1cm4gd2luZG93LmV2YWwoIigiK2UrIikiKX0sXz1mdW5jdGlvbih0LHIsYSl7dmFyIG49dC5nZXRSZXNwb25zZUhlYWRlcigiY29udGVudC10eXBlIil8fCIiLGk9InhtbCI9PT1yfHwhciYmbi5pbmRleE9mKCJ4bWwiKT49MCxvPWk/dC5yZXNwb25zZVhNTDp0LnJlc3BvbnNlVGV4dDtyZXR1cm4gaSYmInBhcnNlcmVycm9yIj09PW8uZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lJiZlLmVycm9yJiZlLmVycm9yKCJwYXJzZXJlcnJvciIpLGEmJmEuZGF0YUZpbHRlciYmKG89YS5kYXRhRmlsdGVyKG8scikpLCJzdHJpbmciPT10eXBlb2YgbyYmKCJqc29uIj09PXJ8fCFyJiZuLmluZGV4T2YoImpzb24iKT49MD9vPUMobyk6KCJzY3JpcHQiPT09cnx8IXImJm4uaW5kZXhPZigiamF2YXNjcmlwdCIpPj0wKSYmZS5nbG9iYWxFdmFsKG8pKSxvfTtyZXR1cm4gU31pZighdGhpcy5sZW5ndGgpcmV0dXJuIGEoImFqYXhTdWJtaXQ6IHNraXBwaW5nIHN1Ym1pdCBwcm9jZXNzIC0gbm8gZWxlbWVudCBzZWxlY3RlZCIpLHRoaXM7dmFyIHUsYyxsLGY9dGhpczsiZnVuY3Rpb24iPT10eXBlb2YgdD90PXtzdWNjZXNzOnR9OnZvaWQgMD09PXQmJih0PXt9KSx1PXQudHlwZXx8dGhpcy5hdHRyMigibWV0aG9kIiksYz10LnVybHx8dGhpcy5hdHRyMigiYWN0aW9uIiksbD0ic3RyaW5nIj09dHlwZW9mIGM/ZS50cmltKGMpOiIiLGw9bHx8d2luZG93LmxvY2F0aW9uLmhyZWZ8fCIiLGwmJihsPShsLm1hdGNoKC9eKFteI10rKS8pfHxbXSlbMV0pLHQ9ZS5leHRlbmQoITAse3VybDpsLHN1Y2Nlc3M6ZS5hamF4U2V0dGluZ3Muc3VjY2Vzcyx0eXBlOnV8fGUuYWpheFNldHRpbmdzLnR5cGUsaWZyYW1lU3JjOi9eaHR0cHMvaS50ZXN0KHdpbmRvdy5sb2NhdGlvbi5ocmVmfHwiIik/ImphdmFzY3JpcHQ6ZmFsc2UiOiJhYm91dDpibGFuayJ9LHQpO3ZhciBtPXt9O2lmKHRoaXMudHJpZ2dlcigiZm9ybS1wcmUtc2VyaWFsaXplIixbdGhpcyx0LG1dKSxtLnZldG8pcmV0dXJuIGEoImFqYXhTdWJtaXQ6IHN1Ym1pdCB2ZXRvZWQgdmlhIGZvcm0tcHJlLXNlcmlhbGl6ZSB0cmlnZ2VyIiksdGhpcztpZih0LmJlZm9yZVNlcmlhbGl6ZSYmdC5iZWZvcmVTZXJpYWxpemUodGhpcyx0KT09PSExKXJldHVybiBhKCJhamF4U3VibWl0OiBzdWJtaXQgYWJvcnRlZCB2aWEgYmVmb3JlU2VyaWFsaXplIGNhbGxiYWNrIiksdGhpczt2YXIgcD10LnRyYWRpdGlvbmFsO3ZvaWQgMD09PXAmJihwPWUuYWpheFNldHRpbmdzLnRyYWRpdGlvbmFsKTt2YXIgZCxoPVtdLHY9dGhpcy5mb3JtVG9BcnJheSh0LnNlbWFudGljLGgpO2lmKHQuZGF0YSYmKHQuZXh0cmFEYXRhPXQuZGF0YSxkPWUucGFyYW0odC5kYXRhLHApKSx0LmJlZm9yZVN1Ym1pdCYmdC5iZWZvcmVTdWJtaXQodix0aGlzLHQpPT09ITEpcmV0dXJuIGEoImFqYXhTdWJtaXQ6IHN1Ym1pdCBhYm9ydGVkIHZpYSBiZWZvcmVTdWJtaXQgY2FsbGJhY2siKSx0aGlzO2lmKHRoaXMudHJpZ2dlcigiZm9ybS1zdWJtaXQtdmFsaWRhdGUiLFt2LHRoaXMsdCxtXSksbS52ZXRvKXJldHVybiBhKCJhamF4U3VibWl0OiBzdWJtaXQgdmV0b2VkIHZpYSBmb3JtLXN1Ym1pdC12YWxpZGF0ZSB0cmlnZ2VyIiksdGhpczt2YXIgZz1lLnBhcmFtKHYscCk7ZCYmKGc9Zz9nKyImIitkOmQpLCJHRVQiPT10LnR5cGUudG9VcHBlckNhc2UoKT8odC51cmwrPSh0LnVybC5pbmRleE9mKCI/Iik+PTA/IiYiOiI/IikrZyx0LmRhdGE9bnVsbCk6dC5kYXRhPWc7dmFyIHg9W107aWYodC5yZXNldEZvcm0mJngucHVzaChmdW5jdGlvbigpe2YucmVzZXRGb3JtKCl9KSx0LmNsZWFyRm9ybSYmeC5wdXNoKGZ1bmN0aW9uKCl7Zi5jbGVhckZvcm0odC5pbmNsdWRlSGlkZGVuKX0pLCF0LmRhdGFUeXBlJiZ0LnRhcmdldCl7dmFyIHk9dC5zdWNjZXNzfHxmdW5jdGlvbigpe307eC5wdXNoKGZ1bmN0aW9uKHIpe3ZhciBhPXQucmVwbGFjZVRhcmdldD8icmVwbGFjZVdpdGgiOiJodG1sIjtlKHQudGFyZ2V0KVthXShyKS5lYWNoKHksYXJndW1lbnRzKX0pfWVsc2UgdC5zdWNjZXNzJiZ4LnB1c2godC5zdWNjZXNzKTtpZih0LnN1Y2Nlc3M9ZnVuY3Rpb24oZSxyLGEpe2Zvcih2YXIgbj10LmNvbnRleHR8fHRoaXMsaT0wLG89eC5sZW5ndGg7bz5pO2krKyl4W2ldLmFwcGx5KG4sW2UscixhfHxmLGZdKX0sdC5lcnJvcil7dmFyIGI9dC5lcnJvcjt0LmVycm9yPWZ1bmN0aW9uKGUscixhKXt2YXIgbj10LmNvbnRleHR8fHRoaXM7Yi5hcHBseShuLFtlLHIsYSxmXSl9fWlmKHQuY29tcGxldGUpe3ZhciBUPXQuY29tcGxldGU7dC5jb21wbGV0ZT1mdW5jdGlvbihlLHIpe3ZhciBhPXQuY29udGV4dHx8dGhpcztULmFwcGx5KGEsW2UscixmXSl9fXZhciBqPWUoImlucHV0W3R5cGU9ZmlsZV06ZW5hYmxlZCIsdGhpcykuZmlsdGVyKGZ1bmN0aW9uKCl7cmV0dXJuIiIhPT1lKHRoaXMpLnZhbCgpfSksdz1qLmxlbmd0aD4wLFM9Im11bHRpcGFydC9mb3JtLWRhdGEiLEQ9Zi5hdHRyKCJlbmN0eXBlIik9PVN8fGYuYXR0cigiZW5jb2RpbmciKT09UyxrPW4uZmlsZWFwaSYmbi5mb3JtZGF0YTthKCJmaWxlQVBJIDoiK2spO3ZhciBBLEw9KHd8fEQpJiYhazt0LmlmcmFtZSE9PSExJiYodC5pZnJhbWV8fEwpP3QuY2xvc2VLZWVwQWxpdmU/ZS5nZXQodC5jbG9zZUtlZXBBbGl2ZSxmdW5jdGlvbigpe0E9cyh2KX0pOkE9cyh2KTpBPSh3fHxEKSYmaz9vKHYpOmUuYWpheCh0KSxmLnJlbW92ZURhdGEoImpxeGhyIikuZGF0YSgianF4aHIiLEEpO2Zvcih2YXIgRT0wO0U8aC5sZW5ndGg7RSsrKWhbRV09bnVsbDtyZXR1cm4gdGhpcy50cmlnZ2VyKCJmb3JtLXN1Ym1pdC1ub3RpZnkiLFt0aGlzLHRdKSx0aGlzfSxlLmZuLmFqYXhGb3JtPWZ1bmN0aW9uKG4pe2lmKG49bnx8e30sbi5kZWxlZ2F0aW9uPW4uZGVsZWdhdGlvbiYmZS5pc0Z1bmN0aW9uKGUuZm4ub24pLCFuLmRlbGVnYXRpb24mJjA9PT10aGlzLmxlbmd0aCl7dmFyIGk9e3M6dGhpcy5zZWxlY3RvcixjOnRoaXMuY29udGV4dH07cmV0dXJuIWUuaXNSZWFkeSYmaS5zPyhhKCJET00gbm90IHJlYWR5LCBxdWV1aW5nIGFqYXhGb3JtIiksZShmdW5jdGlvbigpe2UoaS5zLGkuYykuYWpheEZvcm0obil9KSx0aGlzKTooYSgidGVybWluYXRpbmc7IHplcm8gZWxlbWVudHMgZm91bmQgYnkgc2VsZWN0b3IiKyhlLmlzUmVhZHk/IiI6IiAoRE9NIG5vdCByZWFkeSkiKSksdGhpcyl9cmV0dXJuIG4uZGVsZWdhdGlvbj8oZShkb2N1bWVudCkub2ZmKCJzdWJtaXQuZm9ybS1wbHVnaW4iLHRoaXMuc2VsZWN0b3IsdCkub2ZmKCJjbGljay5mb3JtLXBsdWdpbiIsdGhpcy5zZWxlY3RvcixyKS5vbigic3VibWl0LmZvcm0tcGx1Z2luIix0aGlzLnNlbGVjdG9yLG4sdCkub24oImNsaWNrLmZvcm0tcGx1Z2luIix0aGlzLnNlbGVjdG9yLG4sciksdGhpcyk6dGhpcy5hamF4Rm9ybVVuYmluZCgpLmJpbmQoInN1Ym1pdC5mb3JtLXBsdWdpbiIsbix0KS5iaW5kKCJjbGljay5mb3JtLXBsdWdpbiIsbixyKX0sZS5mbi5hamF4Rm9ybVVuYmluZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnVuYmluZCgic3VibWl0LmZvcm0tcGx1Z2luIGNsaWNrLmZvcm0tcGx1Z2luIil9LGUuZm4uZm9ybVRvQXJyYXk9ZnVuY3Rpb24odCxyKXt2YXIgYT1bXTtpZigwPT09dGhpcy5sZW5ndGgpcmV0dXJuIGE7dmFyIGksbz10aGlzWzBdLHM9dGhpcy5hdHRyKCJpZCIpLHU9dD9vLmdldEVsZW1lbnRzQnlUYWdOYW1lKCIqIik6by5lbGVtZW50cztpZih1JiYhL01TSUUgWzY3OF0vLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkmJih1PWUodSkuZ2V0KCkpLHMmJihpPWUoIjppbnB1dFtmb3JtPSIrcysiXSIpLmdldCgpLGkubGVuZ3RoJiYodT0odXx8W10pLmNvbmNhdChpKSkpLCF1fHwhdS5sZW5ndGgpcmV0dXJuIGE7dmFyIGMsbCxmLG0scCxkLGg7Zm9yKGM9MCxkPXUubGVuZ3RoO2Q+YztjKyspaWYocD11W2NdLGY9cC5uYW1lLGYmJiFwLmRpc2FibGVkKWlmKHQmJm8uY2xrJiYiaW1hZ2UiPT1wLnR5cGUpby5jbGs9PXAmJihhLnB1c2goe25hbWU6Zix2YWx1ZTplKHApLnZhbCgpLHR5cGU6cC50eXBlfSksYS5wdXNoKHtuYW1lOmYrIi54Iix2YWx1ZTpvLmNsa194fSx7bmFtZTpmKyIueSIsdmFsdWU6by5jbGtfeX0pKTtlbHNlIGlmKG09ZS5maWVsZFZhbHVlKHAsITApLG0mJm0uY29uc3RydWN0b3I9PUFycmF5KWZvcihyJiZyLnB1c2gocCksbD0wLGg9bS5sZW5ndGg7aD5sO2wrKylhLnB1c2goe25hbWU6Zix2YWx1ZTptW2xdfSk7ZWxzZSBpZihuLmZpbGVhcGkmJiJmaWxlIj09cC50eXBlKXtyJiZyLnB1c2gocCk7dmFyIHY9cC5maWxlcztpZih2Lmxlbmd0aClmb3IobD0wO2w8di5sZW5ndGg7bCsrKWEucHVzaCh7bmFtZTpmLHZhbHVlOnZbbF0sdHlwZTpwLnR5cGV9KTtlbHNlIGEucHVzaCh7bmFtZTpmLHZhbHVlOiIiLHR5cGU6cC50eXBlfSl9ZWxzZSBudWxsIT09bSYmInVuZGVmaW5lZCIhPXR5cGVvZiBtJiYociYmci5wdXNoKHApLGEucHVzaCh7bmFtZTpmLHZhbHVlOm0sdHlwZTpwLnR5cGUscmVxdWlyZWQ6cC5yZXF1aXJlZH0pKTtpZighdCYmby5jbGspe3ZhciBnPWUoby5jbGspLHg9Z1swXTtmPXgubmFtZSxmJiYheC5kaXNhYmxlZCYmImltYWdlIj09eC50eXBlJiYoYS5wdXNoKHtuYW1lOmYsdmFsdWU6Zy52YWwoKX0pLGEucHVzaCh7bmFtZTpmKyIueCIsdmFsdWU6by5jbGtfeH0se25hbWU6ZisiLnkiLHZhbHVlOm8uY2xrX3l9KSl9cmV0dXJuIGF9LGUuZm4uZm9ybVNlcmlhbGl6ZT1mdW5jdGlvbih0KXtyZXR1cm4gZS5wYXJhbSh0aGlzLmZvcm1Ub0FycmF5KHQpKX0sZS5mbi5maWVsZFNlcmlhbGl6ZT1mdW5jdGlvbih0KXt2YXIgcj1bXTtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5uYW1lO2lmKGEpe3ZhciBuPWUuZmllbGRWYWx1ZSh0aGlzLHQpO2lmKG4mJm4uY29uc3RydWN0b3I9PUFycmF5KWZvcih2YXIgaT0wLG89bi5sZW5ndGg7bz5pO2krKylyLnB1c2goe25hbWU6YSx2YWx1ZTpuW2ldfSk7ZWxzZSBudWxsIT09biYmInVuZGVmaW5lZCIhPXR5cGVvZiBuJiZyLnB1c2goe25hbWU6dGhpcy5uYW1lLHZhbHVlOm59KX19KSxlLnBhcmFtKHIpfSxlLmZuLmZpZWxkVmFsdWU9ZnVuY3Rpb24odCl7Zm9yKHZhciByPVtdLGE9MCxuPXRoaXMubGVuZ3RoO24+YTthKyspe3ZhciBpPXRoaXNbYV0sbz1lLmZpZWxkVmFsdWUoaSx0KTtudWxsPT09b3x8InVuZGVmaW5lZCI9PXR5cGVvZiBvfHxvLmNvbnN0cnVjdG9yPT1BcnJheSYmIW8ubGVuZ3RofHwoby5jb25zdHJ1Y3Rvcj09QXJyYXk/ZS5tZXJnZShyLG8pOnIucHVzaChvKSl9cmV0dXJuIHJ9LGUuZmllbGRWYWx1ZT1mdW5jdGlvbih0LHIpe3ZhciBhPXQubmFtZSxuPXQudHlwZSxpPXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO2lmKHZvaWQgMD09PXImJihyPSEwKSxyJiYoIWF8fHQuZGlzYWJsZWR8fCJyZXNldCI9PW58fCJidXR0b24iPT1ufHwoImNoZWNrYm94Ij09bnx8InJhZGlvIj09bikmJiF0LmNoZWNrZWR8fCgic3VibWl0Ij09bnx8ImltYWdlIj09bikmJnQuZm9ybSYmdC5mb3JtLmNsayE9dHx8InNlbGVjdCI9PWkmJi0xPT10LnNlbGVjdGVkSW5kZXgpKXJldHVybiBudWxsO2lmKCJzZWxlY3QiPT1pKXt2YXIgbz10LnNlbGVjdGVkSW5kZXg7aWYoMD5vKXJldHVybiBudWxsO2Zvcih2YXIgcz1bXSx1PXQub3B0aW9ucyxjPSJzZWxlY3Qtb25lIj09bixsPWM/bysxOnUubGVuZ3RoLGY9Yz9vOjA7bD5mO2YrKyl7dmFyIG09dVtmXTtpZihtLnNlbGVjdGVkKXt2YXIgcD1tLnZhbHVlO2lmKHB8fChwPW0uYXR0cmlidXRlcyYmbS5hdHRyaWJ1dGVzLnZhbHVlJiYhbS5hdHRyaWJ1dGVzLnZhbHVlLnNwZWNpZmllZD9tLnRleHQ6bS52YWx1ZSksYylyZXR1cm4gcDtzLnB1c2gocCl9fXJldHVybiBzfXJldHVybiBlKHQpLnZhbCgpfSxlLmZuLmNsZWFyRm9ybT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZSgiaW5wdXQsc2VsZWN0LHRleHRhcmVhIix0aGlzKS5jbGVhckZpZWxkcyh0KX0pfSxlLmZuLmNsZWFyRmllbGRzPWUuZm4uY2xlYXJJbnB1dHM9ZnVuY3Rpb24odCl7dmFyIHI9L14oPzpjb2xvcnxkYXRlfGRhdGV0aW1lfGVtYWlsfG1vbnRofG51bWJlcnxwYXNzd29yZHxyYW5nZXxzZWFyY2h8dGVsfHRleHR8dGltZXx1cmx8d2VlaykkL2k7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBhPXRoaXMudHlwZSxuPXRoaXMudGFnTmFtZS50b0xvd2VyQ2FzZSgpO3IudGVzdChhKXx8InRleHRhcmVhIj09bj90aGlzLnZhbHVlPSIiOiJjaGVja2JveCI9PWF8fCJyYWRpbyI9PWE/dGhpcy5jaGVja2VkPSExOiJzZWxlY3QiPT1uP3RoaXMuc2VsZWN0ZWRJbmRleD0tMToiZmlsZSI9PWE/L01TSUUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk/ZSh0aGlzKS5yZXBsYWNlV2l0aChlKHRoaXMpLmNsb25lKCEwKSk6ZSh0aGlzKS52YWwoIiIpOnQmJih0PT09ITAmJi9oaWRkZW4vLnRlc3QoYSl8fCJzdHJpbmciPT10eXBlb2YgdCYmZSh0aGlzKS5pcyh0KSkmJih0aGlzLnZhbHVlPSIiKX0pfSxlLmZuLnJlc2V0Rm9ybT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXsoImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucmVzZXR8fCJvYmplY3QiPT10eXBlb2YgdGhpcy5yZXNldCYmIXRoaXMucmVzZXQubm9kZVR5cGUpJiZ0aGlzLnJlc2V0KCl9KX0sZS5mbi5lbmFibGU9ZnVuY3Rpb24oZSl7cmV0dXJuIHZvaWQgMD09PWUmJihlPSEwKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt0aGlzLmRpc2FibGVkPSFlfSl9LGUuZm4uc2VsZWN0ZWQ9ZnVuY3Rpb24odCl7cmV0dXJuIHZvaWQgMD09PXQmJih0PSEwKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgcj10aGlzLnR5cGU7aWYoImNoZWNrYm94Ij09cnx8InJhZGlvIj09cil0aGlzLmNoZWNrZWQ9dDtlbHNlIGlmKCJvcHRpb24iPT10aGlzLnRhZ05hbWUudG9Mb3dlckNhc2UoKSl7dmFyIGE9ZSh0aGlzKS5wYXJlbnQoInNlbGVjdCIpO3QmJmFbMF0mJiJzZWxlY3Qtb25lIj09YVswXS50eXBlJiZhLmZpbmQoIm9wdGlvbiIpLnNlbGVjdGVkKCExKSx0aGlzLnNlbGVjdGVkPXR9fSl9LGUuZm4uYWpheFN1Ym1pdC5kZWJ1Zz0hMX0pO1BLBwhSeh7bRDoAAEQ6AABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABgAAABzdGF0aWNcbGliXG1hcmtlZC5taW4uanMhZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUpe3RoaXMudG9rZW5zPVtdLHRoaXMudG9rZW5zLmxpbmtzPXt9LHRoaXMub3B0aW9ucz1lfHxoLmRlZmF1bHRzLHRoaXMucnVsZXM9YS5ub3JtYWwsdGhpcy5vcHRpb25zLmdmbSYmKHRoaXMucnVsZXM9dGhpcy5vcHRpb25zLnRhYmxlcz9hLnRhYmxlczphLmdmbSl9ZnVuY3Rpb24gdChlLHQpe2lmKHRoaXMub3B0aW9ucz10fHxoLmRlZmF1bHRzLHRoaXMubGlua3M9ZSx0aGlzLnJ1bGVzPXUubm9ybWFsLHRoaXMucmVuZGVyZXI9dGhpcy5vcHRpb25zLnJlbmRlcmVyfHxuZXcgbiwhdGhpcy5saW5rcyl0aHJvdyBuZXcgRXJyb3IoIlRva2VucyBhcnJheSByZXF1aXJlcyBhIGBsaW5rc2AgcHJvcGVydHkuIik7dGhpcy5vcHRpb25zLmdmbT90aGlzLnJ1bGVzPXRoaXMub3B0aW9ucy5icmVha3M/dS5icmVha3M6dS5nZm06dGhpcy5vcHRpb25zLnBlZGFudGljJiYodGhpcy5ydWxlcz11LnBlZGFudGljKX1mdW5jdGlvbiBuKCl7fWZ1bmN0aW9uIHIoZSl7dGhpcy50b2tlbnM9W10sdGhpcy50b2tlbj1udWxsLHRoaXMub3B0aW9ucz1lfHxoLmRlZmF1bHRzLHRoaXMub3B0aW9ucy5yZW5kZXJlcj10aGlzLm9wdGlvbnMucmVuZGVyZXJ8fG5ldyBuLHRoaXMucmVuZGVyZXI9dGhpcy5vcHRpb25zLnJlbmRlcmVyfWZ1bmN0aW9uIHMoZSx0KXtyZXR1cm4gZS5yZXBsYWNlKHQ/LyYvZzovJig/ISM/XHcrOykvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsiKS5yZXBsYWNlKC8+L2csIiZndDsiKS5yZXBsYWNlKC8iL2csIiZxdW90OyIpLnJlcGxhY2UoLycvZywiJiMzOTsiKX1mdW5jdGlvbiBpKGUsdCl7cmV0dXJuIGU9ZS5zb3VyY2UsdD10fHwiIixmdW5jdGlvbiBuKHIscyl7cmV0dXJuIHI/KHM9cy5zb3VyY2V8fHMscz1zLnJlcGxhY2UoLyhefFteXFtdKVxeL2csIiQxIiksZT1lLnJlcGxhY2UocixzKSxuKTpuZXcgUmVnRXhwKGUsdCl9fWZ1bmN0aW9uIGwoKXt9ZnVuY3Rpb24gbyhlKXtmb3IodmFyIHQsbixyPTE7cjxhcmd1bWVudHMubGVuZ3RoO3IrKyl7dD1hcmd1bWVudHNbcl07Zm9yKG4gaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxuKSYmKGVbbl09dFtuXSl9cmV0dXJuIGV9ZnVuY3Rpb24gaCh0LG4saSl7aWYoaXx8ImZ1bmN0aW9uIj09dHlwZW9mIG4pe2l8fChpPW4sbj1udWxsKSxuPW8oe30saC5kZWZhdWx0cyxufHx7fSk7dmFyIGwsYSx1PW4uaGlnaGxpZ2h0LHA9MDt0cnl7bD1lLmxleCh0LG4pfWNhdGNoKGMpe3JldHVybiBpKGMpfWE9bC5sZW5ndGg7dmFyIGc9ZnVuY3Rpb24oKXt2YXIgZSx0O3RyeXtlPXIucGFyc2UobCxuKX1jYXRjaChzKXt0PXN9cmV0dXJuIG4uaGlnaGxpZ2h0PXUsdD9pKHQpOmkobnVsbCxlKX07aWYoIXV8fHUubGVuZ3RoPDMpcmV0dXJuIGcoKTtpZihkZWxldGUgbi5oaWdobGlnaHQsIWEpcmV0dXJuIGcoKTtmb3IoO3A8bC5sZW5ndGg7cCsrKSFmdW5jdGlvbihlKXtyZXR1cm4iY29kZSIhPT1lLnR5cGU/LS1hfHxnKCk6dShlLnRleHQsZS5sYW5nLGZ1bmN0aW9uKHQsbil7cmV0dXJuIG51bGw9PW58fG49PT1lLnRleHQ/LS1hfHxnKCk6KGUudGV4dD1uLGUuZXNjYXBlZD0hMCwtLWF8fGcoKSx2b2lkIDApfSl9KGxbcF0pfWVsc2UgdHJ5e3JldHVybiBuJiYobj1vKHt9LGguZGVmYXVsdHMsbikpLHIucGFyc2UoZS5sZXgodCxuKSxuKX1jYXRjaChjKXtpZihjLm1lc3NhZ2UrPSJcblBsZWFzZSByZXBvcnQgdGhpcyB0byBodHRwczovL2dpdGh1Yi5jb20vY2hqai9tYXJrZWQuIiwobnx8aC5kZWZhdWx0cykuc2lsZW50KXJldHVybiI8cD5BbiBlcnJvciBvY2N1cmVkOjwvcD48cHJlPiIrcyhjLm1lc3NhZ2UrIiIsITApKyI8L3ByZT4iO3Rocm93IGN9fXZhciBhPXtuZXdsaW5lOi9eXG4rLyxjb2RlOi9eKCB7NH1bXlxuXStcbiopKy8sZmVuY2VzOmwsaHI6L14oICpbLSpfXSl7Myx9ICooPzpcbit8JCkvLGhlYWRpbmc6L14gKigjezEsNn0pICooW15cbl0rPykgKiMqICooPzpcbit8JCkvLG5wdGFibGU6bCxsaGVhZGluZzovXihbXlxuXSspXG4gKig9fC0pezIsfSAqKD86XG4rfCQpLyxibG9ja3F1b3RlOi9eKCAqPlteXG5dKyhcblteXG5dKykqXG4qKSsvLGxpc3Q6L14oICopKGJ1bGwpIFtcc1xTXSs/KD86aHJ8XG57Mix9KD8hICkoPyFcMWJ1bGwgKVxuKnxccyokKS8saHRtbDovXiAqKD86Y29tbWVudHxjbG9zZWR8Y2xvc2luZykgKig/OlxuezIsfXxccyokKS8sZGVmOi9eICpcWyhbXlxdXSspXF06ICo8PyhbXlxzPl0rKT4/KD86ICtbIihdKFteXG5dKylbIildKT8gKig/OlxuK3wkKS8sdGFibGU6bCxwYXJhZ3JhcGg6L14oKD86W15cbl0rXG4/KD8haHJ8aGVhZGluZ3xsaGVhZGluZ3xibG9ja3F1b3RlfHRhZ3xkZWYpKSspXG4qLyx0ZXh0Oi9eW15cbl0rL307YS5idWxsZXQ9Lyg/OlsqKy1dfFxkK1wuKS8sYS5pdGVtPS9eKCAqKShidWxsKSBbXlxuXSooPzpcbig/IVwxYnVsbCApW15cbl0qKSovLGEuaXRlbT1pKGEuaXRlbSwiZ20iKSgvYnVsbC9nLGEuYnVsbGV0KSgpLGEubGlzdD1pKGEubGlzdCkoL2J1bGwvZyxhLmJ1bGxldCkoImhyIiwvXG4rKD89KD86ICpbLSpfXSl7Myx9ICooPzpcbit8JCkpLykoKSxhLl90YWc9Iig/ISg/OmF8ZW18c3Ryb25nfHNtYWxsfHN8Y2l0ZXxxfGRmbnxhYmJyfGRhdGF8dGltZXxjb2RlfHZhcnxzYW1wfGtiZHxzdWJ8c3VwfGl8Ynx1fG1hcmt8cnVieXxydHxycHxiZGl8YmRvfHNwYW58YnJ8d2JyfGluc3xkZWx8aW1nKVxcYilcXHcrKD8hOi98QClcXGIiLGEuaHRtbD1pKGEuaHRtbCkoImNvbW1lbnQiLC88IS0tW1xzXFNdKj8tLT4vKSgiY2xvc2VkIiwvPCh0YWcpW1xzXFNdKz88XC9cMT4vKSgiY2xvc2luZyIsLzx0YWcoPzoiW14iXSoifCdbXiddKid8W14nIj5dKSo/Pi8pKC90YWcvZyxhLl90YWcpKCksYS5wYXJhZ3JhcGg9aShhLnBhcmFncmFwaCkoImhyIixhLmhyKSgiaGVhZGluZyIsYS5oZWFkaW5nKSgibGhlYWRpbmciLGEubGhlYWRpbmcpKCJibG9ja3F1b3RlIixhLmJsb2NrcXVvdGUpKCJ0YWciLCI8IithLl90YWcpKCJkZWYiLGEuZGVmKSgpLGEubm9ybWFsPW8oe30sYSksYS5nZm09byh7fSxhLm5vcm1hbCx7ZmVuY2VzOi9eICooYHszLH18fnszLH0pICooXFMrKT8gKlxuKFtcc1xTXSs/KVxzKlwxICooPzpcbit8JCkvLHBhcmFncmFwaDovXi99KSxhLmdmbS5wYXJhZ3JhcGg9aShhLnBhcmFncmFwaCkoIig/ISIsIig/ISIrYS5nZm0uZmVuY2VzLnNvdXJjZS5yZXBsYWNlKCJcXDEiLCJcXDIiKSsifCIrYS5saXN0LnNvdXJjZS5yZXBsYWNlKCJcXDEiLCJcXDMiKSsifCIpKCksYS50YWJsZXM9byh7fSxhLmdmbSx7bnB0YWJsZTovXiAqKFxTLipcfC4qKVxuICooWy06XSsgKlx8Wy18IDpdKilcbigoPzouKlx8LiooPzpcbnwkKSkqKVxuKi8sdGFibGU6L14gKlx8KC4rKVxuICpcfCggKlstOl0rWy18IDpdKilcbigoPzogKlx8LiooPzpcbnwkKSkqKVxuKi99KSxlLnJ1bGVzPWEsZS5sZXg9ZnVuY3Rpb24odCxuKXt2YXIgcj1uZXcgZShuKTtyZXR1cm4gci5sZXgodCl9LGUucHJvdG90eXBlLmxleD1mdW5jdGlvbihlKXtyZXR1cm4gZT1lLnJlcGxhY2UoL1xyXG58XHIvZywiXG4iKS5yZXBsYWNlKC9cdC9nLCIgICAgIikucmVwbGFjZSgvXHUwMGEwL2csIiAiKS5yZXBsYWNlKC9cdTI0MjQvZywiXG4iKSx0aGlzLnRva2VuKGUsITApfSxlLnByb3RvdHlwZS50b2tlbj1mdW5jdGlvbihlLHQpe2Zvcih2YXIgbixyLHMsaSxsLG8saCx1LHAsZT1lLnJlcGxhY2UoL14gKyQvZ20sIiIpO2U7KWlmKChzPXRoaXMucnVsZXMubmV3bGluZS5leGVjKGUpKSYmKGU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHNbMF0ubGVuZ3RoPjEmJnRoaXMudG9rZW5zLnB1c2goe3R5cGU6InNwYWNlIn0pKSxzPXRoaXMucnVsZXMuY29kZS5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHM9c1swXS5yZXBsYWNlKC9eIHs0fS9nbSwiIiksdGhpcy50b2tlbnMucHVzaCh7dHlwZToiY29kZSIsdGV4dDp0aGlzLm9wdGlvbnMucGVkYW50aWM/czpzLnJlcGxhY2UoL1xuKyQvLCIiKX0pO2Vsc2UgaWYocz10aGlzLnJ1bGVzLmZlbmNlcy5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6ImNvZGUiLGxhbmc6c1syXSx0ZXh0OnNbM119KTtlbHNlIGlmKHM9dGhpcy5ydWxlcy5oZWFkaW5nLmV4ZWMoZSkpZT1lLnN1YnN0cmluZyhzWzBdLmxlbmd0aCksdGhpcy50b2tlbnMucHVzaCh7dHlwZToiaGVhZGluZyIsZGVwdGg6c1sxXS5sZW5ndGgsdGV4dDpzWzJdfSk7ZWxzZSBpZih0JiYocz10aGlzLnJ1bGVzLm5wdGFibGUuZXhlYyhlKSkpe2ZvcihlPWUuc3Vic3RyaW5nKHNbMF0ubGVuZ3RoKSxvPXt0eXBlOiJ0YWJsZSIsaGVhZGVyOnNbMV0ucmVwbGFjZSgvXiAqfCAqXHwgKiQvZywiIikuc3BsaXQoLyAqXHwgKi8pLGFsaWduOnNbMl0ucmVwbGFjZSgvXiAqfFx8ICokL2csIiIpLnNwbGl0KC8gKlx8ICovKSxjZWxsczpzWzNdLnJlcGxhY2UoL1xuJC8sIiIpLnNwbGl0KCJcbiIpfSx1PTA7dTxvLmFsaWduLmxlbmd0aDt1Kyspby5hbGlnblt1XT0vXiAqLSs6ICokLy50ZXN0KG8uYWxpZ25bdV0pPyJyaWdodCI6L14gKjotKzogKiQvLnRlc3Qoby5hbGlnblt1XSk/ImNlbnRlciI6L14gKjotKyAqJC8udGVzdChvLmFsaWduW3VdKT8ibGVmdCI6bnVsbDtmb3IodT0wO3U8by5jZWxscy5sZW5ndGg7dSsrKW8uY2VsbHNbdV09by5jZWxsc1t1XS5zcGxpdCgvICpcfCAqLyk7dGhpcy50b2tlbnMucHVzaChvKX1lbHNlIGlmKHM9dGhpcy5ydWxlcy5saGVhZGluZy5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6ImhlYWRpbmciLGRlcHRoOiI9Ij09PXNbMl0/MToyLHRleHQ6c1sxXX0pO2Vsc2UgaWYocz10aGlzLnJ1bGVzLmhyLmV4ZWMoZSkpZT1lLnN1YnN0cmluZyhzWzBdLmxlbmd0aCksdGhpcy50b2tlbnMucHVzaCh7dHlwZToiaHIifSk7ZWxzZSBpZihzPXRoaXMucnVsZXMuYmxvY2txdW90ZS5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6ImJsb2NrcXVvdGVfc3RhcnQifSkscz1zWzBdLnJlcGxhY2UoL14gKj4gPy9nbSwiIiksdGhpcy50b2tlbihzLHQpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6ImJsb2NrcXVvdGVfZW5kIn0pO2Vsc2UgaWYocz10aGlzLnJ1bGVzLmxpc3QuZXhlYyhlKSl7Zm9yKGU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLGk9c1syXSx0aGlzLnRva2Vucy5wdXNoKHt0eXBlOiJsaXN0X3N0YXJ0IixvcmRlcmVkOmkubGVuZ3RoPjF9KSxzPXNbMF0ubWF0Y2godGhpcy5ydWxlcy5pdGVtKSxuPSExLHA9cy5sZW5ndGgsdT0wO3A+dTt1Kyspbz1zW3VdLGg9by5sZW5ndGgsbz1vLnJlcGxhY2UoL14gKihbKistXXxcZCtcLikgKy8sIiIpLH5vLmluZGV4T2YoIlxuICIpJiYoaC09by5sZW5ndGgsbz10aGlzLm9wdGlvbnMucGVkYW50aWM/by5yZXBsYWNlKC9eIHsxLDR9L2dtLCIiKTpvLnJlcGxhY2UobmV3IFJlZ0V4cCgiXiB7MSwiK2grIn0iLCJnbSIpLCIiKSksdGhpcy5vcHRpb25zLnNtYXJ0TGlzdHMmJnUhPT1wLTEmJihsPWEuYnVsbGV0LmV4ZWMoc1t1KzFdKVswXSxpPT09bHx8aS5sZW5ndGg+MSYmbC5sZW5ndGg+MXx8KGU9cy5zbGljZSh1KzEpLmpvaW4oIlxuIikrZSx1PXAtMSkpLHI9bnx8L1xuXG4oPyFccyokKS8udGVzdChvKSx1IT09cC0xJiYobj0iXG4iPT09by5jaGFyQXQoby5sZW5ndGgtMSkscnx8KHI9bikpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6cj8ibG9vc2VfaXRlbV9zdGFydCI6Imxpc3RfaXRlbV9zdGFydCJ9KSx0aGlzLnRva2VuKG8sITEpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6Imxpc3RfaXRlbV9lbmQifSk7dGhpcy50b2tlbnMucHVzaCh7dHlwZToibGlzdF9lbmQifSl9ZWxzZSBpZihzPXRoaXMucnVsZXMuaHRtbC5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLHRoaXMudG9rZW5zLnB1c2goe3R5cGU6dGhpcy5vcHRpb25zLnNhbml0aXplPyJwYXJhZ3JhcGgiOiJodG1sIixwcmU6InByZSI9PT1zWzFdfHwic2NyaXB0Ij09PXNbMV18fCJzdHlsZSI9PT1zWzFdLHRleHQ6c1swXX0pO2Vsc2UgaWYodCYmKHM9dGhpcy5ydWxlcy5kZWYuZXhlYyhlKSkpZT1lLnN1YnN0cmluZyhzWzBdLmxlbmd0aCksdGhpcy50b2tlbnMubGlua3Nbc1sxXS50b0xvd2VyQ2FzZSgpXT17aHJlZjpzWzJdLHRpdGxlOnNbM119O2Vsc2UgaWYodCYmKHM9dGhpcy5ydWxlcy50YWJsZS5leGVjKGUpKSl7Zm9yKGU9ZS5zdWJzdHJpbmcoc1swXS5sZW5ndGgpLG89e3R5cGU6InRhYmxlIixoZWFkZXI6c1sxXS5yZXBsYWNlKC9eICp8ICpcfCAqJC9nLCIiKS5zcGxpdCgvICpcfCAqLyksYWxpZ246c1syXS5yZXBsYWNlKC9eICp8XHwgKiQvZywiIikuc3BsaXQoLyAqXHwgKi8pLGNlbGxzOnNbM10ucmVwbGFjZSgvKD86ICpcfCAqKT9cbiQvLCIiKS5zcGxpdCgiXG4iKX0sdT0wO3U8by5hbGlnbi5sZW5ndGg7dSsrKW8uYWxpZ25bdV09L14gKi0rOiAqJC8udGVzdChvLmFsaWduW3VdKT8icmlnaHQiOi9eICo6LSs6ICokLy50ZXN0KG8uYWxpZ25bdV0pPyJjZW50ZXIiOi9eICo6LSsgKiQvLnRlc3Qoby5hbGlnblt1XSk/ImxlZnQiOm51bGw7Zm9yKHU9MDt1PG8uY2VsbHMubGVuZ3RoO3UrKylvLmNlbGxzW3VdPW8uY2VsbHNbdV0ucmVwbGFjZSgvXiAqXHwgKnwgKlx8ICokL2csIiIpLnNwbGl0KC8gKlx8ICovKTt0aGlzLnRva2Vucy5wdXNoKG8pfWVsc2UgaWYodCYmKHM9dGhpcy5ydWxlcy5wYXJhZ3JhcGguZXhlYyhlKSkpZT1lLnN1YnN0cmluZyhzWzBdLmxlbmd0aCksdGhpcy50b2tlbnMucHVzaCh7dHlwZToicGFyYWdyYXBoIix0ZXh0OiJcbiI9PT1zWzFdLmNoYXJBdChzWzFdLmxlbmd0aC0xKT9zWzFdLnNsaWNlKDAsLTEpOnNbMV19KTtlbHNlIGlmKHM9dGhpcy5ydWxlcy50ZXh0LmV4ZWMoZSkpZT1lLnN1YnN0cmluZyhzWzBdLmxlbmd0aCksdGhpcy50b2tlbnMucHVzaCh7dHlwZToidGV4dCIsdGV4dDpzWzBdfSk7ZWxzZSBpZihlKXRocm93IG5ldyBFcnJvcigiSW5maW5pdGUgbG9vcCBvbiBieXRlOiAiK2UuY2hhckNvZGVBdCgwKSk7cmV0dXJuIHRoaXMudG9rZW5zfTt2YXIgdT17ZXNjYXBlOi9eXFwoW1xcYCp7fVxbXF0oKSMrXC0uIV8+XSkvLGF1dG9saW5rOi9ePChbXiA+XSsoQHw6XC8pW14gPl0rKT4vLHVybDpsLHRhZzovXjwhLS1bXHNcU10qPy0tPnxePFwvP1x3Kyg/OiJbXiJdKiJ8J1teJ10qJ3xbXiciPl0pKj8+LyxsaW5rOi9eIT9cWyhpbnNpZGUpXF1cKGhyZWZcKS8scmVmbGluazovXiE/XFsoaW5zaWRlKVxdXHMqXFsoW15cXV0qKVxdLyxub2xpbms6L14hP1xbKCg/OlxbW15cXV0qXF18W15cW1xdXSkqKVxdLyxzdHJvbmc6L15fXyhbXHNcU10rPylfXyg/IV8pfF5cKlwqKFtcc1xTXSs/KVwqXCooPyFcKikvLGVtOi9eXGJfKCg/Ol9ffFtcc1xTXSkrPylfXGJ8XlwqKCg/OlwqXCp8W1xzXFNdKSs/KVwqKD8hXCopLyxjb2RlOi9eKGArKVxzKihbXHNcU10qP1teYF0pXHMqXDEoPyFgKS8sYnI6L14gezIsfVxuKD8hXHMqJCkvLGRlbDpsLHRleHQ6L15bXHNcU10rPyg/PVtcXDwhXFtfKmBdfCB7Mix9XG58JCkvfTt1Ll9pbnNpZGU9Lyg/OlxbW15cXV0qXF18W15cW1xdXXxcXSg/PVteXFtdKlxdKSkqLyx1Ll9ocmVmPS9ccyo8PyhbXHNcU10qPyk+Pyg/OlxzK1snIl0oW1xzXFNdKj8pWyciXSk/XHMqLyx1Lmxpbms9aSh1LmxpbmspKCJpbnNpZGUiLHUuX2luc2lkZSkoImhyZWYiLHUuX2hyZWYpKCksdS5yZWZsaW5rPWkodS5yZWZsaW5rKSgiaW5zaWRlIix1Ll9pbnNpZGUpKCksdS5ub3JtYWw9byh7fSx1KSx1LnBlZGFudGljPW8oe30sdS5ub3JtYWwse3N0cm9uZzovXl9fKD89XFMpKFtcc1xTXSo/XFMpX18oPyFfKXxeXCpcKig/PVxTKShbXHNcU10qP1xTKVwqXCooPyFcKikvLGVtOi9eXyg/PVxTKShbXHNcU10qP1xTKV8oPyFfKXxeXCooPz1cUykoW1xzXFNdKj9cUylcKig/IVwqKS99KSx1LmdmbT1vKHt9LHUubm9ybWFsLHtlc2NhcGU6aSh1LmVzY2FwZSkoIl0pIiwifnxdKSIpKCksdXJsOi9eKGh0dHBzPzpcL1wvW15cczxdK1tePC4sOjsiJylcXVxzXSkvLGRlbDovXn5+KD89XFMpKFtcc1xTXSo/XFMpfn4vLHRleHQ6aSh1LnRleHQpKCJdfCIsIn5dfCIpKCJ8IiwifGh0dHBzPzovL3wiKSgpfSksdS5icmVha3M9byh7fSx1LmdmbSx7YnI6aSh1LmJyKSgiezIsfSIsIioiKSgpLHRleHQ6aSh1LmdmbS50ZXh0KSgiezIsfSIsIioiKSgpfSksdC5ydWxlcz11LHQub3V0cHV0PWZ1bmN0aW9uKGUsbixyKXt2YXIgcz1uZXcgdChuLHIpO3JldHVybiBzLm91dHB1dChlKX0sdC5wcm90b3R5cGUub3V0cHV0PWZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxuLHIsaSxsPSIiO2U7KWlmKGk9dGhpcy5ydWxlcy5lc2NhcGUuZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz1pWzFdO2Vsc2UgaWYoaT10aGlzLnJ1bGVzLmF1dG9saW5rLmV4ZWMoZSkpZT1lLnN1YnN0cmluZyhpWzBdLmxlbmd0aCksIkAiPT09aVsyXT8obj0iOiI9PT1pWzFdLmNoYXJBdCg2KT90aGlzLm1hbmdsZShpWzFdLnN1YnN0cmluZyg3KSk6dGhpcy5tYW5nbGUoaVsxXSkscj10aGlzLm1hbmdsZSgibWFpbHRvOiIpK24pOihuPXMoaVsxXSkscj1uKSxsKz10aGlzLnJlbmRlcmVyLmxpbmsocixudWxsLG4pO2Vsc2UgaWYoaT10aGlzLnJ1bGVzLnVybC5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoaVswXS5sZW5ndGgpLG49cyhpWzFdKSxyPW4sbCs9dGhpcy5yZW5kZXJlci5saW5rKHIsbnVsbCxuKTtlbHNlIGlmKGk9dGhpcy5ydWxlcy50YWcuZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz10aGlzLm9wdGlvbnMuc2FuaXRpemU/cyhpWzBdKTppWzBdO2Vsc2UgaWYoaT10aGlzLnJ1bGVzLmxpbmsuZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz10aGlzLm91dHB1dExpbmsoaSx7aHJlZjppWzJdLHRpdGxlOmlbM119KTtlbHNlIGlmKChpPXRoaXMucnVsZXMucmVmbGluay5leGVjKGUpKXx8KGk9dGhpcy5ydWxlcy5ub2xpbmsuZXhlYyhlKSkpe2lmKGU9ZS5zdWJzdHJpbmcoaVswXS5sZW5ndGgpLHQ9KGlbMl18fGlbMV0pLnJlcGxhY2UoL1xzKy9nLCIgIiksdD10aGlzLmxpbmtzW3QudG9Mb3dlckNhc2UoKV0sIXR8fCF0LmhyZWYpe2wrPWlbMF0uY2hhckF0KDApLGU9aVswXS5zdWJzdHJpbmcoMSkrZTtjb250aW51ZX1sKz10aGlzLm91dHB1dExpbmsoaSx0KX1lbHNlIGlmKGk9dGhpcy5ydWxlcy5zdHJvbmcuZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz10aGlzLnJlbmRlcmVyLnN0cm9uZyh0aGlzLm91dHB1dChpWzJdfHxpWzFdKSk7ZWxzZSBpZihpPXRoaXMucnVsZXMuZW0uZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz10aGlzLnJlbmRlcmVyLmVtKHRoaXMub3V0cHV0KGlbMl18fGlbMV0pKTtlbHNlIGlmKGk9dGhpcy5ydWxlcy5jb2RlLmV4ZWMoZSkpZT1lLnN1YnN0cmluZyhpWzBdLmxlbmd0aCksbCs9dGhpcy5yZW5kZXJlci5jb2Rlc3BhbihzKGlbMl0sITApKTtlbHNlIGlmKGk9dGhpcy5ydWxlcy5ici5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoaVswXS5sZW5ndGgpLGwrPXRoaXMucmVuZGVyZXIuYnIoKTtlbHNlIGlmKGk9dGhpcy5ydWxlcy5kZWwuZXhlYyhlKSllPWUuc3Vic3RyaW5nKGlbMF0ubGVuZ3RoKSxsKz10aGlzLnJlbmRlcmVyLmRlbCh0aGlzLm91dHB1dChpWzFdKSk7ZWxzZSBpZihpPXRoaXMucnVsZXMudGV4dC5leGVjKGUpKWU9ZS5zdWJzdHJpbmcoaVswXS5sZW5ndGgpLGwrPXModGhpcy5zbWFydHlwYW50cyhpWzBdKSk7ZWxzZSBpZihlKXRocm93IG5ldyBFcnJvcigiSW5maW5pdGUgbG9vcCBvbiBieXRlOiAiK2UuY2hhckNvZGVBdCgwKSk7cmV0dXJuIGx9LHQucHJvdG90eXBlLm91dHB1dExpbms9ZnVuY3Rpb24oZSx0KXt2YXIgbj1zKHQuaHJlZikscj10LnRpdGxlP3ModC50aXRsZSk6bnVsbDtyZXR1cm4iISIhPT1lWzBdLmNoYXJBdCgwKT90aGlzLnJlbmRlcmVyLmxpbmsobixyLHRoaXMub3V0cHV0KGVbMV0pKTp0aGlzLnJlbmRlcmVyLmltYWdlKG4scixzKGVbMV0pKX0sdC5wcm90b3R5cGUuc21hcnR5cGFudHM9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMub3B0aW9ucy5zbWFydHlwYW50cz9lLnJlcGxhY2UoLy0tL2csIuKAlCIpLnJlcGxhY2UoLyhefFstXHUyMDE0LyhcW3siXHNdKScvZywiJDHigJgiKS5yZXBsYWNlKC8nL2csIuKAmSIpLnJlcGxhY2UoLyhefFstXHUyMDE0LyhcW3tcdTIwMThcc10pIi9nLCIkMeKAnCIpLnJlcGxhY2UoLyIvZywi4oCdIikucmVwbGFjZSgvXC57M30vZywi4oCmIik6ZX0sdC5wcm90b3R5cGUubWFuZ2xlPWZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxuPSIiLHI9ZS5sZW5ndGgscz0wO3I+cztzKyspdD1lLmNoYXJDb2RlQXQocyksTWF0aC5yYW5kb20oKT4uNSYmKHQ9IngiK3QudG9TdHJpbmcoMTYpKSxuKz0iJiMiK3QrIjsiO3JldHVybiBufSxuLnByb3RvdHlwZS5jb2RlPWZ1bmN0aW9uKGUsdCxuLHIpe2lmKHI9cnx8e30sci5oaWdobGlnaHQpe3ZhciBpPXIuaGlnaGxpZ2h0KGUsdCk7bnVsbCE9aSYmaSE9PWUmJihuPSEwLGU9aSl9cmV0dXJuIHQ/JzxwcmU+PGNvZGUgY2xhc3M9Iicrci5sYW5nUHJlZml4K3QrJyI+Jysobj9lOnMoZSkpKyJcbjwvY29kZT48L3ByZT5cbiI6IjxwcmU+PGNvZGU+Iisobj9lOnMoZSwhMCkpKyJcbjwvY29kZT48L3ByZT4ifSxuLnByb3RvdHlwZS5ibG9ja3F1b3RlPWZ1bmN0aW9uKGUpe3JldHVybiI8YmxvY2txdW90ZT5cbiIrZSsiPC9ibG9ja3F1b3RlPlxuIn0sbi5wcm90b3R5cGUuaHRtbD1mdW5jdGlvbihlKXtyZXR1cm4gZX0sbi5wcm90b3R5cGUuaGVhZGluZz1mdW5jdGlvbihlLHQsbixyKXtyZXR1cm4iPGgiK3QrJyBpZD0iJytyLmhlYWRlclByZWZpeCtuLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvW15cd10rL2csIi0iKSsnIj4nK2UrIjwvaCIrdCsiPlxuIn0sbi5wcm90b3R5cGUuaHI9ZnVuY3Rpb24oKXtyZXR1cm4iPGhyPlxuIn0sbi5wcm90b3R5cGUubGlzdD1mdW5jdGlvbihlLHQpe3ZhciBuPXQ/Im9sIjoidWwiO3JldHVybiI8IituKyI+XG4iK2UrIjwvIituKyI+XG4ifSxuLnByb3RvdHlwZS5saXN0aXRlbT1mdW5jdGlvbihlKXtyZXR1cm4iPGxpPiIrZSsiPC9saT5cbiJ9LG4ucHJvdG90eXBlLnBhcmFncmFwaD1mdW5jdGlvbihlKXtyZXR1cm4iPHA+IitlKyI8L3A+XG4ifSxuLnByb3RvdHlwZS50YWJsZT1mdW5jdGlvbihlLHQpe3JldHVybiI8dGFibGU+XG48dGhlYWQ+XG4iK2UrIjwvdGhlYWQ+XG4iKyI8dGJvZHk+XG4iK3QrIjwvdGJvZHk+XG4iKyI8L3RhYmxlPlxuIn0sbi5wcm90b3R5cGUudGFibGVyb3c9ZnVuY3Rpb24oZSl7cmV0dXJuIjx0cj5cbiIrZSsiPC90cj5cbiJ9LG4ucHJvdG90eXBlLnRhYmxlY2VsbD1mdW5jdGlvbihlLHQpe3ZhciBuPXQuaGVhZGVyPyJ0aCI6InRkIixyPXQuYWxpZ24/IjwiK24rJyBzdHlsZT0idGV4dC1hbGlnbjonK3QuYWxpZ24rJyI+JzoiPCIrbisiPiI7cmV0dXJuIHIrZSsiPC8iK24rIj5cbiJ9LG4ucHJvdG90eXBlLnN0cm9uZz1mdW5jdGlvbihlKXtyZXR1cm4iPHN0cm9uZz4iK2UrIjwvc3Ryb25nPiJ9LG4ucHJvdG90eXBlLmVtPWZ1bmN0aW9uKGUpe3JldHVybiI8ZW0+IitlKyI8L2VtPiJ9LG4ucHJvdG90eXBlLmNvZGVzcGFuPWZ1bmN0aW9uKGUpe3JldHVybiI8Y29kZT4iK2UrIjwvY29kZT4ifSxuLnByb3RvdHlwZS5icj1mdW5jdGlvbigpe3JldHVybiI8YnI+In0sbi5wcm90b3R5cGUuZGVsPWZ1bmN0aW9uKGUpe3JldHVybiI8ZGVsPiIrZSsiPC9kZWw+In0sbi5wcm90b3R5cGUubGluaz1mdW5jdGlvbihlLHQsbil7dmFyIHI9JzxhIGhyZWY9IicrZSsnIic7cmV0dXJuIHQmJihyKz0nIHRpdGxlPSInK3QrJyInKSxyKz0iPiIrbisiPC9hPiJ9LG4ucHJvdG90eXBlLmltYWdlPWZ1bmN0aW9uKGUsdCxuKXt2YXIgcj0nPGltZyBzcmM9IicrZSsnIiBhbHQ9IicrbisnIic7cmV0dXJuIHQmJihyKz0nIHRpdGxlPSInK3QrJyInKSxyKz0iPiJ9LHIucGFyc2U9ZnVuY3Rpb24oZSx0LG4pe3ZhciBzPW5ldyByKHQsbik7cmV0dXJuIHMucGFyc2UoZSl9LHIucHJvdG90eXBlLnBhcnNlPWZ1bmN0aW9uKGUpe3RoaXMuaW5saW5lPW5ldyB0KGUubGlua3MsdGhpcy5vcHRpb25zLHRoaXMucmVuZGVyZXIpLHRoaXMudG9rZW5zPWUucmV2ZXJzZSgpO2Zvcih2YXIgbj0iIjt0aGlzLm5leHQoKTspbis9dGhpcy50b2soKTtyZXR1cm4gbn0sci5wcm90b3R5cGUubmV4dD1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRva2VuPXRoaXMudG9rZW5zLnBvcCgpfSxyLnByb3RvdHlwZS5wZWVrPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudG9rZW5zW3RoaXMudG9rZW5zLmxlbmd0aC0xXXx8MH0sci5wcm90b3R5cGUucGFyc2VUZXh0PWZ1bmN0aW9uKCl7Zm9yKHZhciBlPXRoaXMudG9rZW4udGV4dDsidGV4dCI9PT10aGlzLnBlZWsoKS50eXBlOyllKz0iXG4iK3RoaXMubmV4dCgpLnRleHQ7cmV0dXJuIHRoaXMuaW5saW5lLm91dHB1dChlKX0sci5wcm90b3R5cGUudG9rPWZ1bmN0aW9uKCl7c3dpdGNoKHRoaXMudG9rZW4udHlwZSl7Y2FzZSJzcGFjZSI6cmV0dXJuIiI7Y2FzZSJociI6cmV0dXJuIHRoaXMucmVuZGVyZXIuaHIoKTtjYXNlImhlYWRpbmciOnJldHVybiB0aGlzLnJlbmRlcmVyLmhlYWRpbmcodGhpcy5pbmxpbmUub3V0cHV0KHRoaXMudG9rZW4udGV4dCksdGhpcy50b2tlbi5kZXB0aCx0aGlzLnRva2VuLnRleHQsdGhpcy5vcHRpb25zKTtjYXNlImNvZGUiOnJldHVybiB0aGlzLnJlbmRlcmVyLmNvZGUodGhpcy50b2tlbi50ZXh0LHRoaXMudG9rZW4ubGFuZyx0aGlzLnRva2VuLmVzY2FwZWQsdGhpcy5vcHRpb25zKTtjYXNlInRhYmxlIjp2YXIgZSx0LG4scixzLGk9IiIsbD0iIjtmb3Iobj0iIixlPTA7ZTx0aGlzLnRva2VuLmhlYWRlci5sZW5ndGg7ZSsrKXI9e2hlYWRlcjohMCxhbGlnbjp0aGlzLnRva2VuLmFsaWduW2VdfSxuKz10aGlzLnJlbmRlcmVyLnRhYmxlY2VsbCh0aGlzLmlubGluZS5vdXRwdXQodGhpcy50b2tlbi5oZWFkZXJbZV0pLHtoZWFkZXI6ITAsYWxpZ246dGhpcy50b2tlbi5hbGlnbltlXX0pO2ZvcihpKz10aGlzLnJlbmRlcmVyLnRhYmxlcm93KG4pLGU9MDtlPHRoaXMudG9rZW4uY2VsbHMubGVuZ3RoO2UrKyl7Zm9yKHQ9dGhpcy50b2tlbi5jZWxsc1tlXSxuPSIiLHM9MDtzPHQubGVuZ3RoO3MrKyluKz10aGlzLnJlbmRlcmVyLnRhYmxlY2VsbCh0aGlzLmlubGluZS5vdXRwdXQodFtzXSkse2hlYWRlcjohMSxhbGlnbjp0aGlzLnRva2VuLmFsaWduW3NdfSk7bCs9dGhpcy5yZW5kZXJlci50YWJsZXJvdyhuKX1yZXR1cm4gdGhpcy5yZW5kZXJlci50YWJsZShpLGwpO2Nhc2UiYmxvY2txdW90ZV9zdGFydCI6Zm9yKHZhciBsPSIiOyJibG9ja3F1b3RlX2VuZCIhPT10aGlzLm5leHQoKS50eXBlOylsKz10aGlzLnRvaygpO3JldHVybiB0aGlzLnJlbmRlcmVyLmJsb2NrcXVvdGUobCk7Y2FzZSJsaXN0X3N0YXJ0Ijpmb3IodmFyIGw9IiIsbz10aGlzLnRva2VuLm9yZGVyZWQ7Imxpc3RfZW5kIiE9PXRoaXMubmV4dCgpLnR5cGU7KWwrPXRoaXMudG9rKCk7cmV0dXJuIHRoaXMucmVuZGVyZXIubGlzdChsLG8pO2Nhc2UibGlzdF9pdGVtX3N0YXJ0Ijpmb3IodmFyIGw9IiI7Imxpc3RfaXRlbV9lbmQiIT09dGhpcy5uZXh0KCkudHlwZTspbCs9InRleHQiPT09dGhpcy50b2tlbi50eXBlP3RoaXMucGFyc2VUZXh0KCk6dGhpcy50b2soKTtyZXR1cm4gdGhpcy5yZW5kZXJlci5saXN0aXRlbShsKTtjYXNlImxvb3NlX2l0ZW1fc3RhcnQiOmZvcih2YXIgbD0iIjsibGlzdF9pdGVtX2VuZCIhPT10aGlzLm5leHQoKS50eXBlOylsKz10aGlzLnRvaygpO3JldHVybiB0aGlzLnJlbmRlcmVyLmxpc3RpdGVtKGwpO2Nhc2UiaHRtbCI6dmFyIGg9dGhpcy50b2tlbi5wcmV8fHRoaXMub3B0aW9ucy5wZWRhbnRpYz90aGlzLnRva2VuLnRleHQ6dGhpcy5pbmxpbmUub3V0cHV0KHRoaXMudG9rZW4udGV4dCk7cmV0dXJuIHRoaXMucmVuZGVyZXIuaHRtbChoKTtjYXNlInBhcmFncmFwaCI6cmV0dXJuIHRoaXMucmVuZGVyZXIucGFyYWdyYXBoKHRoaXMuaW5saW5lLm91dHB1dCh0aGlzLnRva2VuLnRleHQpKTtjYXNlInRleHQiOnJldHVybiB0aGlzLnJlbmRlcmVyLnBhcmFncmFwaCh0aGlzLnBhcnNlVGV4dCgpKX19LGwuZXhlYz1sLGgub3B0aW9ucz1oLnNldE9wdGlvbnM9ZnVuY3Rpb24oZSl7cmV0dXJuIG8oaC5kZWZhdWx0cyxlKSxofSxoLmRlZmF1bHRzPXtnZm06ITAsdGFibGVzOiEwLGJyZWFrczohMSxwZWRhbnRpYzohMSxzYW5pdGl6ZTohMSxzbWFydExpc3RzOiExLHNpbGVudDohMSxoaWdobGlnaHQ6bnVsbCxsYW5nUHJlZml4OiJsYW5nLSIsc21hcnR5cGFudHM6ITEsaGVhZGVyUHJlZml4OiIiLHJlbmRlcmVyOm5ldyBufSxoLlBhcnNlcj1yLGgucGFyc2VyPXIucGFyc2UsaC5SZW5kZXJlcj1uLGguTGV4ZXI9ZSxoLmxleGVyPWUubGV4LGguSW5saW5lTGV4ZXI9dCxoLmlubGluZUxleGVyPXQub3V0cHV0LGgucGFyc2U9aCwib2JqZWN0Ij09dHlwZW9mIGV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9aDoiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShmdW5jdGlvbigpe3JldHVybiBofSk6dGhpcy5tYXJrZWQ9aH0uY2FsbChmdW5jdGlvbigpe3JldHVybiB0aGlzfHwoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3c/d2luZG93Omdsb2JhbCl9KCkpO1BLBwhC+kxqUzkAAFM5AABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABoAAABzdGF0aWNcbGliXHZhbGlkYXRlLm1pbi5qcy8qCiAqIHZhbGlkYXRlLmpzIDEuMwogKiBDb3B5cmlnaHQgKGMpIDIwMTMgUmljayBIYXJyaXNvbiwgaHR0cDovL3JpY2toYXJyaXNvbi5tZQogKiB2YWxpZGF0ZS5qcyBpcyBvcGVuIHNvdXJjZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLgogKiBQb3J0aW9ucyBvZiB2YWxpZGF0ZS5qcyBhcmUgaW5zcGlyZWQgYnkgQ29kZUlnbml0ZXIuCiAqIGh0dHA6Ly9yaWNraGFycmlzb24uZ2l0aHViLmNvbS92YWxpZGF0ZS5qcwogKi8KCihmdW5jdGlvbihxLHIsbSl7dmFyIHM9e3JlcXVpcmVkOiJUaGUgJXMgZmllbGQgaXMgcmVxdWlyZWQuIixtYXRjaGVzOiJUaGUgJXMgZmllbGQgZG9lcyBub3QgbWF0Y2ggdGhlICVzIGZpZWxkLiIsImRlZmF1bHQiOiJUaGUgJXMgZmllbGQgaXMgc3RpbGwgc2V0IHRvIGRlZmF1bHQsIHBsZWFzZSBjaGFuZ2UuIix2YWxpZF9lbWFpbDoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBhIHZhbGlkIGVtYWlsIGFkZHJlc3MuIix2YWxpZF9lbWFpbHM6IlRoZSAlcyBmaWVsZCBtdXN0IGNvbnRhaW4gYWxsIHZhbGlkIGVtYWlsIGFkZHJlc3Nlcy4iLG1pbl9sZW5ndGg6IlRoZSAlcyBmaWVsZCBtdXN0IGJlIGF0IGxlYXN0ICVzIGNoYXJhY3RlcnMgaW4gbGVuZ3RoLiIsbWF4X2xlbmd0aDoiVGhlICVzIGZpZWxkIG11c3Qgbm90IGV4Y2VlZCAlcyBjaGFyYWN0ZXJzIGluIGxlbmd0aC4iLGV4YWN0X2xlbmd0aDoiVGhlICVzIGZpZWxkIG11c3QgYmUgZXhhY3RseSAlcyBjaGFyYWN0ZXJzIGluIGxlbmd0aC4iLGdyZWF0ZXJfdGhhbjoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBhIG51bWJlciBncmVhdGVyIHRoYW4gJXMuIixsZXNzX3RoYW46IlRoZSAlcyBmaWVsZCBtdXN0IGNvbnRhaW4gYSBudW1iZXIgbGVzcyB0aGFuICVzLiIsYWxwaGE6IlRoZSAlcyBmaWVsZCBtdXN0IG9ubHkgY29udGFpbiBhbHBoYWJldGljYWwgY2hhcmFjdGVycy4iLGFscGhhX251bWVyaWM6IlRoZSAlcyBmaWVsZCBtdXN0IG9ubHkgY29udGFpbiBhbHBoYS1udW1lcmljIGNoYXJhY3RlcnMuIixhbHBoYV9kYXNoOiJUaGUgJXMgZmllbGQgbXVzdCBvbmx5IGNvbnRhaW4gYWxwaGEtbnVtZXJpYyBjaGFyYWN0ZXJzLCB1bmRlcnNjb3JlcywgYW5kIGRhc2hlcy4iLG51bWVyaWM6IlRoZSAlcyBmaWVsZCBtdXN0IGNvbnRhaW4gb25seSBudW1iZXJzLiIsaW50ZWdlcjoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBhbiBpbnRlZ2VyLiIsZGVjaW1hbDoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBhIGRlY2ltYWwgbnVtYmVyLiIsaXNfbmF0dXJhbDoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBvbmx5IHBvc2l0aXZlIG51bWJlcnMuIixpc19uYXR1cmFsX25vX3plcm86IlRoZSAlcyBmaWVsZCBtdXN0IGNvbnRhaW4gYSBudW1iZXIgZ3JlYXRlciB0aGFuIHplcm8uIix2YWxpZF9pcDoiVGhlICVzIGZpZWxkIG11c3QgY29udGFpbiBhIHZhbGlkIElQLiIsdmFsaWRfYmFzZTY0OiJUaGUgJXMgZmllbGQgbXVzdCBjb250YWluIGEgYmFzZTY0IHN0cmluZy4iLHZhbGlkX2NyZWRpdF9jYXJkOiJUaGUgJXMgZmllbGQgbXVzdCBjb250YWluIGEgdmFsaWQgY3JlZGl0IGNhcmQgbnVtYmVyLiIsaXNfZmlsZV90eXBlOiJUaGUgJXMgZmllbGQgbXVzdCBjb250YWluIG9ubHkgJXMgZmlsZXMuIix2YWxpZF91cmw6IlRoZSAlcyBmaWVsZCBtdXN0IGNvbnRhaW4gYSB2YWxpZCBVUkwuIn0sdD1mdW5jdGlvbihhKXt9LHU9L14oLis/KVxbKC4rKVxdJC8saD0vXlswLTldKyQvLHY9L15cLT9bMC05XSskLyxrPS9eXC0/WzAtOV0qXC4/WzAtOV0rJC8scD0vXlthLXpBLVowLTkuISMkJSZhbXA7JyorXC1cLz0/XF5fYHt8fX5cLV0rQFthLXpBLVowLTlcLV0rKD86XC5bYS16QS1aMC05XC1dKykqJC8sdz0vXlthLXpdKyQvaSx4PS9eW2EtejAtOV0rJC9pLHk9L15bYS16MC05X1wtXSskL2ksej0vXlswLTldKyQvaSxBPS9eWzEtOV1bMC05XSokL2ksQj0vXigoMjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV17Mn18WzAtOV17MSwyfSlcLil7M30oMjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV17Mn18WzAtOV17MSwyfSkkL2ksQz0vW15hLXpBLVowLTlcL1wrPV0vaSxEPS9eW1xkXC1cc10rJC8sRT0vXigoaHR0cHxodHRwcyk6XC9cLyhcdys6ezAsMX1cdypAKT8oXFMrKXwpKDpbMC05XSspPyhcL3xcLyhbXHcjITouPys9JiVAIVwtXC9dKSk/JC8sZT1mdW5jdGlvbihhLGIsYyl7dGhpcy5jYWxsYmFjaz1jfHx0O3RoaXMuZXJyb3JzPVtdO3RoaXMuZmllbGRzPXt9O3RoaXMuZm9ybT10aGlzLl9mb3JtQnlOYW1lT3JOb2RlKGEpfHx7fTt0aGlzLm1lc3NhZ2VzPXt9O3RoaXMuaGFuZGxlcnM9e307YT0wO2ZvcihjPWIubGVuZ3RoO2E8YzthKyspe3ZhciBkPWJbYV07aWYoKGQubmFtZXx8ZC5uYW1lcykmJmQucnVsZXMpaWYoZC5uYW1lcylmb3IodmFyIGw9MDtsPGQubmFtZXMubGVuZ3RoO2wrKyl0aGlzLl9hZGRGaWVsZChkLGQubmFtZXNbbF0pO2Vsc2UgdGhpcy5fYWRkRmllbGQoZCxkLm5hbWUpfXZhciBnPXRoaXMuZm9ybS5vbnN1Ym1pdDt0aGlzLmZvcm0ub25zdWJtaXQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gYS5fdmFsaWRhdGVGb3JtKGIpJiYoZz09PW18fGcoKSl9Y2F0Y2goYyl7fX19KHRoaXMpfSxuPWZ1bmN0aW9uKGEsYil7dmFyIGM7aWYoMDxhLmxlbmd0aCYmKCJyYWRpbyI9PT1hWzBdLnR5cGV8fCJjaGVja2JveCI9PT1hWzBdLnR5cGUpKWZvcihjPTA7YzxhLmxlbmd0aDtjKyspe2lmKGFbY10uY2hlY2tlZClyZXR1cm4gYVtjXVtiXX1lbHNlIHJldHVybiBhW2JdfTtlLnByb3RvdHlwZS5zZXRNZXNzYWdlPWZ1bmN0aW9uKGEsYil7dGhpcy5tZXNzYWdlc1thXT1iO3JldHVybiB0aGlzfTtlLnByb3RvdHlwZS5yZWdpc3RlckNhbGxiYWNrPWZ1bmN0aW9uKGEsYil7YSYmKCJzdHJpbmciPT09dHlwZW9mIGEmJmImJiJmdW5jdGlvbiI9PT10eXBlb2YgYikmJih0aGlzLmhhbmRsZXJzW2FdPWIpO3JldHVybiB0aGlzfTtlLnByb3RvdHlwZS5fZm9ybUJ5TmFtZU9yTm9kZT1mdW5jdGlvbihhKXtyZXR1cm4ib2JqZWN0Ij09PXR5cGVvZiBhP2E6ci5mb3Jtc1thXX07ZS5wcm90b3R5cGUuX2FkZEZpZWxkPWZ1bmN0aW9uKGEsYil7dGhpcy5maWVsZHNbYl09e25hbWU6YixkaXNwbGF5OmEuZGlzcGxheXx8YixydWxlczphLnJ1bGVzLGlkOm51bGwsdHlwZTpudWxsLHZhbHVlOm51bGwsY2hlY2tlZDpudWxsfX07ZS5wcm90b3R5cGUuX3ZhbGlkYXRlRm9ybT1mdW5jdGlvbihhKXt0aGlzLmVycm9ycz1bXTtmb3IodmFyIGIgaW4gdGhpcy5maWVsZHMpaWYodGhpcy5maWVsZHMuaGFzT3duUHJvcGVydHkoYikpe3ZhciBjPXRoaXMuZmllbGRzW2JdfHx7fSxkPXRoaXMuZm9ybVtjLm5hbWVdO2QmJmQhPT1tJiYoYy5pZD1uKGQsImlkIiksYy50eXBlPTA8ZC5sZW5ndGg/ZFswXS50eXBlOmQudHlwZSxjLnZhbHVlPW4oZCwidmFsdWUiKSxjLmNoZWNrZWQ9bihkLCJjaGVja2VkIiksdGhpcy5fdmFsaWRhdGVGaWVsZChjKSl9ImZ1bmN0aW9uIj09PXR5cGVvZiB0aGlzLmNhbGxiYWNrJiZ0aGlzLmNhbGxiYWNrKHRoaXMuZXJyb3JzLGEpOzA8dGhpcy5lcnJvcnMubGVuZ3RoJiYoYSYmYS5wcmV2ZW50RGVmYXVsdD9hLnByZXZlbnREZWZhdWx0KCk6ZXZlbnQmJihldmVudC5yZXR1cm5WYWx1ZT0hMSkpO3JldHVybiEwfTtlLnByb3RvdHlwZS5fdmFsaWRhdGVGaWVsZD1mdW5jdGlvbihhKXtmb3IodmFyIGI9YS5ydWxlcy5zcGxpdCgifCIpLGM9YS5ydWxlcy5pbmRleE9mKCJyZXF1aXJlZCIpLGQ9IWEudmFsdWV8fCIiPT09YS52YWx1ZXx8YS52YWx1ZT09PW0sbD0wLGc9Yi5sZW5ndGg7bDxnO2wrKyl7dmFyIGY9YltsXSxlPW51bGwsaD0hMSxrPXUuZXhlYyhmKTtpZigtMSE9PWN8fC0xIT09Zi5pbmRleE9mKCIhY2FsbGJhY2tfIil8fCFkKWlmKGsmJihmPWtbMV0sZT1rWzJdKSwiISI9PT1mLmNoYXJBdCgwKSYmKGY9Zi5zdWJzdHJpbmcoMSxmLmxlbmd0aCkpLCJmdW5jdGlvbiI9PT10eXBlb2YgdGhpcy5faG9va3NbZl0/dGhpcy5faG9va3NbZl0uYXBwbHkodGhpcyxbYSxlXSl8fChoPSEwKToiY2FsbGJhY2tfIj09PWYuc3Vic3RyaW5nKDAsOSkmJihmPWYuc3Vic3RyaW5nKDksZi5sZW5ndGgpLCJmdW5jdGlvbiI9PT10eXBlb2YgdGhpcy5oYW5kbGVyc1tmXSYmITE9PT10aGlzLmhhbmRsZXJzW2ZdLmFwcGx5KHRoaXMsW2EudmFsdWUsZV0pJiYoaD0hMCkpLGgpe2I9dGhpcy5tZXNzYWdlc1tmXXx8c1tmXTtjPSJBbiBlcnJvciBoYXMgb2NjdXJyZWQgd2l0aCB0aGUgIithLmRpc3BsYXkrIiBmaWVsZC4iO2ImJihjPWIucmVwbGFjZSgiJXMiLGEuZGlzcGxheSksZSYmKGM9Yy5yZXBsYWNlKCIlcyIsdGhpcy5maWVsZHNbZV0/dGhpcy5maWVsZHNbZV0uZGlzcGxheTplKSkpO3RoaXMuZXJyb3JzLnB1c2goe2lkOmEuaWQsbmFtZTphLm5hbWUsbWVzc2FnZTpjLHJ1bGU6Zn0pO2JyZWFrfX19O2UucHJvdG90eXBlLl9ob29rcz17cmVxdWlyZWQ6ZnVuY3Rpb24oYSl7dmFyIGI9YS52YWx1ZTtyZXR1cm4iY2hlY2tib3giPT09YS50eXBlfHwicmFkaW8iPT09YS50eXBlPyEwPT09YS5jaGVja2VkOm51bGwhPT1iJiYiIiE9PWJ9LCJkZWZhdWx0IjpmdW5jdGlvbihhLGIpe3JldHVybiBhLnZhbHVlIT09Yn0sbWF0Y2hlczpmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMuZm9ybVtiXTtyZXR1cm4gYz9hLnZhbHVlPT09Yy52YWx1ZTohMX0sdmFsaWRfZW1haWw6ZnVuY3Rpb24oYSl7cmV0dXJuIHAudGVzdChhLnZhbHVlKX0sdmFsaWRfZW1haWxzOmZ1bmN0aW9uKGEpe2E9YS52YWx1ZS5zcGxpdCgiLCIpO2Zvcih2YXIgYj0wO2I8YS5sZW5ndGg7YisrKWlmKCFwLnRlc3QoYVtiXSkpcmV0dXJuITE7cmV0dXJuITB9LG1pbl9sZW5ndGg6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gaC50ZXN0KGIpP2EudmFsdWUubGVuZ3RoPj1wYXJzZUludChiLDEwKTohMX0sbWF4X2xlbmd0aDpmdW5jdGlvbihhLGIpe3JldHVybiBoLnRlc3QoYik/YS52YWx1ZS5sZW5ndGg8PXBhcnNlSW50KGIsMTApOiExfSxleGFjdF9sZW5ndGg6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gaC50ZXN0KGIpP2EudmFsdWUubGVuZ3RoPT09cGFyc2VJbnQoYiwxMCk6ITF9LGdyZWF0ZXJfdGhhbjpmdW5jdGlvbihhLGIpe3JldHVybiBrLnRlc3QoYS52YWx1ZSk/cGFyc2VGbG9hdChhLnZhbHVlKT5wYXJzZUZsb2F0KGIpOiExfSxsZXNzX3RoYW46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gay50ZXN0KGEudmFsdWUpP3BhcnNlRmxvYXQoYS52YWx1ZSk8cGFyc2VGbG9hdChiKTohMX0sYWxwaGE6ZnVuY3Rpb24oYSl7cmV0dXJuIHcudGVzdChhLnZhbHVlKX0sYWxwaGFfbnVtZXJpYzpmdW5jdGlvbihhKXtyZXR1cm4geC50ZXN0KGEudmFsdWUpfSxhbHBoYV9kYXNoOmZ1bmN0aW9uKGEpe3JldHVybiB5LnRlc3QoYS52YWx1ZSl9LG51bWVyaWM6ZnVuY3Rpb24oYSl7cmV0dXJuIGgudGVzdChhLnZhbHVlKX0saW50ZWdlcjpmdW5jdGlvbihhKXtyZXR1cm4gdi50ZXN0KGEudmFsdWUpfSxkZWNpbWFsOmZ1bmN0aW9uKGEpe3JldHVybiBrLnRlc3QoYS52YWx1ZSl9LGlzX25hdHVyYWw6ZnVuY3Rpb24oYSl7cmV0dXJuIHoudGVzdChhLnZhbHVlKX0saXNfbmF0dXJhbF9ub196ZXJvOmZ1bmN0aW9uKGEpe3JldHVybiBBLnRlc3QoYS52YWx1ZSl9LHZhbGlkX2lwOmZ1bmN0aW9uKGEpe3JldHVybiBCLnRlc3QoYS52YWx1ZSl9LHZhbGlkX2Jhc2U2NDpmdW5jdGlvbihhKXtyZXR1cm4gQy50ZXN0KGEudmFsdWUpfSx2YWxpZF91cmw6ZnVuY3Rpb24oYSl7cmV0dXJuIEUudGVzdChhLnZhbHVlKX0sdmFsaWRfY3JlZGl0X2NhcmQ6ZnVuY3Rpb24oYSl7aWYoIUQudGVzdChhLnZhbHVlKSlyZXR1cm4hMTt2YXIgYj0wLGM9MCxkPSExO2E9YS52YWx1ZS5yZXBsYWNlKC9cRC9nLCIiKTtmb3IodmFyIGU9YS5sZW5ndGgtMTswPD1lO2UtLSljPWEuY2hhckF0KGUpLGM9cGFyc2VJbnQoYywxMCksZCYmOTwoYyo9MikmJihjLT05KSxiKz1jLGQ9IWQ7cmV0dXJuIDA9PT1iJTEwfSxpc19maWxlX3R5cGU6ZnVuY3Rpb24oYSxiKXtpZigiZmlsZSIhPT1hLnR5cGUpcmV0dXJuITA7dmFyIGM9YS52YWx1ZS5zdWJzdHIoYS52YWx1ZS5sYXN0SW5kZXhPZigiLiIpKzEpLGQ9Yi5zcGxpdCgiLCIpLGU9ITEsZz0wLGY9ZC5sZW5ndGg7Zm9yKGc7ZzxmO2crKyljPT1kW2ddJiYoZT0hMCk7cmV0dXJuIGV9fTtxLkZvcm1WYWxpZGF0b3I9ZX0pKHdpbmRvdyxkb2N1bWVudCk7ClBLBwhmjB/EMxgAADMYAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAB2aWV3L1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAB2aWV3XGFkbWluL1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABcAAAB2aWV3XGFkbWluXGFkbWluLmxheW91dDwhRE9DVFlQRSBodG1sPg0KPGh0bWw+DQo8aGVhZD4NCiAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCIvPg0KICAgIDx0aXRsZT57ey5UaXRsZX19IC0gRnhoLkdvPC90aXRsZT4NCiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9zdGF0aWMvY3NzL2FkbWluLmNzcyIvPg0KICAgIDxzY3JpcHQgc3JjPSJodHRwOi8vbGlicy5iYWlkdS5jb20vanF1ZXJ5LzEuOC4zL2pxdWVyeS5taW4uanMiPjwvc2NyaXB0Pg0KICAgIDxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9qcXVlcnkuZm9ybS5taW4uanMiPjwvc2NyaXB0Pg0KICAgIDxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi92YWxpZGF0ZS5taW4uanMiPjwvc2NyaXB0Pg0KPC9oZWFkPg0KPGJvZHk+DQo8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJjbGVhciI+DQogICAgPGRpdiBjbGFzcz0iY29udGFpbmVyIGNsZWFyIj4NCiAgICAgICAgPGgzIGNsYXNzPSJsb2dvIGxlZnQiPkZ4aC5HbyAtIDxzcGFuPnt7LlRpdGxlfX08L3NwYW4+PC9oMz4NCiAgICAgICAgPGRpdiBjbGFzcz0ibmF2IGxlZnQgcmVsYXRpdmUiPg0KICAgICAgICAgICAgPGEgY2xhc3M9ImRhc2hib2FyZCBsZWZ0IiBocmVmPSIvYWRtaW4vIj7mjqfliLblj7A8L2E+DQogICAgICAgICAgICA8YSBjbGFzcz0iYXJ0aWNsZSBsZWZ0IiBocmVmPSIvYWRtaW4vYXJ0aWNsZXMvIiB0aXRsZT0i5paH56ugIj7mlofnq6A8L2E+PC9hPg0KICAgICAgICAgICAgPGEgY2xhc3M9InBhZ2VzIGxlZnQiIGhyZWY9Ii9hZG1pbi9wYWdlcy8iIHRpdGxlPSLni6znq4vpobXpnaIiPumhtemdojwvYT4NCiAgICAgICAgICAgIDxhIGNsYXNzPSJjb21tZW50cyBsZWZ0IiBocmVmPSIvYWRtaW4vY29tbWVudHMvIiB0aXRsZT0i6K+E6K66Ij7or4Torro8L2E+DQogICAgICAgICAgICA8YSBjbGFzcz0iZmlsZXMgbGVmdCIgaHJlZj0iL2FkbWluL2ZpbGVzLyIgdGl0bGU9IuWqkuS9k+aWh+S7tiI+5paH5Lu2PC9hPg0KICAgICAgICAgICAgPGEgY2xhc3M9InBsdWdpbnMgbGVmdCIgaHJlZj0iL2FkbWluL3BsdWdpbnMvIiB0aXRsZT0i5o+S5Lu2Ij7mj5Lku7Y8L2E+DQogICAgICAgICAgICA8YSBjbGFzcz0ic2V0dGluZyBsZWZ0IiBocmVmPSIvYWRtaW4vc2V0dGluZy8iIHRpdGxlPSLorr7nva4iPuiuvue9rjwvYT4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxhIGNsYXNzPSJvdXQgbmF2LWl0ZW0gcmlnaHQiIGhyZWY9Ii9sb2dvdXQvIiB0aXRsZT0i6YCA5Ye6Ij7pgIDlh7o8L2E+DQogICAgICAgIDxhIGNsYXNzPSJwcm9maWxlIG5hdi1pdGVtIHJpZ2h0IiBocmVmPSIvYWRtaW4vcHJvZmlsZS8iIHRpdGxlPSLmiJEiPuaIkTwvYT4NCiAgICAgICAgPGEgY2xhc3M9ImZyb250IG5hdi1pdGVtIHJpZ2h0IiBocmVmPSIvIiB0YXJnZXQ9Il9ibGFuayIgdGl0bGU9Iuafpeeci+e9keermSI+5YmN5Y+wPC9hPg0KICAgIDwvZGl2Pg0KPC9kaXY+DQp7QENvbnRlbnR9DQo8ZGl2IGlkPSJmb290ZXIiIGNsYXNzPSJjbGVhciI+DQogICAgPGRpdiBjbGFzcz0iY29udGFpbmVyIGNsZWFyIj4NCiAgICAgICA8cCBjbGFzcz0ibGlua3MgdGV4dC1jZW50ZXIiPg0KICAgICAgICAgICA8YSBjbGFzcz0idGhlbWUiIGhyZWY9Ii9jbWQvdGhlbWUvIj7kuLvpopg8L2E+DQogICAgICAgICAgIDxhIGNsYXNzPSJyZWFkZXIiIGhyZWY9Ii9jbWQvcmVhZGVyLyI+6K+76ICFPC9hPg0KICAgICAgICAgICA8YSBjbGFzcz0ic3RhdCIgaHJlZj0iL2NtZC9tZXNzYWdlLyI+5raI5oGvPC9hPg0KICAgICAgICAgICA8YSBjbGFzcz0iYmFja3VwIiBocmVmPSIvY21kL2JhY2t1cC8iPuWkh+S7vTwvYT4NCiAgICAgICAgICAgPGEgY2xhc3M9ImVyciIgaHJlZj0iL2NtZC9sb2dzLyI+5pel5b+XPC9hPg0KICAgICAgICAgICA8YSBjbGFzcz0ic3lzIiBocmVmPSIvY21kL21vbml0b3IvIj7ns7vnu588L2E+DQogICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iY3AgdGV4dC1jZW50ZXIiPlByb3VkbHkgUG93ZXJlZCBieSBGeGguR288L3A+DQogICAgPC9kaXY+DQo8L2Rpdj4NCjwvYm9keT4NCjwvaHRtbD5QSwcI/cPW1fMHAADzBwAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAdmlld1xhZG1pblxhcnRpY2xlcy5odG1sPHVsIGlkPSJhcnRpY2xlLWxpc3QiIGNsYXNzPSJjb250YWluZXI5NjAgYWRtaW4iPg0KICAgIDxsaT4NCiAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtYmx1ZSIgaHJlZj0iL2FkbWluL2FydGljbGUvd3JpdGUvIj7mt7vliqDmlofnq6A8L2E+DQogICAgPC9saT57e3JhbmdlIC5BcnRpY2xlc319DQogICAgPGxpPg0KICAgICAgICA8c3BhbiBjbGFzcz0idGltZSI+e3tEYXRlSW50NjQgLkNyZWF0ZVRpbWUgIk1NLkREIn19PC9zcGFuPjxoNCBjbGFzcz0iaW5saW5lLWJsb2NrIHRpdGxlIj48YSBocmVmPSJ7ey5MaW5rfX0iIHRhcmdldD0iX2JsYW5rIj57ey5UaXRsZX19PC9hPjwvaDQ+e3tpZiBuZSAuU3RhdHVzICJwdWJsaXNoIn19DQogICAgICAgIDxzcGFuIGNsYXNzPSJsYmwgc3RhdHVzIj7ojYnnqL88L3NwYW4+e3tlbmR9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0ic2x1ZyI+e3suU2x1Z319PC9zcGFuPnt7aWYgZXEgLklzQ29tbWVudCBmYWxzZX19DQogICAgICAgIDxzcGFuIGNsYXNzPSJpcy1jb21tZW50Ij7lhbPor4Q8L3NwYW4+e3tlbmR9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0iY291bnQiPnt7LkNvbW1lbnROdW19fSAvIHt7LkhpdHN9fTwvc3Bhbj4NCiAgICAgICAgPGEgY2xhc3M9ImVkaXQgbGJsIGxibC1ncmVlbiIgaHJlZj0iL2FkbWluL2FydGljbGUve3suSWR9fS8iIHJlbD0ie3suSWR9fSI+57yW6L6RPC9hPg0KICAgICAgICA8YSBjbGFzcz0iZGVsIGxibCBsYmwtcmVkIiBocmVmPSIvYWRtaW4vYXJ0aWNsZS97ey5JZH19LyIgcmVsPSJ7ey5JZH19Ij7liKDpmaQ8L2E+DQogICAgPC9saT57e2VuZH19DQo8L3VsPg0KPHVsIGlkPSJhcnRpY2xlLXBhZ2VyIiBjbGFzcz0icGFnZXIgY29udGFpbmVyOTYwIj57e3JhbmdlIC5QYWdlci5QYWdlU2xpY2V9fQ0KICAgIDxsaSBjbGFzcz0iaXRlbXt7aWYgZXEgJC5QYWdlci5DdXJyZW50IC59fSBjdXJyZW50e3tlbmR9fSI+PGEgaHJlZj0iL2FkbWluL2FydGljbGVzLz9wYWdlPXt7Ln19Ij57ey59fTwvYT48L2xpPnt7ZW5kfX0NCjwvdWw+DQo8c2NyaXB0Pg0KICAgICQoIi5kZWwiKS5vbigiY2xpY2siLGZ1bmN0aW9uKGUpew0KICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7DQogICAgICAgIGlmKGNvbmZpcm0oIuWIoOmZpOaWh+eroOWwhuS9v+ebuOWFs+WGheWuueWkseaViO+8geehruiupO+8nyIpKXsNCiAgICAgICAgICAgIHZhciBpZCA9ICQodGhpcykuYXR0cigicmVsIik7DQogICAgICAgICAgICAkLmFqYXgoew0KICAgICAgICAgICAgICAgICJ1cmwiOiIvYWRtaW4vYXJ0aWNsZS8iK2lkKyIvIiwNCiAgICAgICAgICAgICAgICAidHlwZSI6ImRlbGV0ZSIsDQogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKGpzb24pew0KICAgICAgICAgICAgICAgICAgICBpZihqc29uLnJlcyl7DQogICAgICAgICAgICAgICAgICAgICAgICBhbGVydCgi5bey5Yig6ZmkIik7DQogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgICAgICAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoanNvbi5tc2cpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSkNCiAgICAgICAgfQ0KICAgIH0pOw0KPC9zY3JpcHQ+UEsHCPHSkWl7BgAAewYAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAADwAAAHZpZXdcYWRtaW5cY21kL1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABoAAAB2aWV3XGFkbWluXGNtZFxiYWNrdXAuaHRtbDxoZWFkZXIgY2xhc3M9ImNtZC1oZWFkZXIgY2xlYXIiPg0KICAgIDxoMSBjbGFzcz0iY21kLXRpdGxlIGxlZnQiPuWkh+S7veaVsOaNrjwvaDE+DQogICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1ibHVlIGxlZnQiIGlkPSJiYWNrdXAtYnRuIj7lpIfku708L2J1dHRvbj4NCjwvaGVhZGVyPg0KPHVsIGNsYXNzPSJjbWQtbGlzdCIgaWQ9ImJhY2t1cC1saXN0Ij57e3JhbmdlIC5GaWxlc319DQogICAgPGxpPg0KICAgICAgICA8c3BhbiBjbGFzcz0idGltZSI+e3tEYXRlVGltZSAuTW9kVGltZSAiTU0uREQgSEg6bW0ifX08L3NwYW4+DQogICAgICAgIDxzcGFuIGNsYXNzPSJuYW1lIj57ey5OYW1lfX0gPGEgY2xhc3M9ImxpbmsiIGhyZWY9Ii9jbWQvYmFja3VwL2ZpbGU/ZmlsZT17ey5OYW1lfX0iPuS4i+i9vTwvYT48L3NwYW4+DQogICAgICAgIDxzcGFuIGNsYXNzPSJzaXplIj57e0ZpbGVTaXplIC5TaXplfX08L3NwYW4+DQogICAgICAgIDxhIGNsYXNzPSJkZWwiIGhyZWY9IiMiIHJlbD0ie3suTmFtZX19Ij7liKDpmaQ8L2E+DQogICAgPC9saT57e2VuZH19DQo8L3VsPg0KPHNjcmlwdD4NCiAgICAkKGZ1bmN0aW9uICgpIHsNCiAgICAgICAgJCgnI2JhY2t1cC1idG4nKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICAkLmFqYXgoew0KICAgICAgICAgICAgICAgIHR5cGU6ICJwb3N0IiwNCiAgICAgICAgICAgICAgICBiZWZvcmVTZW5kOiBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICAgICAgICAgICQoJy5jbWQtbGlzdCcpLnByZXBlbmQoJzxsaSBjbGFzcz0iYmFja3VwLWxvYWRpbmciPuWkh+S7veS4rS4uPC9saT4nKTsNCiAgICAgICAgICAgICAgICAgICAgJCgnI2JhY2t1cC1idG4nKS5oaWRlKCk7DQogICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAoanNvbikgew0KICAgICAgICAgICAgICAgICAgICBpZiAoanNvbi5yZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICQoJy5iYWNrdXAtbG9hZGluZycpLnJlbW92ZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJCgnLmNtZC1saXN0JykucHJlcGVuZCgnPGxpIGNsYXNzPSJiYWNrdXAtcmVzdWx0Ij7liJrliJrlpIfku73liLAgJyArIGpzb24uZmlsZSArICc8L2xpPicpOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoanNvbi5tc2cpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICQoJyNiYWNrdXAtYnRuJykuc2hvdygpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICB9KTsNCiAgICAgICAgJCgnLmRlbCcpLm9uKCJj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cz0iY21kLWxpc3QiIGlkPSJyZWFkZXItbGlzdCI+DQogICAgPGxpPg0KICAgICAgICDlpoLmnpzliKDpmaTor7vogIXvvIzkuI3kvJrlvbHlk43or7vogIXlt7LmnInnmoTor4TorrrvvJvkvYbmraTlkI7or6Xor7vogIXnmoTmlrDor4TorrrpnIDopoHlrqHmoLjjgIINCiAgICA8L2xpPnt7cmFuZ2UgLlJlYWRlcnN9fQ0KICAgIDxsaT4NCiAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtYmx1ZSBhdXRob3IiIGhyZWY9Int7LlVybH19IiB0YXJnZXQ9Il9ibGFuayI+e3suQXV0aG9yfX08L2E+DQogICAgICAgIDxzcGFuIGNsYXNzPSJlbWFpbCI+e3suRW1haWx9fTwvc3Bhbj4NCiAgICAgICAgPHNwYW4gY2xhc3M9ImxibCBsYmwtcmVkIGNvbW1lbnRzIj57ey5Db21tZW50c319PC9zcGFuPg0KICAgICAgICA8YSBjbGFzcz0iZGVsIiBocmVmPSIjIj7liKDpmaQ8L2E+DQogICAgPC9saT57e2VuZH19DQo8L3VsPg0KPHNjcmlwdD4NCiAgICAkKGZ1bmN0aW9uKCl7DQogICAgICAgICQoJy5kZWwnKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpOw0KICAgICAgICAgICAgdmFyIGVtYWlsID0gJHRoaXMucGFyZW50KCkuZmluZCgnLmVtYWlsJykudGV4dCgpOw0KICAgICAgICAgICAgY29uc29sZS5sb2coZW1haWwpOw0KICAgICAgICAgICAgJC5wb3N0KCIvY21kL3JlYWRlci8iLCB7ImVtYWlsIjogZW1haWx9LCBmdW5jdGlvbiAoanNvbikgew0KICAgICAgICAgICAgICAgIGlmIChqc29uLnJlcykgew0KICAgICAgICAgICAgICAgICAgICAkdGhpcy5wYXJlbnQoKS5yZW1vdmUoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSk7DQogICAgfSk7DQo8L3NjcmlwdD5QSwcIC5ZKcvEDAADxAwAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAdmlld1xhZG1pblxjbWRcdGhlbWUuaHRtbDxoZWFkZXIgY2xhc3M9ImNtZC1oZWFkZXIgY2xlYXIiPg0KICAgIDxoMSBjbGFzcz0iY21kLXRpdGxlIGxlZnQiPuS4u+mimOmjjuagvDwvaDE+DQogICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGxlZnQge3tTZXR0aW5nIGB0aGVtZV9jYWNoZWB9fSIgaWQ9InRoZW1lLWNhY2hlLWJ0biI+57yT5a2YKHt7U2V0dGluZyAidGhlbWVfY2FjaGUifX0pPC9idXR0b24+DQo8L2hlYWRlcj4NCjx1bCBjbGFzcz0iY21kLWxpc3QiIGlkPSJ0aGVtZS1saXN0Ij57e3JhbmdlIC5UaGVtZXN9fQ0KICAgIDxsaT57e2lmIGVxIC5OYW1lICQuQ3VycmVudFRoZW1lfX0NCiAgICAgICAgPGg1IGNsYXNzPSJ0aGVtZS1uYW1lIGlubGluZS1ibG9jayBsYmwgbGJsLWJsdWUiPnt7Lk5hbWV9fTwvaDU+e3tlbHNlfX0NCiAgICAgICAgPGg1IGNsYXNzPSJ0aGVtZS1uYW1lIGlubGluZS1ibG9jayI+e3suTmFtZX19PC9oNT57e2VuZH19e3tyYW5nZSAuTGF5b3V0fX0NCiAgICAgICAgPHNwYW4gY2xhc3M9ImxibCBsYmwtZ3JlZW4gbGF5b3V0Ij57ey59fTwvc3Bhbj57e2VuZH19e3tyYW5nZSAuRmlsZXN9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0iZmlsZSI+e3sufX08L3NwYW4+e3tlbmR9fXt7cmFuZ2UgLkVycm9yRmlsZXN9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3ItZmlsZSI+e3sufX08L3NwYW4+e3tlbmR9fQ0KICAgIDwvbGk+e3tlbmR9fQ0KPC91bD4NCjxwPuS4u+mimOWQjeWvueW6lOinhuWbvuS4reeahOebruW9leOAgumrmOS6rueahOS4u+mimOWNs+W9k+WJjeS9v+eUqOeahOS4u+mimOOAguWNleWHu+S4u+mimOWQjeWNs+WPr+WIh+aNoueOsOeUqOS4u+mimOOAgjwvcD4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbiAoKSB7DQogICAgICAgICQoJyN0aGVtZS1jYWNoZS1idG4nKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoZSkgew0KICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKTsNCiAgICAgICAgICAgIHZhciBjaGFuZ2UgPSAidHJ1ZSI7DQogICAgICAgICAgICBpZiAoJHRoaXMuaGFzQ2xhc3MoInRydWUiKSkgew0KICAgICAgICAgICAgICAgIGNoYW5nZSA9ICJmYWxzZSI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkLnBvc3QoIi9jbWQvdGhlbWUvIiwgeyJjYWNoZSI6IGNoYW5nZX0sIGZ1bmN0aW9uIChqc29uKSB7DQogICAgICAgICAgICAgICAgaWYgKGpzb24ucmVzKSB7DQogICAgICAgICAgICAgICAgICAgICR0aGlzLnJlbW92ZUNsYXNzKCJ0cnVlIikucmVtb3ZlQ2xhc3MoImZhbHNlIikuYWRkQ2xhc3MoY2hhbmdlKS50ZXh0KCLnvJPlrZgoIiArIGNoYW5nZSArICIpIik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0pOw0KICAgICAgICAkKCcudGhlbWUtbmFtZScpLm9uKCJjbGljayIsZnVuY3Rpb24oZSl7DQogICAgICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpOw0KICAgICAgICAgICAgaWYoJHRoaXMuaGFzQ2xhc3MoImxibCIpKXsNCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkLnBvc3QoIi9jbWQvdGhlbWUvIix7InRoZW1lIjokdGhpcy50ZXh0KCl9LGZ1bmN0aW9uKGpzb24pew0KICAgICAgICAgICAgICAgaWYoanNvbi5yZXMpew0KICAgICAgICAgICAgICAgICAgICQoIi50aGVtZS1uYW1lLmxibCIpLnJlbW92ZUNsYXNzKCJsYmwiKS5yZW1vdmVDbGFzcygibGJsLWJsdWUiKTsNCiAgICAgICAgICAgICAgICAgICAkdGhpcy5hZGRDbGFzcygibGJsIikuYWRkQ2xhc3MoImxibC1ibHVlIik7DQogICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSkNCiAgICB9KTsNCjwvc2NyaXB0PlBLBwiiN+sCTQcAAE0HAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABUAAAB2aWV3XGFkbWluXGNtZC5sYXlvdXQ8IURPQ1RZUEUgaHRtbD4NCjxodG1sPg0KPGhlYWQ+DQogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiLz4NCiAgICA8dGl0bGU+e3suVGl0bGV9fSAtIEZ4aC5HbzwvdGl0bGU+DQogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvc3RhdGljL2Nzcy9jbWQuY3NzIi8+DQogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwOi8vbGlicy5iYWlkdS5jb20vZm9udGF3ZXNvbWUvNC4wLjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+DQogICAgPHNjcmlwdCBzcmM9Imh0dHA6Ly9saWJzLmJhaWR1LmNvbS9qcXVlcnkvMS44LjMvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+DQo8L2hlYWQ+DQo8Ym9keSBjbGFzcz0iY21kIj4NCntAQ29udGVudH0NCjxwIGNsYXNzPSJiYWNrIj48YSBocmVmPSJqYXZhc2NyaXB0Omhpc3RvcnkuYmFjaygpIj5CYWNrPC9hPjwvcD4NCjwvYm9keT4NCjwvaHRtbD5QSwcICn3IAM4BAADOAQAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAdmlld1xhZG1pblxjb21tZW50cy5odG1sPGRpdiBpZD0iY29tbWVudC1saXN0IiBjbGFzcz0iYWRtaW4gY29udGFpbmVyOTYwIj57e3JhbmdlIC5Db21tZW50c319DQogICAgPGRpdiBjbGFzcz0iY29tbWVudCBjbGVhciIgaWQ9ImNvbW1lbnQte3suSWR9fSI+DQogICAgICAgIDxpbWcgY2xhc3M9ImMtYXZhdGFyIGxlZnQiIHNyYz0ie3suQXZhdGFyfX0iIGFsdD0ie3suQXV0aG9yfX0iLz4NCiAgICAgICAgPGRpdiBjbGFzcz0iYy1zZWN0aW9uIGxlZnQiPg0KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1tZXRhIj4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0ibGJsIGxibC1ibHVlIGMtYXV0aG9ye3tpZiAuSXNBZG1pbn19IGFkbWlue3tlbmR9fSIgaHJlZj0ie3suVXJsfX0iIHRhcmdldD0iX2JsYW5rIj57ey5BdXRob3J9fXt7aWYgLklzQWRtaW59fSZuYnNwOyZuYnNwOyhhZG1pbil7e2VuZH19PC9hPg0KICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJjLXRpbWUiPnt7RGF0ZUludDY0IC5DcmVhdGVUaW1lICJNTS5ERCBISDptbSJ9fTwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iYy1lbWFpbCI+e3suRW1haWx9fTwvc3Bhbj57e2lmIC5HZXRDb250ZW50fX0NCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iYy1jbnQiPkB7ey5HZXRDb250ZW50LlRpdGxlfX08L3NwYW4+e3tlbHNlfX0NCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iYy1jbnQiPkDml6DmlYg8L3NwYW4+e3tlbmR9fXt7aWYgbmUgLlN0YXR1cyAiYXBwcm92ZWQifX0NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0iYy1jaGVjayIgaHJlZj0iIyIgcmVsPSJ7ey5JZH19IiB0aXRsZT0i5a6h5qC4Ij7lrqHmoLjkuK08L2E+e3tlbmR9fQ0KICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJjLXJlcGx5IiBocmVmPSIjIiByZWw9Int7LklkfX0iIHRpdGxlPSLlm57lpI0iPuWbnuWkjTwvYT4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0iYy1kZWwiIGhyZWY9IiMiIHJlbD0ie3suSWR9fSIgdGl0bGU9IuWIoOmZpCI+5Yig6ZmkPC9hPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8c2VjdGlvbiBjbGFzcz0iYy1jb250ZW50Ij57e0h0bWwgLkNvbnRlbnR9fTwvc2VjdGlvbj57e2lmIC5QYXJlbnRNZH19DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXAtbWQgbWFya2Rvd24iPnt7SHRtbCAuUGFyZW50TWR9fTwvZGl2Pnt7ZW5kfX0NCiAgICAgICAgPC9kaXY+DQogICAgPC9kaXY+e3tlbmR9fQ0KICAgIDx1bCBpZD0iYXJ0aWNsZS1wYWdlciIgY2xhc3M9InBhZ2VyIGNvbnRhaW5lcjk2MCI+e3tyYW5nZSAuUGFnZXIuUGFnZVNsaWNlfX0NCiAgICAgICAgPGxpIGNsYXNzPSJpdGVte3tpZiBlcSAkLlBhZ2VyLkN1cnJlbnQgLn19IGN1cnJlbnR7e2VuZH19Ij48YSBocmVmPSIvYWRtaW4vY29tbWVudHMvP3BhZ2U9e3sufX0iPnt7Ln19PC9hPjwvbGk+e3tlbmR9fQ0KICAgIDwvdWw+DQogICAgPGZvcm0gaWQ9ImNvbW1lbnQtZm9ybSIgYWN0aW9uPSIvYWRtaW4vY29tbWVudHMvIiBjbGFzcz0iZm9ybSBjbGVhciBsZWZ0IiBtZXRob2Q9InBvc3QiPg0KICAgICAgICA8dGV4dGFyZWEgY2xhc3M9ImlwdCBsZWZ0IiBuYW1lPSJjb250ZW50IiBpZD0iY29tbWVudC1jb250ZW50IiByZXF1aXJlZD0icmVxdWlyZWQiPjwvdGV4dGFyZWE+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSIgaWQ9ImNvbW1lbnQtc3VibWl0Ij7lm57lpI3or4Torro8L2J1dHRvbj4NCiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1ncmVlbiIgaWQ9ImNvbW1lbnQtY2xvc2UiPuWFs+mXreWbnuWkjTwvYnV0dG9uPg0KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iMCIgaWQ9ImNvbW1lbnQtcGFyZW50IiBuYW1lPSJwaWQiLz4NCiAgICA8L2Zvcm0+DQo8L2Rpdj4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbiAoKSB7DQogICAgICAgICQoJy5jLWRlbCcpLm9uKCJjbGljayIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIGlmIChjb25maXJtKCLliKDpmaTor4TorrrlsIbkvb/nm7jlhbPlhoXlrrnml6DmlYghIikpIHsNCiAgICAgICAgICAgICAgICB2YXIgaWQgPSAkKHRoaXMpLmF0dHIoInJlbCIpOw0KICAgICAgICAgICAgICAgICQuYWpheCh7DQogICAgICAgICAgICAgICAgICAgIHR5cGU6ICJkZWxldGUiLA0KICAgICAgICAgICAgICAgICAgICB1cmw6ICIvYWRtaW4vY29tbWVudHMvP2lkPSIgKyBpZCwNCiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uLnJlcykgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNjb21tZW50LScgKyBpZCkucmVtb3ZlKCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KCLliKDpmaTlpLHotKUiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0pDQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0pOw0KICAgICAgICAkKCcuYy1jaGVjaycpLm9uKCJjbGljayIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIGlmIChjb25maXJtKCLlrqHmoLjlkI7mraTkvZzogIXlsIbkuI3lho3moIforrDlrqHmoLghIikpIHsNCiAgICAgICAgICAgICAgICB2YXIgaWQgPSAkKHRoaXMpLmF0dHIoInJlbCIpOw0KICAgICAgICAgICAgICAgICQuYWpheCh7DQogICAgICAgICAgICAgICAgICAgIHR5cGU6ICJwdXQiLA0KICAgICAgICAgICAgICAgICAgICB1cmw6ICIvYWRtaW4vY29tbWVudHMvP2lkPSIgKyBpZCwNCiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uLnJlcykgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNjb21tZW50LScgKyBpZCkuZmluZCgiLmMtY2hlY2siKS5yZW1vdmUoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoIuWuoeaguOWksei0pSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSkNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSk7DQogICAgICAgICQoJy5jLXJlcGx5Jykub24oImNsaWNrIixmdW5jdGlvbigpew0KICAgICAgICAgICAgdmFyIGlkID0gJCh0aGlzKS5hdHRyKCJyZWwiKTsNCiAgICAgICAgICAgICQoJyNjb21tZW50LScraWQpLmFwcGVuZCgkKCcjY29tbWVudC1mb3JtJykuZGV0YWNoKCkuc2hvdygpKTsNCiAgICAgICAgICAgICQoJyNjb21tZW50LXBhcmVudCcpLnZhbChpZCk7DQogICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfSk7DQogICAgICAgICQoJyNjb21tZW50LWZvcm0nKS5hamF4Rm9ybShmdW5jdGlvbihqc29uKXsNCiAgICAgICAgICAgIGlmKGpzb24ucmVzKXsNCiAgICAgICAgICAgICAgICBhbGVydCgi5bey5Zue5aSNIik7DQogICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAiL2FkbWluL2NvbW1lbnRzLyI7DQogICAgICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgICAgICBhbGVydCgi5Zue5aSN5aSx6LSlIik7DQogICAgICAgICAgICB9DQogICAgICAgIH0pOw0KICAgICAgICAkKCcjY29tbWVudC1jbG9zZScpLm9uKCJjbGljayIsZnVuY3Rpb24oKXsNCiAgICAgICAgICAgICQoJyNjb21tZW50LWZvcm0nKS5oaWRlKCk7DQogICAgICAgICAgICAkKCcjY29tbWVudC1wYXJlbnQnKS52YWwoMCk7DQogICAgICAgICAgICAkKCcjY29tbWVudC1jb250ZW50JykudmFsKCIiKTsNCiAgICAgICAgfSkNCiAgICB9KTsNCjwvc2NyaXB0PlBLBwhmlClrdg8AAHYPAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABwAAAB2aWV3XGFkbWluXGVkaXRfYXJ0aWNsZS5odG1sPHN0eWxlPg0KICAgIEBpbXBvcnQgIi9zdGF0aWMvY3NzL2NvZGVtaXJyb3IuY3NzIjsNCiAgICBAaW1wb3J0ICIvc3RhdGljL2Nzcy9oaWdobGlnaHQuY3NzIjsNCjwvc3R5bGU+DQo8Zm9ybSBpZD0iYXJ0aWNsZS1mb3JtIiBjbGFzcz0iZm9ybSBjbGVhciBjb250YWluZXIiIGFjdGlvbj0iIyIgbWV0aG9kPSJwb3N0Ij4NCiAgICA8ZGl2IGNsYXNzPSJsZWZ0IGdyaWQtMS0yIj4NCiAgICAgICAgPGlucHV0IGNsYXNzPSJpcHQgdGl0bGUiIGlkPSJ0aXRsZSIgdHlwZT0idGV4dCIgcmVxdWlyZWQ9InJlcXVpcmVkIiBuYW1lPSJ0aXRsZSIgcGxhY2Vob2xkZXI9IuaWh+eroOagh+mimCIgdmFsdWU9Int7LkFydGljbGUuVGl0bGV9fSIvPg0KICAgICAgICA8dGV4dGFyZWEgbmFtZT0iY29udGVudCIgaWQ9ImNvbnRlbnQiIGNsYXNzPSJpcHQiPnt7SHRtbCAuQXJ0aWNsZS5UZXh0fX08L3RleHRhcmVhPg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImxlZnQgZ3JpZC0xLTIiPg0KICAgICAgICA8ZGl2IGNsYXNzPSJwcmV2aWV3IG1hcmtkb3duIj48L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGNsYXNzPSJmb3JtLXZlcnRpY2FsIGxlZnQiPg0KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWdyZWVuIGxlZnQiIHR5cGU9ImJ1dHRvbiIgaWQ9ImF0dGFjaC1zaG93Ij7mt7vliqDpmYTku7Y8L2J1dHRvbj4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4gZm9yPSJzbHVnIj7lm7rlrprpk77mjqU8L3NwYW4+Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8aW5wdXQgaWQ9InNsdWciIGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InNsdWciIHJlcXVpcmVkPSJyZXF1aXJlZCIgcGxhY2Vob2xkZXI9IuaWh+eroOeahOWUr+S4gOmTvuaOpSIgdmFsdWU9Int7LkFydGljbGUuU2x1Z319Ii8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4+5qCH562+PC9zcGFuPiZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPGlucHV0IGlkPSJ0YWciIGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InRhZyIgcGxhY2Vob2xkZXI9IuaWh+eroOeahOagh+etviIgdmFsdWU9Int7LkFydGljbGUuVGFnU3RyaW5nfX0iLz4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8c3Bhbj7kv53lrZjnirbmgIE8L3NwYW4+Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8c2VsZWN0IG5hbWU9InN0YXR1cyIgaWQ9InN0YXR1cyI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icHVibGlzaCJ7e2lmIGVxIC5BcnRpY2xlLlN0YXR1cyAicHVibGlzaCJ9fSBzZWxlY3RlZHt7ZW5kfX0+5YWs5byAPC9vcHRpb24+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iZHJhZnQie3tpZiBlcSAuQXJ0aWNsZS5TdGF0dXMgImRyYWZ0In19IHNlbGVjdGVke3tlbmR9fT7ojYnnqL88L29wdGlvbj4NCiAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxzcGFuPuWFgeiuuOivhOiuujwvc3Bhbj4mbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT0iY29tbWVudCIgaWQ9ImlzLWNvbW1lbnQiPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEie3tpZiBlcSAuQXJ0aWNsZS5Jc0NvbW1lbnQgdHJ1ZX19IHNlbGVjdGVke3tlbmR9fT7lhYHorrg8L29wdGlvbj4NCiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIwInt7aWYgZXEgLkFydGljbGUuSXNDb21tZW50IGZhbHNlfX0gc2VsZWN0ZWR7e2VuZH19PuWFs+mXrTwvb3B0aW9uPg0KICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgIDwvcD4NCiAgICA8L2Rpdj4NCiAgICA8cCBjbGFzcz0ic3VibWl0IHRleHQtcmlnaHQiIGlkPSJhcnRpY2xlLXN1Ym1pdCI+DQogICAgICAgIDxzcGFuIGNsYXNzPSJpbnZhbGlkIGxibCBsYmwtcmVkIGhpZGUiIGlkPSJzbHVnLWludmFsaWQiPuWbuuWumumTvuaOpeeUseWtl+avje+8jOaVsOWtl+WSjC3nu4TmiJA8L3NwYW4+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5L+d5a2Y5paH56ugPC9idXR0b24+DQogICAgPC9wPg0KPC9mb3JtPg0KPGZvcm0gY2xhc3M9ImZvcm0gaGlkZSIgaWQ9ImF0dGFjaC1mb3JtIiBhY3Rpb249Ii9hZG1pbi9maWxlcy91cGxvYWQvIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBtZXRob2Q9InBvc3QiPg0KICAgIDxpbnB1dCBpZD0iYXR0YWNoLXVwbG9hZCIgdHlwZT0iZmlsZSIgbmFtZT0iZmlsZSIvPg0KPC9mb3JtPg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2NvZGVtaXJyb3IubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9jb2RlbWlycm9yLW1vZGUubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9tYXJrZWQubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9oaWdobGlnaHQubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2pzL3VwbG9hZC5qcyI+PC9zY3JpcHQ+DQo8c2NyaXB0Pg0KICAgICQoZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgZWRpdG9yID0gQ29kZU1pcnJvci5mcm9tVGV4dEFyZWEoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKSwgew0KICAgICAgICAgICAgbW9kZTogJ21hcmtkb3duJywNCiAgICAgICAgICAgIGxpbmVOdW1iZXJzOiB0cnVlLA0KICAgICAgICAgICAgdGhlbWU6ICJkZWZhdWx0IiwNCiAgICAgICAgICAgIGV4dHJhS2V5czogeyJFbnRlciI6ICJuZXdsaW5lQW5kSW5kZW50Q29udGludWVNYXJrZG93bkxpc3QifQ0KICAgICAgICB9KTsNCiAgICAgICAgZWRpdG9yLm9uKCJjaGFuZ2UiLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB2YXIgc3RyID0gZWRpdG9yLmdldFZhbHVlKCk7DQogICAgICAgICAgICAkKCcucHJldmlldycpLmh0bWwobWFya2VkKHN0cikpLmZpbmQoInByZSBjb2RlIikuZWFjaChmdW5jdGlvbiAoaSwgZSkgew0KICAgICAgICAgICAgICAgIGhsanMuaGlnaGxpZ2h0QmxvY2soZSk7DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIG5ldyBGb3JtVmFsaWRhdG9yKCJhcnRpY2xlLWZvcm0iLCBbDQogICAgICAgICAgICB7Im5hbWUiOiAic2x1ZyIsICJydWxlcyI6ICJhbHBoYV9kYXNoIn0NCiAgICAgICAgXSwgZnVuY3Rpb24gKGVycm9ycywgZSkgew0KICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOw0KICAgICAgICAgICAgJCgnLmludmFsaWQnKS5oaWRlKCk7DQogICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCkgew0KICAgICAgICAgICAgICAgICQoIiMiICsgZXJyb3JzWzBdLmlkICsgIi1pbnZhbGlkIikucmVtb3ZlQ2xhc3MoImhpZGUiKS5zaG93KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJCgnI2FydGljbGUtZm9ybScpLmFqYXhTdWJtaXQoZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgICAgICBpZiAoanNvbi5yZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmZpcm0oIuW3suS/neWtmO+8jOWOu+afpeeci++8n+i/mOaYr+e7p+e7ree8lui+kSIpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9ICIvYWRtaW4vYXJ0aWNsZXMvIjsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGFsZXJ0KGpzb24ubXNnKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIGluaXRVcGxvYWQoIiNhcnRpY2xlLXN1Ym1pdCIpOw0KICAgIH0pOw0KPC9zY3JpcHQ+UEsHCNzKa1hpDwAAaQ8AAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAGQAAAHZpZXdcYWRtaW5cZWRpdF9wYWdlLmh0bWw8c3R5bGU+DQogICAgQGltcG9ydCAiL3N0YXRpYy9jc3MvY29kZW1pcnJvci5jc3MiOw0KICAgIEBpbXBvcnQgIi9zdGF0aWMvY3NzL2hpZ2hsaWdodC5jc3MiOw0KPC9zdHlsZT4NCjxmb3JtIGlkPSJhcnRpY2xlLWZvcm0iIGNsYXNzPSJmb3JtIGNsZWFyIGNvbnRhaW5lciIgYWN0aW9uPSIjIiBtZXRob2Q9InBvc3QiPg0KICAgIDxkaXYgY2xhc3M9ImxlZnQgZ3JpZC0xLTIiPg0KICAgICAgICA8aW5wdXQgY2xhc3M9ImlwdCB0aXRsZSIgaWQ9InRpdGxlIiB0eXBlPSJ0ZXh0IiByZXF1aXJlZD0icmVxdWlyZWQiIG5hbWU9InRpdGxlIiBwbGFjZWhvbGRlcj0i6aG16Z2i5qCH6aKYIiB2YWx1ZT0ie3suUGFnZS5UaXRsZX19Ii8+DQogICAgICAgIDx0ZXh0YXJlYSBuYW1lPSJjb250ZW50IiBpZD0iY29udGVudCIgY2xhc3M9ImlwdCI+e3tIdG1sIC5QYWdlLlRleHR9fTwvdGV4dGFyZWE+DQogICAgPC9kaXY+DQogICAgPGRpdiBjbGFzcz0ibGVmdCBncmlkLTEtMiI+DQogICAgICAgIDxkaXYgY2xhc3M9InByZXZpZXcgbWFya2Rvd24iPjwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImZvcm0tdmVydGljYWwgbGVmdCI+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZ3JlZW4gbGVmdCIgdHlwZT0iYnV0dG9uIiBpZD0iYXR0YWNoLXNob3ciPua3u+WKoOmZhOS7tjwvYnV0dG9uPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8c3BhbiBmb3I9InNsdWciPuWbuuWumumTvuaOpTwvc3Bhbj4mbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxpbnB1dCBpZD0ic2x1ZyIgY2xhc3M9ImlwdCIgdHlwZT0idGV4dCIgbmFtZT0ic2x1ZyIgcmVxdWlyZWQ9InJlcXVpcmVkIiBwbGFjZWhvbGRlcj0i6aG16Z2i55qE5ZSv5LiA6ZO+5o6lIiB2YWx1ZT0ie3suUGFnZS5TbHVnfX0iLz4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8c3Bhbj7kv53lrZjnirbmgIE8L3NwYW4+Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8c2VsZWN0IG5hbWU9InN0YXR1cyIgaWQ9InN0YXR1cyI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icHVibGlzaCJ7e2lmIGVxIC5QYWdlLlN0YXR1cyAicHVibGlzaCJ9fSBzZWxlY3RlZHt7ZW5kfX0+5YWs5byAPC9vcHRpb24+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iZHJhZnQie3tpZiBlcSAuUGFnZS5TdGF0dXMgImRyYWZ0In19IHNlbGVjdGVke3tlbmR9fT7ojYnnqL88L29wdGlvbj4NCiAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxzcGFuPuWFgeiuuOivhOiuujwvc3Bhbj4mbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT0iY29tbWVudCIgaWQ9ImlzLWNvbW1lbnQiPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEie3tpZiBlcSAuUGFnZS5Jc0NvbW1lbnQgdHJ1ZX19IHNlbGVjdGVke3tlbmR9fT7lhYHorrg8L29wdGlvbj4NCiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIwInt7aWYgZXEgLlBhZ2UuSXNDb21tZW50IGZhbHNlfX0gc2VsZWN0ZWR7e2VuZH19PuWFs+mXrTwvb3B0aW9uPg0KICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4+572u6aG26ZO+5o6lPC9zcGFuPiZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPHNlbGVjdCBuYW1lPSJsaW5rIiBpZD0iaXMtbGluayI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCJ7e2lmIGVxIC5QYWdlLklzTGlua2VkIGZhbHNlfX0gc2VsZWN0ZWR7e2VuZH19PuWFs+mXrTwvb3B0aW9uPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEie3tpZiBlcSAuUGFnZS5Jc0xpbmtlZCB0cnVlfX0gc2VsZWN0ZWR7e2VuZH19PuWFgeiuuDwvb3B0aW9uPg0KICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgIDwvcD4NCiAgICA8L2Rpdj4NCiAgICA8cCBjbGFzcz0ic3VibWl0IHRleHQtcmlnaHQiIGlkPSJhcnRpY2xlLXN1Ym1pdCI+DQogICAgICAgIDxzcGFuIGNsYXNzPSJpbnZhbGlkIGxibCBsYmwtcmVkIGhpZGUiIGlkPSJzbHVnLWludmFsaWQiPuWbuuWumumTvuaOpeeUseWtl+avje+8jOaVsOWtl+WSjC3nu4TmiJA8L3NwYW4+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5L+d5a2Y5paH56ugPC9idXR0b24+DQogICAgPC9wPg0KPC9mb3JtPg0KPGZvcm0gY2xhc3M9ImZvcm0gaGlkZSIgaWQ9ImF0dGFjaC1mb3JtIiBhY3Rpb249Ii9hZG1pbi9maWxlcy91cGxvYWQvIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBtZXRob2Q9InBvc3QiPg0KICAgIDxpbnB1dCBpZD0iYXR0YWNoLXVwbG9hZCIgdHlwZT0iZmlsZSIgbmFtZT0iZmlsZSIvPg0KPC9mb3JtPg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2NvZGVtaXJyb3IubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9jb2RlbWlycm9yLW1vZGUubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9tYXJrZWQubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9oaWdobGlnaHQubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2pzL3VwbG9hZC5qcyI+PC9zY3JpcHQ+DQo8c2NyaXB0Pg0KICAgICQoZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgZWRpdG9yID0gQ29kZU1pcnJvci5mcm9tVGV4dEFyZWEoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKSwgew0KICAgICAgICAgICAgbW9kZTogJ21hcmtkb3duJywNCiAgICAgICAgICAgIGxpbmVOdW1iZXJzOiB0cnVlLA0KICAgICAgICAgICAgdGhlbWU6ICJkZWZhdWx0IiwNCiAgICAgICAgICAgIGV4dHJhS2V5czogeyJFbnRlciI6ICJuZXdsaW5lQW5kSW5kZW50Q29udGludWVNYXJrZG93bkxpc3QifQ0KICAgICAgICB9KTsNCiAgICAgICAgZWRpdG9yLm9uKCJjaGFuZ2UiLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB2YXIgc3RyID0gZWRpdG9yLmdldFZhbHVlKCk7DQogICAgICAgICAgICAkKCcucHJldmlldycpLmh0bWwobWFya2VkKHN0cikpLmZpbmQoInByZSBjb2RlIikuZWFjaChmdW5jdGlvbiAoaSwgZSkgew0KICAgICAgICAgICAgICAgIGhsanMuaGlnaGxpZ2h0QmxvY2soZSk7DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIG5ldyBGb3JtVmFsaWRhdG9yKCJhcnRpY2xlLWZvcm0iLCBbDQogICAgICAgICAgICB7Im5hbWUiOiAic2x1ZyIsICJydWxlcyI6ICJhbHBoYV9kYXNoIn0NCiAgICAgICAgXSwgZnVuY3Rpb24gKGVycm9ycywgZSkgew0KICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOw0KICAgICAgICAgICAgJCgnLmludmFsaWQnKS5oaWRlKCk7DQogICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCkgew0KICAgICAgICAgICAgICAgICQoIiMiICsgZXJyb3JzWzBdLmlkICsgIi1pbnZhbGlkIikucmVtb3ZlQ2xhc3MoImhpZGUiKS5zaG93KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJCgnI2FydGljbGUtZm9ybScpLmFqYXhTdWJtaXQoZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgICAgICBpZiAoanNvbi5yZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmZpcm0oIuW3suS/neWtmO+8jOWOu+afpeeci++8n+i/mOaYr+e7p+e7ree8lui+kSIpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9ICIvYWRtaW4vcGFnZXMvIjsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGFsZXJ0KGpzb24ubXNnKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSk7DQogICAgICAgIGluaXRVcGxvYWQoIiNhcnRpY2xlLXN1Ym1pdCIpOw0KICAgIH0pOw0KPC9zY3JpcHQ+UEsHCG+ShHDfDwAA3w8AAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFQAAAHZpZXdcYWRtaW5cZmlsZXMuaHRtbDx1bCBpZD0iZmlsZXMtbGlzdCIgY2xhc3M9ImFkbWluIGNvbnRhaW5lcjk2MCBwYWdlciI+DQogICAgPGxpIGNsYXNzPSJmaWxlIiBpZD0iZmlsZXMtYnRuLWxpIj4NCiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1ncmVlbiIgaWQ9ImF0dGFjaC1zaG93Ij7mt7vliqDpmYTku7Y8L2J1dHRvbj4NCiAgICA8L2xpPnt7cmFuZ2UgLkZpbGVzfX0NCiAgICA8bGkgY2xhc3M9ImZpbGUiIGlkPSJmaWxlLXt7LklkfX0iPg0KICAgICAgICA8c3BhbiBjbGFzcz0idXBsb2FkLXRpbWUiPnt7RGF0ZUludDY0IC5VcGxvYWRUaW1lICJNTS5ERCJ9fTwvc3Bhbj4NCiAgICAgICAgPHNwYW4gY2xhc3M9InNpemUiPnt7RmlsZVNpemUgLlNpemV9fTwvc3Bhbj4NCiAgICAgICAgPHNwYW4gY2xhc3M9Im5hbWUiPnt7Lk5hbWV9fTwvc3Bhbj4NCiAgICAgICAgPGEgY2xhc3M9ImxpbmsiIGhyZWY9Ii97ey5Vcmx9fSIgdGFyZ2V0PSJfYmxhbmsiIHRpdGxlPSIve3suVXJsfX0iPuafpeecizwvYT4NCiAgICAgICAgPGEgY2xhc3M9ImRlbCBmYWRlLW91dCIgaHJlZj0iIyIgcmVsPSJ7ey5JZH19IiB0aXRsZT0i5Yig6Zmk6ZmE5Lu2Ij7liKDpmaQ8L2E+DQogICAgPC9saT57e2VuZH19DQogICAge3tyYW5nZSAuUGFnZXIuUGFnZVNsaWNlfX0NCiAgICA8bGkgY2xhc3M9Iml0ZW17e2lmIGVxICQuUGFnZXIuQ3VycmVudCAufX0gY3VycmVudHt7ZW5kfX0iPjxhIGhyZWY9Ii9hZG1pbi9maWxlcy8/cGFnZT17ey59fSI+e3sufX08L2E+PC9saT57e2VuZH19DQo8L3VsPg0KPGZvcm0gY2xhc3M9ImZvcm0gaGlkZSIgaWQ9ImF0dGFjaC1mb3JtIiBhY3Rpb249Ii9hZG1pbi9maWxlcy91cGxvYWQvIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBtZXRob2Q9InBvc3QiPg0KICAgIDxpbnB1dCBpZD0iYXR0YWNoLXVwbG9hZCIgdHlwZT0iZmlsZSIgbmFtZT0iZmlsZSIvPg0KPC9mb3JtPg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvanMvdXBsb2FkLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbiAoKSB7DQogICAgICAgIGluaXRVcGxvYWQoIiNhdHRhY2gtc2hvdyIpOw0KICAgICAgICAkKCIuZGVsIikub24oImNsaWNrIiwgZnVuY3Rpb24gKCkgew0KICAgICAgICAgICAgaWYgKGNvbmZpcm0oIuWIoOmZpOmZhOS7tuebuOWFs+mTvuaOpeS8muWkseaViCEiKSkgew0KICAgICAgICAgICAgICAgIHZhciBpZCA9ICQodGhpcykuYXR0cigicmVsIik7DQogICAgICAgICAgICAgICAgJC5hamF4KHsNCiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiZGVsZXRlIiwNCiAgICAgICAgICAgICAgICAgICAgInVybCI6ICIvYWRtaW4vZmlsZXMvP2lkPSIgKyBpZCwNCiAgICAgICAgICAgICAgICAgICAgInN1Y2Nlc3MiOiBmdW5jdGlvbiAoanNvbikgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoanNvbi5yZXMpew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNmaWxlLScraWQpLnJlbW92ZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoanNvbi5tc2cpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0pDQogICAgfSk7DQo8L3NjcmlwdD5QSwcIubTxfqwGAACsBgAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAdmlld1xhZG1pblxob21lLmh0bWw8ZGl2IGNsYXNzPSJhZG1pbiBjb250YWluZXIgY2xlYXIiIGlkPSJkYXNoYm9hcmQiPg0KICAgIDxkaXYgY2xhc3M9ImdyaWQtMS01IGxlZnQiPg0KICAgICAgICA8ZGl2IGNsYXNzPSJ3ZWxjb21lIj4NCiAgICAgICAgICAgIDxoND5XZWxjb21lPC9oND4NCiAgICAgICAgICAgIDxwPuasoui/juWbnuadpe+8jCA8c3Ryb25nPnt7LlVzZXIuTmlja319PC9zdHJvbmc+PC9wPg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBjbGFzcz0icXVpY2stbGluayI+DQogICAgICAgICAgICA8aDQ+5b+r6YCf6ZO+5o6lPC9oND4NCiAgICAgICAgICAgIDx1bD4NCiAgICAgICAgICAgICAgICA8bGk+PGEgaHJlZj0iL2FkbWluL2FydGljbGUvd3JpdGUvIj7mkrDlhpnmlofnq6A8L2E+PC9saT4NCiAgICAgICAgICAgICAgICA8bGk+PGEgaHJlZj0iL2FkbWluL3BhZ2Uvd3JpdGUvIj7mt7vliqDpobXpnaI8L2E+PC9saT4NCiAgICAgICAgICAgICAgICA8bGk+PGEgaHJlZj0iL2FkbWluL2NvbW1lbnRzLyI+5p+l55yL5ZKM5a6h5qC46K+E6K66PC9hPjwvbGk+DQogICAgICAgICAgICAgICAgPGxpPjxhIGhyZWY9Ii9hZG1pbi9zZXR0aW5nLyI+5L+u5pS56YWN572uPC9hPjwvbGk+DQogICAgICAgICAgICAgICAgPGxpPjxhIGhyZWY9Ii9hZG1pbi9wcm9maWxlLyI+5pu05paw5Liq5Lq66LWE5paZPC9hPjwvbGk+DQogICAgICAgICAgICA8L3VsPg0KICAgICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGNsYXNzPSJncmlkLTEtMiBsZWZ0Ij4NCiAgICAgICAgPGRpdiBjbGFzcz0iYWN0aXZpdHkiPg0KICAgICAgICAgICAgPGg0PuacgOaWsOa0u+WKqDwvaDQ+e3tyYW5nZSAuTWVzc2FnZXN9fQ0KICAgICAgICAgICAgPGRpdiBjbGFzcz0ibXNnIHJlbGF0aXZlIHt7LlR5cGV9fSI+DQogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9InRpbWUiPnt7RGF0ZUludDY0IC5DcmVhdGVUaW1lICJNTS5ERCBISDptbSJ9fTwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJkYXRhIj57e0h0bWwgLkRhdGF9fTwvZGl2Pg0KICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJyZWFkIGFic29sdXRlIiBocmVmPSIvYWRtaW4vbWVzc2FnZS9yZWFkP2lkPXt7LklkfX0iIHJlbD0ie3suSWR9fSI+6ZqQ6JePPC9hPg0KICAgICAgICAgICAgPC9kaXY+e3tlbmR9fXt7aWYgbHQgKGxlbiAuTWVzc2FnZXMpIDF9fQ0KICAgICAgICAgICAgPHA+5rKh5pyJ5paw55qE5rS75Yqo5L+h5oGvPC9wPg0KICAgICAgICAgICAge3tlbmR9fQ0KICAgICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGNsYXNzPSJncmlkLTEtNCByaWdodCI+DQogICAgICAgIDxkaXYgY2xhc3M9InN0YXRzIj4NCiAgICAgICAgICAgIDxoND7mlbDmja7nu5/orqE8L2g0Pg0KICAgICAgICAgICAgPHA+5bey57uP5Y+R5biD5paH56ugIDxzcGFuIGNsYXNzPSJsYmwgbGJsLXJlZCI+e3suU3RhdGlzLkFydGljbGVzfX08L3NwYW4+IOevh++8jA0KICAgICAgICAgICAg6aG16Z2iIDxzcGFuIGNsYXNzPSJsYmwgbGJsLXJlZCI+e3suU3RhdGlzLlBhZ2VzfX08L3NwYW4+IOS4qu+8jCA8YnIvPg0KICAgICAgICAgICAg5pS25Yiw6K+E6K66IDxzcGFuIGNsYXNzPSJsYmwgbGJsLWJsdWUiPnt7LlN0YXRpcy5Db21tZW50c319PC9zcGFuPiDmrKHvvIwNCiAgICAgICAgICAgIOS4iuS8oCA8c3BhbiBjbGFzcz0ibGJsIGxibC1ncmVlbiI+e3suU3RhdGlzLkZpbGVzfX08L3NwYW4+IOS4qumZhOS7tu+8jDxici8+DQogICAgICAgICAgICDor4TorrrogIUgPHNwYW4gY2xhc3M9ImxibCBsYmwtZ3JlZW4iPnt7LlN0YXRpcy5SZWFkZXJzfX08L3NwYW4+IOS6ujwvcD4NCiAgICAgICAgICAgIDxwPuW9k+WJjeeoi+W6j+eJiOacrO+8mjxzdHJvbmc+e3suU3RhdGlzLlZlcnNpb259fTwvc3Ryb25nPjwvcD4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgY2xhc3M9Im9mZmljZSI+DQogICAgICAgICAgICA8aDQ+5a6Y5pa55raI5oGvPC9oND4NCiAgICAgICAgICAgIDxwPui/mOayoeaciea2iOaBrzwvcD4NCiAgICAgICAgPC9kaXY+DQogICAgPC9kaXY+DQo8L2Rpdj4NCjxzY3JpcHQ+DQogICAgJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXsNCiAgICAgICAkKCIucmVhZCIpLm9uKCJjbGljayIsZnVuY3Rpb24oKXsNCiAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKTsNCiAgICAgICAgICAgJC5wb3N0KCR0aGlzLmF0dHIoImhyZWYiKSxmdW5jdGlvbihqc29uKXsNCiAgICAgICAgICAgICAgaWYoanNvbi5yZXMpew0KICAgICAgICAgICAgICAgICAgJHRoaXMucGFyZW50KCkucmVtb3ZlKCk7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgfSk7DQogICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICB9KTsNCiAgICB9KTsNCjwvc2NyaXB0PlBLBwiEpr8mZQkAAGUJAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABUAAAB2aWV3XGFkbWluXGxvZ2luLmh0bWw8IURPQ1RZUEUgaHRtbD4NCjxodG1sPg0KPGhlYWQ+DQogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiLz4NCiAgICA8dGl0bGU+55m75b2VIC0gRnhoLkdvPC90aXRsZT4NCiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9zdGF0aWMvY3NzL2NvbW1vbi5jc3MiLz4NCiAgICA8c3R5bGU+DQogICAgICAgICNsb2dpbi1mb3Jtew0KICAgICAgICAgICAgd2lkdGg6IDI4MHB4Ow0KICAgICAgICAgICAgbWFyZ2luOiA4MHB4IGF1dG87DQogICAgICAgIH0NCiAgICAgICAgI2xvZ2luLWZvcm0gaDF7DQogICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAxMnB4Ow0KICAgICAgICB9DQogICAgPC9zdHlsZT4NCjwvaGVhZD4NCjxib2R5Pg0KPGZvcm0gaWQ9ImxvZ2luLWZvcm0iIGNsYXNzPSJmb3JtIGZvcm0tdmVydGljYWwiIGFjdGlvbj0iIyIgbWV0aG9kPSJwb3N0IiBuYW1lPSJsb2dpbi1mb3JtIj4NCiAgICA8aDE+55m75b2VIC0gRnhoLkdvPC9oMT4NCiAgICA8cCBjbGFzcz0iZmllbGQiPg0KICAgICAgICA8bGFiZWwgZm9yPSJ1c2VyIj7nlKjmiLflkI08L2xhYmVsPg0KICAgICAgICA8aW5wdXQgY2xhc3M9ImlwdCIgaWQ9InVzZXIiIHR5cGU9InRleHQiIHJlcXVpcmVkPSJyZXF1aXJlZCIgbmFtZT0idXNlciIvPg0KICAgICAgICA8c3BhbiBjbGFzcz0iaW52YWxpZCBsYmwgbGJsLXJlZCBoaWRlIiBpZD0idXNlci1pbnZhbGlkIj7nlKjmiLflkI3kuLrlrZfmr40r5pWw5a2X77yM6ZW/5bqmNC0yMOS4quWtl+espjwvc3Bhbj4NCiAgICA8L3A+DQogICAgPHAgY2xhc3M9ImZpZWxkIj4NCiAgICAgICAgPGxhYmVsIGZvcj0icGFzc3dvcmQiPueUqOaIt+WvhueggTwvbGFiZWw+DQogICAgICAgIDxpbnB1dCBjbGFzcz0iaXB0IiBpZD0icGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiByZXF1aXJlZD0icmVxdWlyZWQiIG5hbWU9InBhc3N3b3JkIi8+DQogICAgICAgIDxzcGFuIGNsYXNzPSJpbnZhbGlkIGxibCBsYmwtcmVkIGhpZGUiIGlkPSJwYXNzd29yZC1pbnZhbGlkIj7lr4bnoIHplb/luqY0LTIw5Liq5a2X56ymPC9zcGFuPg0KICAgIDwvcD4NCiAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWJsdWUiPueZuyDlvZU8L2J1dHRvbj4NCiAgICA8c3BhbiBjbGFzcz0idGlwIj7pu5jorqTorrDkvY/nmbvpmYYz5aSpPC9zcGFuPg0KPC9mb3JtPg0KPHNjcmlwdCBzcmM9Imh0dHA6Ly9saWJzLmJhaWR1LmNvbS9qcXVlcnkvMS44LjMvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+DQo8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvdmFsaWRhdGUubWluLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9qcXVlcnkuZm9ybS5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdD4NCiAgICAkKGZ1bmN0aW9uICgpIHsNCiAgICAgICAgbmV3IEZvcm1WYWxpZGF0b3IoImxvZ2luLWZvcm0iLCBbDQogICAgICAgICAgICB7Im5hbWUiOiAidXNlciIsICJydWxlcyI6ICJhbHBoYV9udW1lcmljfG1pbl9sZW5ndGhbNF18bWF4X2xlbmd0aFsyMF0ifSwNCiAgICAgICAgICAgIHsibmFtZSI6ICJwYXNzd29yZCIsICJydWxlcyI6ICJyZXF1aXJlZHxtaW5fbGVuZ3RoWzRdfG1heF9sZW5ndGhbMjBdIn0NCiAgICAgICAgXSwgZnVuY3Rpb24gKGVycm9ycywgZSkgew0KICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOw0KICAgICAgICAgICAgJCgnLmludmFsaWQnKS5oaWRlKCk7DQogICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCkgew0KICAgICAgICAgICAgICAgICQoIiMiICsgZXJyb3JzWzBdLmlkICsgIi1pbnZhbGlkIikucmVtb3ZlQ2xhc3MoImhpZGUiKS5zaG93KCk7DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJCgnI2xvZ2luLWZvcm0nKS5hamF4U3VibWl0KHsNCiAgICAgICAgICAgICAgICBkYXRhVHlwZTogImpzb24iLA0KICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChqc29uKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICghanNvbi5yZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KCLnmbvlvZXplJnor6/vvIzor7fmo4Dmn6XnlKjmiLfmiJblr4bnoIEiKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gIi9hZG1pbi8iOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0pDQogICAgfSk7DQo8L3NjcmlwdD4NCjwvYm9keT4NCjwvaHRtbD5QSwcINP2heOsIAADrCAAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAdmlld1xhZG1pblxwYWdlcy5odG1sPHVsIGlkPSJhcnRpY2xlLWxpc3QiIGNsYXNzPSJjb250YWluZXI5NjAgYWRtaW4iPg0KICAgIDxsaT4NCiAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtYmx1ZSIgaHJlZj0iL2FkbWluL3BhZ2Uvd3JpdGUvIj7mt7vliqDpobXpnaI8L2E+DQogICAgPC9saT57e3JhbmdlIC5QYWdlc319DQogICAgPGxpPg0KICAgICAgICA8c3BhbiBjbGFzcz0idGltZSI+e3tEYXRlSW50NjQgLkNyZWF0ZVRpbWUgIk1NLkREIn19PC9zcGFuPjxoNCBjbGFzcz0iaW5saW5lLWJsb2NrIHRpdGxlIj48YSBocmVmPSJ7ey5MaW5rfX0iIHRhcmdldD0iX2JsYW5rIj57ey5UaXRsZX19PC9hPjwvaDQ+e3tpZiBuZSAuU3RhdHVzICJwdWJsaXNoIn19DQogICAgICAgIDxzcGFuIGNsYXNzPSJsYmwgc3RhdHVzIj7ojYnnqL88L3NwYW4+e3tlbmR9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0ic2x1ZyI+e3suU2x1Z319PC9zcGFuPnt7aWYgZXEgLklzQ29tbWVudCBmYWxzZX19DQogICAgICAgIDxzcGFuIGNsYXNzPSJpcy1jb21tZW50Ij7lhbPor4Q8L3NwYW4+e3tlbmR9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0iY291bnQiPnt7LkNvbW1lbnROdW19fSAvIHt7LkhpdHN9fTwvc3Bhbj4NCiAgICAgICAgPGEgY2xhc3M9ImVkaXQgbGJsIGxibC1ncmVlbiIgaHJlZj0iL2FkbWluL3BhZ2Uve3suSWR9fS8iIHJlbD0ie3suSWR9fSI+57yW6L6RPC9hPg0KICAgICAgICA8YSBjbGFzcz0iZGVsIGxibCBsYmwtcmVkIiBocmVmPSIvYWRtaW4vcGFnZS97ey5JZH19LyIgcmVsPSJ7ey5JZH19Ij7liKDpmaQ8L2E+DQogICAgPC9saT57e2VuZH19DQo8L3VsPg0KPHVsIGlkPSJhcnRpY2xlLXBhZ2VyIiBjbGFzcz0icGFnZXIgY29udGFpbmVyOTYwIj57e3JhbmdlIC5QYWdlci5QYWdlU2xpY2V9fQ0KICAgIDxsaSBjbGFzcz0iaXRlbXt7aWYgZXEgJC5QYWdlci5DdXJyZW50IC59fSBjdXJyZW50e3tlbmR9fSI+PGEgaHJlZj0iL2FkbWluL3BhZ2VzLz9wYWdlPXt7Ln19Ij57ey59fTwvYT48L2xpPnt7ZW5kfX0NCjwvdWw+DQo8c2NyaXB0Pg0KICAgICQoIi5kZWwiKS5vbigiY2xpY2siLGZ1bmN0aW9uKGUpew0KICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7DQogICAgICAgIGlmKGNvbmZpcm0oIuWIoOmZpOmhtemdouWwhuS9v+ebuOWFs+WGheWuueWkseaViO+8geehruiupO+8nyIpKXsNCiAgICAgICAgICAgIHZhciBpZCA9ICQodGhpcykuYXR0cigicmVsIik7DQogICAgICAgICAgICAkLmFqYXgoew0KICAgICAgICAgICAgICAgICJ1cmwiOiIvYWRtaW4vcGFnZS8iK2lkKyIvIiwNCiAgICAgICAgICAgICAgICAidHlwZSI6ImRlbGV0ZSIsDQogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKGpzb24pew0KICAgICAgICAgICAgICAgICAgICBpZihqc29uLnJlcyl7DQogICAgICAgICAgICAgICAgICAgICAgICBhbGVydCgi5bey5Yig6ZmkIik7DQogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7DQogICAgICAgICAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoanNvbi5tc2cpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSkNCiAgICAgICAgfQ0KICAgIH0pOw0KPC9zY3JpcHQ+UEsHCMMNnkZpBgAAaQYAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAHZpZXdcYWRtaW5ccGFzc3dvcmQuaHRtbDxmb3JtIGlkPSJwYXNzd29yZCIgY2xhc3M9ImZvcm0gZm9ybS1hbGlnbiBjbGVhciIgYWN0aW9uPSIjIiBuYW1lPSJwYXNzd29yZC1mb3JtIiBtZXRob2Q9InBvc3QiPg0KICAgIDxwIGNsYXNzPSJmaWVsZCI+DQogICAgICAgIDxsYWJlbCBmb3I9Im9sZCI+5pen5a+G56CBPC9sYWJlbD4NCiAgICAgICAgPGlucHV0IGlkPSJvbGQiIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJvbGQiIHJlcXVpcmVkPSJyZXF1aXJlZCIgY2xhc3M9ImlwdCIvPg0KICAgICAgICA8c3BhbiBjbGFzcz0idGlwIj7pqozor4Hml6flr4bnoIE8L3NwYW4+PGJyLz4NCiAgICAgICAgPHNwYW4gY2xhc3M9ImludmFsaWQgbGJsIGxibC1yZWQgaGlkZSIgaWQ9Im9sZC1pbnZhbGlkIj7lr4bnoIHplb/luqY0LTIw5Liq5a2X56ymPC9zcGFuPg0KICAgIDwvcD4NCiAgICA8cCBjbGFzcz0iZmllbGQiPg0KICAgICAgICA8bGFiZWwgZm9yPSJuZXciPuaWsOWvhueggTwvbGFiZWw+DQogICAgICAgIDxpbnB1dCBpZD0ibmV3IiB0eXBlPSJwYXNzd29yZCIgbmFtZT0ibmV3IiByZXF1aXJlZD0icmVxdWlyZWQiIGNsYXNzPSJpcHQiLz48YnIvPg0KICAgICAgICA8c3BhbiBjbGFzcz0iaW52YWxpZCBsYmwgbGJsLXJlZCBoaWRlIiBpZD0ibmV3LWludmFsaWQiPuWvhueggemVv+W6pjQtMjDkuKrlrZfnrKY8L3NwYW4+DQogICAgPC9wPg0KICAgIDxwIGNsYXNzPSJmaWVsZCI+DQogICAgICAgIDxsYWJlbCBmb3I9ImNvbmZpcm0iPuehruiupOWvhueggTwvbGFiZWw+DQogICAgICAgIDxpbnB1dCBpZD0iY29uZmlybSIgdHlwZT0icGFzc3dvcmQiIG5hbWU9ImNvbmZpcm0iIHJlcXVpcmVkPSJyZXF1aXJlZCIgY2xhc3M9ImlwdCIvPjxici8+DQogICAgICAgIDxzcGFuIGNsYXNzPSJpbnZhbGlkIGxibCBsYmwtcmVkIGhpZGUiIGlkPSJjb25maXJtLWludmFsaWQiPuehruiupOWvhueggeS4jeWMuemFjTwvc3Bhbj4NCiAgICA8L3A+DQogICAgPHAgY2xhc3M9ImZpZWxkIj4NCiAgICAgICAgPGxhYmVsPiZuYnNwOzwvbGFiZWw+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5L+d5a2Y5L+u5pS5PC9idXR0b24+DQogICAgPC9wPg0KPC9mb3JtPg0KPHNjcmlwdD4NCiAgICAkKGZ1bmN0aW9uKCl7DQogICAgICAgIG5ldyBGb3JtVmFsaWRhdG9yKCJwYXNzd29yZC1mb3JtIixbDQogICAgICAgICAgICB7Im5hbWUiOiJvbGQiLCJydWxlcyI6Im1pbl9sZW5ndGhbMl18bWF4X2xlbmd0aFsyMF0ifSwNCiAgICAgICAgICAgIHsibmFtZSI6Im5ldyIsInJ1bGVzIjoibWluX2xlbmd0aFsyXXxtYXhfbGVuZ3RoWzIwXSJ9LA0KICAgICAgICAgICAgeyJuYW1lIjoiY29uZmlybSIsInJ1bGVzIjoicmVxdWlyZWR8bWF0Y2hlc1tuZXddIn0NCiAgICAgICAgXSxmdW5jdGlvbihlcnJvcnMsZSl7DQogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7DQogICAgICAgICAgICAkKCcuaW52YWxpZCcpLmhpZGUoKTsNCiAgICAgICAgICAgIGlmKGVycm9ycy5sZW5ndGgpew0KICAgICAgICAgICAgICAgICQoIiMiK2Vycm9yc1swXS5pZCsiLWludmFsaWQiKS5yZW1vdmVDbGFzcygiaGlkZSIpLnNob3coKTsNCiAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkKCcjcGFzc3dvcmQnKS5hamF4U3VibWl0KGZ1bmN0aW9uKGpzb24pew0KICAgICAgICAgICAgICAgIGlmKCFqc29uLnJlcyl7DQogICAgICAgICAgICAgICAgICAgIGFsZXJ0KGpzb24ubXNnKTsNCiAgICAgICAgICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgICAgICAgICAgYWxlcnQoIuW3suS/neWtmCIpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9KQ0KICAgIH0pOw0KPC9zY3JpcHQ+UEsHCG5xJ4FPBwAATwcAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAHZpZXdcYWRtaW5ccGx1Z2luLmh0bWw8dWwgaWQ9InBsdWdpbi1saXN0IiBjbGFzcz0iY29udGFpbmVyOTYwIGFkbWluIj57e3JhbmdlIC5QbHVnaW5zfX0NCiAgICA8bGkgY2xhc3M9ImNsZWFyIj57e2lmIC5Jc0FjdGl2ZX19DQogICAgICAgIDxzcGFuIGNsYXNzPSJsZWZ0IGxibCBhY3RpdmUgbGJsLWdyZWVuIj4mbmJzcDs8L3NwYW4+e3tlbmR9fQ0KICAgICAgICA8c3BhbiBjbGFzcz0ibmFtZSBsZWZ0Ij57ey5OYW1lfX08L3NwYW4+DQogICAgICAgIDxzcGFuIGNsYXNzPSJ2ZXJzaW9uIGxlZnQiPnt7LlZlcnNpb259fTwvc3Bhbj57e2lmIC5IYXNTZXR0aW5nfX0NCiAgICAgICAgPGEgY2xhc3M9InNldHRpbmcgbGVmdCIgaHJlZj0iL2FkbWluL3BsdWdpbnMve3suS2V5fX0vIj7pgInpobk8L2E+e3tlbmR9fXt7aWYgLklzQWN0aXZlfX0NCiAgICAgICAgPGEgY2xhc3M9ImRlYWN0aXZhdGUgbGJsIGxibC1yZWQgcmlnaHQiIGhyZWY9IiMiIHJlbD0ie3suS2V5fX0iPuWwgeWNsDwvYT57e2Vsc2V9fQ0KICAgICAgICA8YSBjbGFzcz0iYWN0aXZhdGUgbGJsIGxibC1ibHVlIHJpZ2h0IiBocmVmPSIjIiByZWw9Int7LktleX19Ij7mv4DmtLs8L2E+e3tlbmR9fQ0KICAgICAgICA8cCBjbGFzcz0iZGVzYyBsZWZ0Ij57ey5EZXNjfX08L3A+DQogICAgPC9saT57e2VuZH19DQo8L3VsPg0KPHNjcmlwdD4NCiAgICAkKGZ1bmN0aW9uICgpIHsNCiAgICAgICAgJCgiLmRlYWN0aXZhdGUiKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpOw0KICAgICAgICAgICAgdmFyIHAgPSAkdGhpcy5hdHRyKCJyZWwiKTsNCiAgICAgICAgICAgICQucG9zdCgiIiwgew0KICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiZGVhY3RpdmF0ZSIsDQogICAgICAgICAgICAgICAgInBsdWdpbiI6IHANCiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChqc29uKSB7DQogICAgICAgICAgICAgICAgaWYgKGpzb24ucmVzKSB7DQogICAgICAgICAgICAgICAgICAgICR0aGlzLm9mZigiY2xpY2siKS50ZXh0KCLkuIvmrKHmv4DmtLsiKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBhbGVydCgi5bCB5Y2w5aSx6LSlIik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSkNCiAgICAgICAgfSk7DQogICAgICAgICQoIi5hY3RpdmF0ZSIpLm9uKCJjbGljayIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcyk7DQogICAgICAgICAgICB2YXIgcCA9ICR0aGlzLmF0dHIoInJlbCIpOw0KICAgICAgICAgICAgJC5wb3N0KCIiLCB7DQogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhY3RpdmF0ZSIsDQogICAgICAgICAgICAgICAgInBsdWdpbiI6IHANCiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChqc29uKSB7DQogICAgICAgICAgICAgICAgaWYgKGpzb24ucmVzKSB7DQogICAgICAgICAgICAgICAgICAgICR0aGlzLm9mZigiY2xpY2siKS50ZXh0KCLkuIvmrKHlsIHljbAiKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBhbGVydCgi5r+A5rS75aSx6LSlIik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSkNCiAgICAgICAgfSkNCiAgICB9KTsNCjwvc2NyaXB0PlBLBwhPcFmhYgYAAGIGAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAB2aWV3XGFkbWluXHBsdWdpbl9zZXR0aW5nLmh0bWw8Zm9ybSBpZD0icGx1Z2luLXNldHRpbmctZm9ybSIgY2xhc3M9ImZvcm0gY29udGFpbmVyOTYwIGFkbWluIiBhY3Rpb249IiMiIG1ldGhvZD0icG9zdCI+DQogICAge3tIdG1sIC5Gb3JtfX0NCjwvZm9ybT4NCjxzY3JpcHQ+DQogICAgJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXsNCiAgICAgICAgJCgnI3BsdWdpbi1zZXR0aW5nLWZvcm0nKS5hamF4Rm9ybShmdW5jdGlvbihqc29uKXsNCiAgICAgICAgICAgIGFsZXJ0KGpzb24ucmVzID8gIuW3suS/neWtmCI6IuS/neWtmOWksei0pSIpOw0KICAgICAgICB9KQ0KICAgIH0pDQo8L3NjcmlwdD5QSwcINCtz1TgBAAA4AQAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAdmlld1xhZG1pblxwcm9maWxlLmh0bWw8Zm9ybSBpZD0icHJvZmlsZSIgY2xhc3M9ImFkbWluIGZvcm0gY2xlYXIgZm9ybS1hbGlnbiIgYWN0aW9uPSIjIiBtZXRob2Q9InBvc3QiIG5hbWU9InByb2ZpbGUtZm9ybSI+DQogICAgPGRpdiBjbGFzcz0iYXZhdGFyIGdyaWQtMS00IGxlZnQgdGV4dC1jZW50ZXIiPg0KICAgICAgICA8aW1nIHNyYz0ie3suVXNlci5BdmF0YXJ9fSIgYWx0PSJ7ey5Vc2VyLk5pY2t9fSIgY2xhc3M9ImZpZWxkIi8+DQogICAgICAgIDxzcGFuIGNsYXNzPSJ0aXAgZmllbGQgaW5saW5lLWJsb2NrIj7lpLTlg4/nlLEgPGEgaHJlZj0iaHR0cDovL2dyYXZhdGFyLmNvbS8iIHRhcmdldD0iX2JsYW5rIiByZWw9Im5vLWZvbGxvdyI+R3JhdmF0YXI8L2E+IOaPkOS+mzwvc3Bhbj4NCiAgICAgICAgPHAgY2xhc3M9ImZpZWxkIj4NCiAgICAgICAgICAgIDxhIGNsYXNzPSJidG4gYnRuLXJlZCBpbmxpbmUtYmxvY2siIGhyZWY9Ii9hZG1pbi9wYXNzd29yZC8iPuS/ruaUueWvhueggTwvYT4NCiAgICAgICAgPC9wPg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImluZm8gcmlnaHQgZ3JpZC0zLTQiPg0KICAgICAgICA8cCBjbGFzcz0iZmllbGQiPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0idXNlciI+55m75b2V5ZCNPC9sYWJlbD4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0idXNlciIgdHlwZT0idGV4dCIgbmFtZT0idXNlciIgdmFsdWU9Int7LlVzZXIuTmFtZX19IiByZXF1aXJlZD0icmVxdWlyZWQiIGNsYXNzPSJpcHQiLz4NCiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJ0aXAiPueZu+W9leeahOeUqOaIt+WQjTwvc3Bhbj48YnIvPg0KICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImludmFsaWQgbGJsIGxibC1yZWQgaGlkZSIgaWQ9InVzZXItaW52YWxpZCI+55So5oi35ZCN5Li65a2X5q+NK+aVsOWtl++8jOmVv+W6pjQtMjDkuKrlrZfnrKY8L3NwYW4+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9ImZpZWxkIj4NCiAgICAgICAgICAgIDxsYWJlbCBmb3I9Im5pY2siPuaYteensDwvbGFiZWw+DQogICAgICAgICAgICA8aW5wdXQgaWQ9Im5pY2siIHR5cGU9InRleHQiIG5hbWU9Im5pY2siIHZhbHVlPSJ7ey5Vc2VyLk5pY2t9fSIgcmVxdWlyZWQ9InJlcXVpcmVkIiBjbGFzcz0iaXB0Ii8+DQogICAgICAgICAgICA8c3BhbiBjbGFzcz0idGlwIj7mmL7npLrlnKjliY3lj7DnmoTnp7Dlkbw8L3NwYW4+DQogICAgICAgICAgICA8YnIvPjxzcGFuIGNsYXNzPSJpbnZhbGlkIGxibCBsYmwtcmVkIGhpZGUiIGlkPSJuaWNrLWludmFsaWQiPuaYteensOmVv+W6pjItMjDkuKrlrZfnrKY8L3NwYW4+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9ImZpZWxkIj4NCiAgICAgICAgICAgIDxsYWJlbCBmb3I9ImVtYWlsIj7pgq7nrrE8L2xhYmVsPg0KICAgICAgICAgICAgPGlucHV0IGlkPSJlbWFpbCIgdHlwZT0iZW1haWwiIG5hbWU9ImVtYWlsIiB2YWx1ZT0ie3suVXNlci5FbWFpbH19IiByZXF1aXJlZD0icmVxdWlyZWQiIGNsYXNzPSJpcHQiLz4NCiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJ0aXAiPuiBlOezu+mCrueuse+8jOWNgeWIhumHjeimge+8gTwvc3Bhbj4NCiAgICAgICAgICAgIDxici8+PHNwYW4gY2xhc3M9ImludmFsaWQgbGJsIGxibC1yZWQgaGlkZSIgaWQ9ImVtYWlsLWludmFsaWQiPumCrueuseagvOW8j+mUmeivrzwvc3Bhbj4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iZmllbGQiPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0idXJsIj7nvZHlnYA8L2xhYmVsPg0KICAgICAgICAgICAgPGlucHV0IGlkPSJ1cmwiIHR5cGU9InVybCIgbmFtZT0idXJsIiB2YWx1ZT0ie3suVXNlci5Vcmx9fSIgY2xhc3M9ImlwdCIvPg0KICAgICAgICAgICAgPGJyLz48c3BhbiBjbGFzcz0iaW52YWxpZCBsYmwgbGJsLXJlZCBoaWRlIiBpZD0idXJsLWludmFsaWQiPue9keWdgOagvOW8j+mUmeivrzwvc3Bhbj4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iZmllbGQiPg0KICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPSJpcHQgYmlvIiBuYW1lPSJiaW8iIGlkPSJiaW8iPnt7LlVzZXIuQmlvfX08L3RleHRhcmVhPg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJmaWVsZCI+DQogICAgICAgICAgICA8bGFiZWw+Jm5ic3A7PC9sYWJlbD4NCiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5L+d5a2Y5L+u5pS5PC9idXR0b24+DQogICAgICAgIDwvcD4NCiAgICA8L2Rpdj4NCjwvZm9ybT4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbigpew0KICAgICAgICBuZXcgRm9ybVZhbGlkYXRvcigicHJvZmlsZS1mb3JtIixbDQogICAgICAgICAgICB7Im5hbWUiOiJ1c2VyIiwicnVsZXMiOiJhbHBoYV9udW1lcmljfG1pbl9sZW5ndGhbNF18bWF4X2xlbmd0aFsyMF0ifSwNCiAgICAgICAgICAgIHsibmFtZSI6Im5pY2siLCJydWxlcyI6Im1pbl9sZW5ndGhbMl18bWF4X2xlbmd0aFsyMF0ifSwNCiAgICAgICAgICAgIHsibmFtZSI6ImVtYWlsIiwicnVsZXMiOiJ2YWxpZF9lbWFpbCJ9LA0KICAgICAgICAgICAgeyJuYW1lIjoidXJsIiwicnVsZXMiOiJ2YWxpZF91cmwifQ0KICAgICAgICBdLGZ1bmN0aW9uKGVycm9ycyxlKXsNCiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTsNCiAgICAgICAgICAgICQoJy5pbnZhbGlkJykuaGlkZSgpOw0KICAgICAgICAgICAgaWYoZXJyb3JzLmxlbmd0aCl7DQogICAgICAgICAgICAgICAgJCgiIyIrZXJyb3JzWzBdLmlkKyItaW52YWxpZCIpLnJlbW92ZUNsYXNzKCJoaWRlIikuc2hvdygpOw0KICAgICAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICQoJyNwcm9maWxlJykuYWpheFN1Ym1pdChmdW5jdGlvbihqc29uKXsNCiAgICAgICAgICAgICAgICBpZighanNvbi5yZXMpew0KICAgICAgICAgICAgICAgICAgICBhbGVydChqc29uLm1zZyk7DQogICAgICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAgICAgIGFsZXJ0KCLlt7Lkv53lrZgiKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSkNCiAgICB9KTsNCjwvc2NyaXB0PlBLBwgfj6FfAgwAAAIMAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABcAAAB2aWV3XGFkbWluXHNldHRpbmcuaHRtbDx1bCBpZD0ic2V0dGluZy1uYXYiIGNsYXNzPSJjb250YWluZXIgdGV4dC1jZW50ZXIiPg0KICAgIDxsaT48YSBocmVmPSIjZ2VuZXJhbCI+5Z+65pysPC9hPjwvbGk+DQogICAgPGxpPjxhIGhyZWY9IiNjb250ZW50Ij7lhoXlrrk8L2E+PC9saT4NCiAgICA8bGk+PGEgaHJlZj0iI25hdiI+5a+86IiqPC9hPjwvbGk+DQogICAgPGxpPjxhIGhyZWY9IiNjdXN0b20iPuiHquWumuS5iTwvYT48L2xpPg0KPC91bD4NCjxkaXYgaWQ9InNldHRpbmctcGFuZWxzIiBjbGFzcz0iY29udGFpbmVyIj4NCiAgICA8Zm9ybSBpZD0ic2V0dGluZy1mb3JtIiBjbGFzcz0ic2V0dGluZy1mb3JtIGZvcm0gZm9ybS1hbGlnbiBzZXR0aW5nLXBhbmVsIiBhY3Rpb249Ii9hZG1pbi9zZXR0aW5nLyIgbWV0aG9kPSJwb3N0Ij4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0ic2l0ZS11cmwiPuermeeCueWcsOWdgDwvbGFiZWw+DQogICAgICAgICAgICA8aW5wdXQgaWQ9InNpdGUtdXJsIiBjbGFzcz0iaXB0IiB0eXBlPSJ1cmwiIG5hbWU9InNpdGVfdXJsIiByZXF1aXJlZD0icmVxdWlyZWQiIHZhbHVlPSJ7e1NldHRpbmcgYHNpdGVfdXJsYH19Ii8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0ic2l0ZS10aXRsZSI+56uZ54K55Li75qCH6aKYPC9sYWJlbD4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0ic2l0ZS10aXRsZSIgY2xhc3M9ImlwdCIgdHlwZT0idGV4dCIgbmFtZT0ic2l0ZV90aXRsZSIgcmVxdWlyZWQ9InJlcXVpcmVkIiB2YWx1ZT0ie3tTZXR0aW5nIGBzaXRlX3RpdGxlYH19Ii8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0ic2l0ZS1zdWItdGl0bGUiPuermeeCueWJr+agh+mimDwvbGFiZWw+DQogICAgICAgICAgICA8aW5wdXQgaWQ9InNpdGUtc3ViLXRpdGxlIiBjbGFzcz0iaXB0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJzaXRlX3N1Yl90aXRsZSIgcmVxdWlyZWQ9InJlcXVpcmVkIiB2YWx1ZT0ie3tTZXR0aW5nIGBzaXRlX3N1Yl90aXRsZWB9fSIvPg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxsYWJlbCBmb3I9InNpdGUta2V5d29yZHMiPk1ldGHlhbPplK7lrZc8L2xhYmVsPg0KICAgICAgICAgICAgPGlucHV0IGlkPSJzaXRlLWtleXdvcmRzIiBjbGFzcz0iaXB0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJzaXRlX2tleXdvcmRzIiB2YWx1ZT0ie3tTZXR0aW5nIGBzaXRlX2tleXdvcmRzYH19Ii8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0ic2l0ZS1kZXNjIj5NZXRh56uZ54K55LuL57uNPC9sYWJlbD4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0ic2l0ZS1kZXNjIiBjbGFzcz0iaXB0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJzaXRlX2Rlc2NyaXB0aW9uIiB2YWx1ZT0ie3tTZXR0aW5nIGBzaXRlX2Rlc2NyaXB0aW9uYH19Ii8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHA+DQogICAgICAgICAgICA8bGFiZWw+Jm5ic3A7PC9sYWJlbD4NCiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5L+d5a2YPC9idXR0b24+DQogICAgICAgIDwvcD4NCiAgICA8L2Zvcm0+DQogICAgPGZvcm0gaWQ9InNldHRpbmctY29udGVudC1mb3JtIiBjbGFzcz0ic2V0dGluZy1mb3JtIGZvcm0gZm9ybS1hbGlnbiBzZXR0aW5nLXBhbmVsIiBhY3Rpb249Ii9hZG1pbi9zZXR0aW5nLyIgbWV0aG9kPSJwb3N0Ij4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0iYXJ0aWNsZS1zaXplIj7ljZXpobXmlofnq6DliJfooajmlbA8L2xhYmVsPg0KICAgICAgICAgICAgPGlucHV0IGlkPSJhcnRpY2xlLXNpemUiIGNsYXNzPSJpcHQiIHR5cGU9Im51bWJlciIgbmFtZT0iYXJ0aWNsZV9zaXplIiB2YWx1ZT0ie3tTZXR0aW5nIGBhcnRpY2xlX3NpemVgfX0iIG1heD0iMTAiIG1pbj0iMyIgcmVxdWlyZWQ9InJlcXVpcmVkIi8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPGxhYmVsIGZvcj0icG9wdWxhci1zaXplIj7ng63or4Tmlofnq6DliJfooajmlbA8L2xhYmVsPg0KICAgICAgICAgICAgPGlucHV0IGlkPSJwb3B1bGFyLXNpemUiIGNsYXNzPSJpcHQiIHR5cGU9Im51bWJlciIgbmFtZT0icG9wdWxhcl9zaXplIiB2YWx1ZT0ie3tTZXR0aW5nIGBwb3B1bGFyX3NpemVgfX0iIG1heD0iMTAiIG1pbj0iMyIgIHJlcXVpcmVkPSJyZXF1aXJlZCIvPg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxsYWJlbCBmb3I9InJlY2VudC1jb21tZW50LXNpemUiPuacgOi/keivhOiuuuWIl+ihqOaVsDwvbGFiZWw+DQogICAgICAgICAgICA8aW5wdXQgaWQ9InJlY2VudC1jb21tZW50LXNpemUiIGNsYXNzPSJpcHQiIHR5cGU9Im51bWJlciIgbmFtZT0icmVjZW50X2NvbW1lbnRfc2l6ZSIgdmFsdWU9Int7U2V0dGluZyBgcmVjZW50X2NvbW1lbnRfc2l6ZWB9fSIgbWF4PSIxMCIgbWluPSIzIiByZXF1aXJlZD0icmVxdWlyZWQiLz4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8bGFiZWwgZm9yPSJnby1tYXJrZG93biI+R2/muLLmn5NNYXJrZG93bjwvbGFiZWw+DQogICAgICAgICAgICA8aW5wdXQgaWQ9ImdvLW1hcmtkb3duIiBjbGFzcz0iaXB0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJlbmFibGVfZ29fbWFya2Rvd24iIHZhbHVlPSJ7e1NldHRpbmcgYGVuYWJsZV9nb19tYXJrZG93bmB9fSIvPg0KICAgICAgICAgICAgPHNwYW4gY2xhc3M9InRpcCBibG9jayI+6buY6K6k5YWz6Zet77yM5L2/55So5YmN56uvbWFya2VkLmpz5riy5p+T77yM5aGrdHJ1ZeaXtuW8gOWQrzwvc3Bhbj4NCiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImVuYWJsZV9nb19tYXJrZG93bl9kZWYiIHZhbHVlPSJmYWxzZSIvPg0KICAgICAgICA8L3A+DQogICAgICAgIDxwPg0KICAgICAgICAgICAgPGxhYmVsPiZuYnNwOzwvbGFiZWw+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWJsdWUiPuS/neWtmDwvYnV0dG9uPg0KICAgICAgICA8L3A+DQogICAgPC9mb3JtPg0KICAgIDxmb3JtIGlkPSJzZXR0aW5nLW5hdi1mb3JtIiBjbGFzcz0ic2V0dGluZy1mb3JtIGZvcm0gZm9ybS1hbGlnbiBzZXR0aW5nLXBhbmVsIiBhY3Rpb249Ii9hZG1pbi9zZXR0aW5nL25hdi8iIG1ldGhvZD0icG9zdCI+e3tyYW5nZSAuTmF2aWdhdG9yc319DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJsYWJlbCI+5o6S5bqPPC9zcGFuPjxpbnB1dCBjbGFzcz0iaXB0IG9yZGVyIiB0eXBlPSJudW1iZXIiIG5hbWU9Im9yZGVyIiB2YWx1ZT0ie3suT3JkZXJ9fSIvPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImxhYmVsIj7mlofmnKw8L3NwYW4+PGlucHV0IGNsYXNzPSJpcHQgdGV4dCIgdHlwZT0idGV4dCIgbmFtZT0idGV4dCIgdmFsdWU9Int7LlRleHR9fSIgcmVxdWlyZWQ9InJlcXVpcmVkIi8+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPuagh+mimDwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCB0aXRsZSIgdHlwZT0idGV4dCIgbmFtZT0idGl0bGUiIHZhbHVlPSJ7ey5UaXRsZX19Ii8+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPumTvuaOpTwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCBsaW5rIiB0eXBlPSJ0ZXh0IiBuYW1lPSJsaW5rIiB2YWx1ZT0ie3suTGlua319IiByZXF1aXJlZD0icmVxdWlyZWQiLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxhIGNsYXNzPSJkZWwiIGhyZWY9IiMiPuWIoOmZpDwvYT4NCiAgICAgICAgPC9wPnt7ZW5kfX0NCiAgICAgICAgPHA+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWJsdWUiPuS/neWtmDwvYnV0dG9uPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtZ3JlZW4gYWRkIiBocmVmPSIjIiByZWw9IiNuYXYtaXRlbSI+5re75Yqg5LiA6aG5PC9hPg0KICAgICAgICA8L3A+DQogICAgICAgIDxzY3JpcHQgdHlwZT0idGV4dC90ZW1wbGF0ZSIgaWQ9Im5hdi1pdGVtIj4NCiAgICAgICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPuaOkuW6jzwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCBvcmRlciIgdHlwZT0ibnVtYmVyIiBuYW1lPSJvcmRlciIgdmFsdWU9IjEiLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPuaWh+acrDwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCB0ZXh0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJ0ZXh0IiB2YWx1ZT0iIiByZXF1aXJlZD0icmVxdWlyZWQiLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPuagh+mimDwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCB0aXRsZSIgdHlwZT0idGV4dCIgbmFtZT0idGl0bGUiIHZhbHVlPSIiLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPumTvuaOpTwvc3Bhbj48aW5wdXQgY2xhc3M9ImlwdCBsaW5rIiB0eXBlPSJ0ZXh0IiBuYW1lPSJsaW5rIiB2YWx1ZT0iIiByZXF1aXJlZD0icmVxdWlyZWQiLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0iZGVsIiBocmVmPSIjIj7liKDpmaQ8L2E+DQogICAgICAgICAgICA8L3A+DQogICAgICAgIDwvc2NyaXB0Pg0KICAgIDwvZm9ybT4NCiAgICA8Zm9ybSBpZD0ic2V0dGluZy1jdXN0b20tZm9ybSIgY2xhc3M9InNldHRpbmctZm9ybSBmb3JtIGZvcm0tYWxpZ24gc2V0dGluZy1wYW5lbCIgYWN0aW9uPSIvYWRtaW4vc2V0dGluZy9jdXN0b20vIiBtZXRob2Q9InBvc3QiPnt7cmFuZ2UgJGssJHYgOj0gLkN1c3RvbX19DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0iaXB0IGtleSIgdHlwZT0idGV4dCIgbmFtZT0ia2V5IiB2YWx1ZT0ie3ska319Ii8+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8aW5wdXQgbmFtZT0idmFsdWUiIGNsYXNzPSJpcHQgdmFsdWUiIHR5cGU9InRleHQiIHZhbHVlPSJ7eyR2fX0iLz4NCiAgICAgICAgICAgIDxhIGNsYXNzPSJkZWwiIGhyZWY9IiMiPuWIoOmZpDwvYT4NCiAgICAgICAgPC9wPnt7ZW5kfX0NCiAgICAgICAgPHA+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWJsdWUiPuS/neWtmDwvYnV0dG9uPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtZ3JlZW4gYWRkIiBocmVmPSIjIiByZWw9IiNjdXN0b20taXRlbSI+5re75Yqg5LiA6aG5PC9hPg0KICAgICAgICAgICAgPHNwYW4gY2xhc3M9InRpcCBibG9jayI+5L2/55So5Ye95pWw6Ieq5a6a5LmJ6YWN572u77yM6ZyA6KaB5Yqg5YmN57yAImNfIu+8jOWmgkdldFNldHRpbmcoImNfa2V5Iik8L3NwYW4+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHNjcmlwdCB0eXBlPSJ0ZXh0L3RlbXBsYXRlIiBpZD0iY3VzdG9tLWl0ZW0iPg0KICAgICAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0iaXB0IGtleSIgdHlwZT0idGV4dCIgbmFtZT0ia2V5IiBwbGFjZWhvbGRlcj0i5a2X5q615ZCNIi8+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICAgICAgPGlucHV0IG5hbWU9InZhbHVlIiBjbGFzcz0iaXB0IHZhbHVlIiB0eXBlPSJ0ZXh0IiBwbGFjZWhvbGRlcj0i5a2X5q615YC8Ii8+DQogICAgICAgICAgICAgICAgPGEgY2xhc3M9ImRlbCIgaHJlZj0iIyI+5Yig6ZmkPC9hPg0KICAgICAgICAgICAgPC9wPg0KICAgICAgICA8L3NjcmlwdD4NCiAgICA8L2Zvcm0+DQo8L2Rpdj4NCjxzY3JpcHQgc3JjPSJodHRwOi8vbGlicy5iYWlkdS5jb20vanF1ZXJ5dG9vbHMvMS4yLjcvanF1ZXJ5LnRvb2xzLm1pbi5qcyI+PC9zY3JpcHQ+DQo8c2NyaXB0Pg0KICAgICQoZnVuY3Rpb24gKCkgew0KICAgICAgICAkKCcjc2V0dGluZy1uYXYnKS50YWJzKCIuc2V0dGluZy1wYW5lbCIpOw0KICAgICAgICAkKCcuc2V0dGluZy1mb3JtJykuYWpheEZvcm0oZnVuY3Rpb24gKGpzb24pIHsNCiAgICAgICAgICAgIGFsZXJ0KGpzb24ucmVzID8gIuW3suS/neWtmCIgOiBqc29uLm1zZyk7DQogICAgICAgIH0pLm9uKCJjbGljayIsIi5hZGQiLGZ1bmN0aW9uKGUpew0KICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOw0KICAgICAgICAgICAgJCh0aGlzKS5wYXJlbnQoKS5wYXJlbnQoKS5wcmVwZW5kKCQoJCh0aGlzKS5hdHRyKCJyZWwiKSkuaHRtbCgpKTsNCiAgICAgICAgfSkub24oImNsaWNrIiwiLmRlbCIsZnVuY3Rpb24oZSl7DQogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7DQogICAgICAgICAgICBpZihjb25maXJtKCLopoHliKDpmaTov5npobnvvJ8iKSl7DQogICAgICAgICAgICAgICAgJCh0aGlzKS5wYXJlbnQoKS5yZW1vdmUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSkNCiAgICB9KQ0KPC9zY3JpcHQ+UEsHCBDClLKKGgAAihoAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAHZpZXdcYWRtaW5cd3JpdGVfYXJ0aWNsZS5odG1sPHN0eWxlPg0KICAgIEBpbXBvcnQgIi9zdGF0aWMvY3NzL2NvZGVtaXJyb3IuY3NzIjsNCiAgICBAaW1wb3J0ICIvc3RhdGljL2Nzcy9oaWdobGlnaHQuY3NzIjsNCjwvc3R5bGU+DQo8Zm9ybSBpZD0iYXJ0aWNsZS1mb3JtIiBjbGFzcz0iZm9ybSBjbGVhciBjb250YWluZXIiIGFjdGlvbj0iIyIgbWV0aG9kPSJwb3N0Ij4NCiAgICA8ZGl2IGNsYXNzPSJsZWZ0IGdyaWQtMS0yIj4NCiAgICAgICAgPGlucHV0IGNsYXNzPSJpcHQgdGl0bGUiIGlkPSJ0aXRsZSIgdHlwZT0idGV4dCIgcmVxdWlyZWQ9InJlcXVpcmVkIiBuYW1lPSJ0aXRsZSIgcGxhY2Vob2xkZXI9IuaWh+eroOagh+mimCIvPg0KICAgICAgICA8dGV4dGFyZWEgbmFtZT0iY29udGVudCIgaWQ9ImNvbnRlbnQiIGNsYXNzPSJpcHQiPuaSsOWGmeaWh+eroOWGheWuue+8jOaUr+aMgWBtYXJrZG93bmDor63ms5Xpq5jkuq48L3RleHRhcmVhPg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImxlZnQgZ3JpZC0xLTIiPg0KICAgICAgICA8ZGl2IGNsYXNzPSJwcmV2aWV3IG1hcmtkb3duIj48L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGNsYXNzPSJmb3JtLXZlcnRpY2FsIGxlZnQiPg0KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWdyZWVuIGxlZnQiIHR5cGU9ImJ1dHRvbiIgaWQ9ImF0dGFjaC1zaG93Ij7mt7vliqDpmYTku7Y8L2J1dHRvbj4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4gZm9yPSJzbHVnIj7lm7rlrprpk77mjqU8L3NwYW4+Jm5ic3A7Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8aW5wdXQgaWQ9InNsdWciIGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InNsdWciIHJlcXVpcmVkPSJyZXF1aXJlZCIgcGxhY2Vob2xkZXI9IuaWh+eroOeahOWUr+S4gOmTvuaOpSIvPg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxzcGFuPuagh+etvjwvc3Bhbj4mbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxpbnB1dCBpZD0idGFnIiBjbGFzcz0iaXB0IiB0eXBlPSJ0ZXh0IiBuYW1lPSJ0YWciIHBsYWNlaG9sZGVyPSLmlofnq6DnmoTmoIfnrb4iLz4NCiAgICAgICAgPC9wPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8c3Bhbj7kv53lrZjnirbmgIE8L3NwYW4+Jm5ic3A7Jm5ic3A7DQogICAgICAgICAgICA8c2VsZWN0IG5hbWU9InN0YXR1cyIgaWQ9InN0YXR1cyI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icHVibGlzaCI+5YWs5byAPC9vcHRpb24+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iZHJhZnQiPuiNieeovzwvb3B0aW9uPg0KICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4+5YWB6K646K+E6K66PC9zcGFuPiZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPHNlbGVjdCBuYW1lPSJjb21tZW50IiBpZD0iaXMtY29tbWVudCI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMSI+5YWB6K64PC9vcHRpb24+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+5YWz6ZetPC9vcHRpb24+DQogICAgICAgICAgICA8L3NlbGVjdD4NCiAgICAgICAgPC9wPg0KICAgIDwvZGl2Pg0KICAgIDxwIGNsYXNzPSJzdWJtaXQgdGV4dC1yaWdodCIgaWQ9ImFydGljbGUtc3VibWl0Ij4NCiAgICAgICAgPHNwYW4gY2xhc3M9ImludmFsaWQgbGJsIGxibC1yZWQgaGlkZSIgaWQ9InNsdWctaW52YWxpZCI+5Zu65a6a6ZO+5o6l55Sx5a2X5q+N77yM5pWw5a2X5ZKMLee7hOaIkDwvc3Bhbj4NCiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1ibHVlIj7kv53lrZjmlofnq6A8L2J1dHRvbj4NCiAgICA8L3A+DQo8L2Zvcm0+DQo8Zm9ybSBjbGFzcz0iZm9ybSBoaWRlIiBpZD0iYXR0YWNoLWZvcm0iIGFjdGlvbj0iL2FkbWluL2ZpbGVzL3VwbG9hZC8iIGVuY3R5cGU9Im11bHRpcGFydC9mb3JtLWRhdGEiIG1ldGhvZD0icG9zdCI+DQogICAgPGlucHV0IGlkPSJhdHRhY2gtdXBsb2FkIiB0eXBlPSJmaWxlIiBuYW1lPSJmaWxlIi8+DQo8L2Zvcm0+DQo8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvY29kZW1pcnJvci5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2NvZGVtaXJyb3ItbW9kZS5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL21hcmtlZC5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2hpZ2hsaWdodC5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvanMvdXBsb2FkLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBlZGl0b3IgPSBDb2RlTWlycm9yLmZyb21UZXh0QXJlYShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudCIpLCB7DQogICAgICAgICAgICBtb2RlOiAnbWFya2Rvd24nLA0KICAgICAgICAgICAgbGluZU51bWJlcnM6IHRydWUsDQogICAgICAgICAgICB0aGVtZTogImRlZmF1bHQiLA0KICAgICAgICAgICAgZXh0cmFLZXlzOiB7IkVudGVyIjogIm5ld2xpbmVBbmRJbmRlbnRDb250aW51ZU1hcmtkb3duTGlzdCJ9DQogICAgICAgIH0pOw0KICAgICAgICBlZGl0b3Iub24oImNoYW5nZSIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBzdHIgPSBlZGl0b3IuZ2V0VmFsdWUoKTsNCiAgICAgICAgICAgICQoJy5wcmV2aWV3JykuaHRtbChtYXJrZWQoc3RyKSkuZmluZCgicHJlIGNvZGUiKS5lYWNoKGZ1bmN0aW9uIChpLCBlKSB7DQogICAgICAgICAgICAgICAgaGxqcy5oaWdobGlnaHRCbG9jayhlKTsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9KTsNCiAgICAgICAgbmV3IEZvcm1WYWxpZGF0b3IoImFydGljbGUtZm9ybSIsIFsNCiAgICAgICAgICAgIHsibmFtZSI6ICJzbHVnIiwgInJ1bGVzIjogImFscGhhX2Rhc2gifQ0KICAgICAgICBdLGZ1bmN0aW9uIChlcnJvcnMsIGUpIHsNCiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTsNCiAgICAgICAgICAgICQoJy5pbnZhbGlkJykuaGlkZSgpOw0KICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGgpIHsNCiAgICAgICAgICAgICAgICAkKCIjIiArIGVycm9yc1swXS5pZCArICItaW52YWxpZCIpLnJlbW92ZUNsYXNzKCJoaWRlIikuc2hvdygpOw0KICAgICAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICQoJyNhcnRpY2xlLWZvcm0nKS5hamF4U3VibWl0KGZ1bmN0aW9uIChqc29uKSB7DQogICAgICAgICAgICAgICAgaWYgKGpzb24ucmVzKSB7DQogICAgICAgICAgICAgICAgICAgIGFsZXJ0KCLlt7Lkv53lrZgiKTsNCiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAiL2FkbWluL2FydGljbGVzLyI7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgYWxlcnQoanNvbi5tc2cpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9KTsNCiAgICAgICAgaW5pdFVwbG9hZCgiI2FydGljbGUtc3VibWl0Iik7DQogICAgfSk7DQo8L3NjcmlwdD5QSwcIFurhzyQOAAAkDgAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAdmlld1xhZG1pblx3cml0ZV9wYWdlLmh0bWw8c3R5bGU+DQogICAgQGltcG9ydCAiL3N0YXRpYy9jc3MvY29kZW1pcnJvci5jc3MiOw0KICAgIEBpbXBvcnQgIi9zdGF0aWMvY3NzL2hpZ2hsaWdodC5jc3MiOw0KPC9zdHlsZT4NCjxmb3JtIGlkPSJhcnRpY2xlLWZvcm0iIGNsYXNzPSJmb3JtIGNsZWFyIGNvbnRhaW5lciIgYWN0aW9uPSIjIiBtZXRob2Q9InBvc3QiPg0KICAgIDxkaXYgY2xhc3M9ImxlZnQgZ3JpZC0xLTIiPg0KICAgICAgICA8aW5wdXQgY2xhc3M9ImlwdCB0aXRsZSIgaWQ9InRpdGxlIiB0eXBlPSJ0ZXh0IiByZXF1aXJlZD0icmVxdWlyZWQiIG5hbWU9InRpdGxlIiBwbGFjZWhvbGRlcj0i6aG16Z2i5qCH6aKYIi8+DQogICAgICAgIDx0ZXh0YXJlYSBuYW1lPSJjb250ZW50IiBpZD0iY29udGVudCIgY2xhc3M9ImlwdCI+5pKw5YaZ6aG16Z2i5YaF5a6577yM5pSv5oyBYG1hcmtkb3duYOivreazlemrmOS6rjwvdGV4dGFyZWE+DQogICAgPC9kaXY+DQogICAgPGRpdiBjbGFzcz0ibGVmdCBncmlkLTEtMiI+DQogICAgICAgIDxkaXYgY2xhc3M9InByZXZpZXcgbWFya2Rvd24iPjwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImZvcm0tdmVydGljYWwgbGVmdCI+DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZ3JlZW4gbGVmdCIgdHlwZT0iYnV0dG9uIiBpZD0iYXR0YWNoLXNob3ciPua3u+WKoOmZhOS7tjwvYnV0dG9uPg0KICAgICAgICA8cCBjbGFzcz0iaXRlbSI+DQogICAgICAgICAgICA8c3BhbiBmb3I9InNsdWciPuWbuuWumumTvuaOpTwvc3Bhbj4mbmJzcDsmbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxpbnB1dCBpZD0ic2x1ZyIgY2xhc3M9ImlwdCIgdHlwZT0idGV4dCIgbmFtZT0ic2x1ZyIgcmVxdWlyZWQ9InJlcXVpcmVkIiBwbGFjZWhvbGRlcj0i6aG16Z2i55qE5ZSv5LiA6ZO+5o6lIi8+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4+5L+d5a2Y54q25oCBPC9zcGFuPiZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPHNlbGVjdCBuYW1lPSJzdGF0dXMiIGlkPSJzdGF0dXMiPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9InB1Ymxpc2giPuWFrOW8gDwvb3B0aW9uPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImRyYWZ0Ij7ojYnnqL88L29wdGlvbj4NCiAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICA8L3A+DQogICAgICAgIDxwIGNsYXNzPSJpdGVtIj4NCiAgICAgICAgICAgIDxzcGFuPuWFgeiuuOivhOiuujwvc3Bhbj4mbmJzcDsmbmJzcDsNCiAgICAgICAgICAgIDxzZWxlY3QgbmFtZT0iY29tbWVudCIgaWQ9ImlzLWNvbW1lbnQiPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPuWFgeiuuDwvb3B0aW9uPg0KICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjAiPuWFs+mXrTwvb3B0aW9uPg0KICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgIDwvcD4NCiAgICAgICAgPHAgY2xhc3M9Iml0ZW0iPg0KICAgICAgICAgICAgPHNwYW4+572u6aG26ZO+5o6lPC9zcGFuPiZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPHNlbGVjdCBuYW1lPSJsaW5rIiBpZD0iaXMtbGluayI+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+5YWz6ZetPC9vcHRpb24+DQogICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMSI+5YWB6K64PC9vcHRpb24+DQogICAgICAgICAgICA8L3NlbGVjdD4NCiAgICAgICAgPC9wPg0KICAgIDwvZGl2Pg0KICAgIDxwIGNsYXNzPSJzdWJtaXQgdGV4dC1yaWdodCIgaWQ9ImFydGljbGUtc3VibWl0Ij4NCiAgICAgICAgPHNwYW4gY2xhc3M9ImludmFsaWQgbGJsIGxibC1yZWQgaGlkZSIgaWQ9InNsdWctaW52YWxpZCI+5Zu65a6a6ZO+5o6l55Sx5a2X5q+N77yM5pWw5a2X5ZKMLee7hOaIkDwvc3Bhbj4NCiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1ibHVlIj7kv53lrZjmlofnq6A8L2J1dHRvbj4NCiAgICA8L3A+DQo8L2Zvcm0+DQo8Zm9ybSBjbGFzcz0iZm9ybSBoaWRlIiBpZD0iYXR0YWNoLWZvcm0iIGFjdGlvbj0iL2FkbWluL2ZpbGVzL3VwbG9hZC8iIGVuY3R5cGU9Im11bHRpcGFydC9mb3JtLWRhdGEiIG1ldGhvZD0icG9zdCI+DQogICAgPGlucHV0IGlkPSJhdHRhY2gtdXBsb2FkIiB0eXBlPSJmaWxlIiBuYW1lPSJmaWxlIi8+DQo8L2Zvcm0+DQo8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvY29kZW1pcnJvci5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2NvZGVtaXJyb3ItbW9kZS5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL21hcmtlZC5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvbGliL2hpZ2hsaWdodC5taW4uanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvanMvdXBsb2FkLmpzIj48L3NjcmlwdD4NCjxzY3JpcHQ+DQogICAgJChmdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBlZGl0b3IgPSBDb2RlTWlycm9yLmZyb21UZXh0QXJlYShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudCIpLCB7DQogICAgICAgICAgICBtb2RlOiAnbWFya2Rvd24nLA0KICAgICAgICAgICAgbGluZU51bWJlcnM6IHRydWUsDQogICAgICAgICAgICB0aGVtZTogImRlZmF1bHQiLA0KICAgICAgICAgICAgZXh0cmFLZXlzOiB7IkVudGVyIjogIm5ld2xpbmVBbmRJbmRlbnRDb250aW51ZU1hcmtkb3duTGlzdCJ9DQogICAgICAgIH0pOw0KICAgICAgICBlZGl0b3Iub24oImNoYW5nZSIsIGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBzdHIgPSBlZGl0b3IuZ2V0VmFsdWUoKTsNCiAgICAgICAgICAgICQoJy5wcmV2aWV3JykuaHRtbChtYXJrZWQoc3RyKSkuZmluZCgicHJlIGNvZGUiKS5lYWNoKGZ1bmN0aW9uIChpLCBlKSB7DQogICAgICAgICAgICAgICAgaGxqcy5oaWdobGlnaHRCbG9jayhlKTsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICB9KTsNCiAgICAgICAgbmV3IEZvcm1WYWxpZGF0b3IoImFydGljbGUtZm9ybSIsIFsNCiAgICAgICAgICAgIHsibmFtZSI6ICJzbHVnIiwgInJ1bGVzIjogImFscGhhX2Rhc2gifQ0KICAgICAgICBdLGZ1bmN0aW9uIChlcnJvcnMsIGUpIHsNCiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTsNCiAgICAgICAgICAgICQoJy5pbnZhbGlkJykuaGlkZSgpOw0KICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGgpIHsNCiAgICAgICAgICAgICAgICAkKCIjIiArIGVycm9yc1swXS5pZCArICItaW52YWxpZCIpLnJlbW92ZUNsYXNzKCJoaWRlIikuc2hvdygpOw0KICAgICAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgICAgIH0N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bGJsIGxibC1ibHVlIGMtYXV0aG9ye3tpZiAuSXNBZG1pbn19IGFkbWlue3tlbmR9fSIgaHJlZj0ie3suVXJsfX0iIHRhcmdldD0iX2JsYW5rIj57ey5BdXRob3J9fXt7aWYgLklzQWRtaW59fSZuYnNwOyZuYnNwOyhhZG1pbil7e2VuZH19PC9hPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iYy10aW1lIj48aSBjbGFzcz0iZmEgZmEtY2xvY2stbyI+PC9pPnt7RGF0ZUludDY0IC5DcmVhdGVUaW1lICJNTS5ERCBISDptbSJ9fTwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9ImMtcmVwbHkiIGhyZWY9IiMiIHJlbD0ie3suSWR9fSI+PGkgY2xhc3M9ImZhIGZhLXF1b3RlLXJpZ2h0Ij48L2k+PC9hPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxzZWN0aW9uIGNsYXNzPSJjLWNvbnRlbnQiPnt7SHRtbCAuQ29udGVudH19PC9zZWN0aW9uPnt7aWYgLlBhcmVudE1kfX0NCiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXAtbWQgbWFya2Rvd24iPnt7SHRtbCAuUGFyZW50TWR9fTwvZGl2Pnt7ZW5kfX0NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj57e2VuZH19e3tlbmR9fQ0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImNvbW1lbnQtc2hvdyIgY2xhc3M9InRleHQtY2VudGVyIj57e2lmIC5Db250ZW50LklzQ29tbWVudH19DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZ3JlZW4gZW5hYmxlIj7lj5Hooajor4Torro8L2J1dHRvbj57e2Vsc2V9fQ0KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXJlZCI+5pys5paH5YWz6Zet5LqG6K+E6K66PC9idXR0b24+e3tlbmR9fQ0KICAgIDwvZGl2Pnt7aWYgLkNvbnRlbnQuSXNDb21tZW50fX0NCiAgICA8Zm9ybSBpZD0iY29tbWVudC1mb3JtIiBjbGFzcz0iaGlkZSBjbGVhciB0ZXh0LWNlbnRlciBmb3JtIiBhY3Rpb249Ii9jb21tZW50L3t7LkNvbnRlbnQuSWR9fS8iIG1ldGhvZD0icG9zdCI+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtaW5mbyBsZWZ0IHRleHQtcmlnaHQiPg0KICAgICAgICAgICAgPHAgY2xhc3M9Iml0ZW0gYy1hdmF0YXItZmllbGQiPg0KICAgICAgICAgICAgICAgIDxpbWcgY2xhc3M9ImMtYXZhdGFyIG51bGwiIHNyYz0iL3N0YXRpYy9pbWcvc2l0ZS5wbmciIGFsdD0iIiBpZD0iY29tbWVudC1hdmF0YXIiLz4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0ibm90LW1lIGJsb2NrIiBocmVmPSIjIj7kuI3mmK/miJE/PC9hPg0KICAgICAgICAgICAgPC9wPg0KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1pbmZvLWZpZWxkcyBoaWRlIj4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InVzZXIiIHJlcXVpcmVkPSJyZXF1aXJlZCIgcGxhY2Vob2xkZXI9IuensOWRvCIgaWQ9ImNvbW1lbnQtYXV0aG9yIi8+PC9wPg0KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJpdGVtIj48aW5wdXQgY2xhc3M9ImlwdCIgdHlwZT0iZW1haWwiIG5hbWU9ImVtYWlsIiByZXF1aXJlZD0icmVxdWlyZWQiIHBsYWNlaG9sZGVyPSLpgq7nrrEiIGlkPSJjb21tZW50LWVtYWlsIi8+IDwvcD4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InVybCIgbmFtZT0idXJsIiBwbGFjZWhvbGRlcj0i572R5Z2AIiBpZD0iY29tbWVudC11cmwiLz48L3A+DQogICAgICAgICAgICAgICAgPGlucHV0IGlkPSJjb21tZW50LXBhcmVudCIgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iMCIgbmFtZT0icGlkIi8+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtY29udGVudCB0ZXh0LWxlZnQgcmlnaHQiPg0KICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPSJpcHQiIG5hbWU9ImNvbnRlbnQiIGlkPSJjb21tZW50LWNvbnRlbnQiIHJlcXVpcmVkPSJyZXF1aXJlZCI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5Y+R6KGo6K+E6K66PC9idXR0b24+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJsYmwgbGJsLWdyZWVuIGNhbmNlbC1yZXBseSIgdHlwZT0iYnV0dG9uIj7lj5bmtojlm57lpI08L2J1dHRvbj4NCiAgICAgICAgPC9kaXY+DQogICAgPC9mb3JtPnt7ZW5kfX0NCiAgICA8c2NyaXB0IHR5cGU9InRleHQvdGVtcGxhdGUiIGlkPSJjb21tZW50LXRwbCI+DQogICAgICAgIDxkaXYgY2xhc3M9ImNvbW1lbnQgY2xlYXIiPg0KICAgICAgICAgICAgPGltZyBjbGFzcz0iYy1hdmF0YXIgbGVmdCIgc3JjPSIiIGFsdD0iIi8+DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXNlY3Rpb24gbGVmdCI+DQogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1tZXRhIj4NCiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9ImxibCBsYmwtYmx1ZSBjLWF1dGhvciIgaHJlZj0iIiB0YXJnZXQ9Il9ibGFuayI+PC9hPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iYy10aW1lIj48aSBjbGFzcz0iZmEgZmEtY2xvY2stbyI+PC9pPk5vdzwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9ImMtcmVwbHkiIGhyZWY9IiMiIHJlbD0iIj48aSBjbGFzcz0iZmEgZmEtcXVvdGUtcmlnaHQiPjwvaT48L2E+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJjLWNoZWNr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byBCbG9nIiAvPg0KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iL3N0YXRpYy9jc3Mvc3R5bGUuY3NzIi8+DQogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwOi8vbGlicy5iYWlkdS5jb20vZm9udGF3ZXNvbWUvNC4wLjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+DQogICAgPGxpbmsgcmVsPSJhbHRlcm5hdGUiIHR5cGU9ImFwcGxpY2F0aW9uL3Jzcyt4bWwiIHRpdGxlPSJ7e1NldHRpbmcgYHNpdGVfdGl0bGVgfX0gLSBSU1MgMi4wIiBocmVmPSIvZmVlZC8iLz4NCiAgICA8c2NyaXB0IHNyYz0iaHR0cDovL2xpYnMuYmFpZHUuY29tL2pxdWVyeS8xLjguMy9qcXVlcnkubWluLmpzIj48L3NjcmlwdD4NCiAgICA8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvanF1ZXJ5LmZvcm0ubWluLmpzIj48L3NjcmlwdD4NCiAgICA8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvbWFya2VkLm1pbi5qcyI+PC9zY3JpcHQ+DQo8L2hlYWQ+DQo8Ym9keT4NCjxoZWFkZXIgaWQ9ImhlYWRlciIgY2xhc3M9ImNsZWFyIj4NCiAgICA8ZGl2IGNsYXNzPSJjb250YWluZXI5NjAgdGV4dC1jZW50ZXIiPg0KICAgICAgICA8aW1nIHNyYz0ie3tTZXR0aW5nIGBjX2hvbWVfYXZhdGFyYH19IiBhbHQ9InNpdGUiIGlkPSJoZWFkZXItaW1nIi8+DQogICAgICAgIDxoMSBpZD0iaGVhZGVyLWgiPjxhIGhyZWY9Ii8iPnt7U2V0dGluZyAic2l0ZV90aXRsZSJ9fTwvYT48L2gxPg0KICAgICAgICA8aDQgaWQ9ImhlYWRlci1zdWIiPnt7U2V0dGluZyAic2l0ZV9zdWJfdGl0bGUifX08L2g0Pg0KICAgIDwvZGl2Pg0KPC9oZWFkZXI+DQo8bmF2IGlkPSJuYXYiIGNsYXNzPSJjbGVhciB0ZXh0LWNlbnRlciI+DQogICAgPHVsPnt7cmFuZ2UgTmF2aWdhdG9yfX0NCiAgICAgICAgPGxpIGNsYXNzPSJpbmxpbmUtYmxvY2siPjxhIGhyZWY9Int7Lkxpbmt9fSIgdGl0bGU9Int7LlRpdGxlfX0iPnt7LlRleHR9fTwvYT48L2xpPnt7ZW5kfX0NCiAgICA8L3VsPg0KPC9uYXY+DQo8ZGl2IGlkPSJtYWluIiBjbGFzcz0iY29udGFpbmVyOTYwIj4NCiAgICB7QENvbnRlbnR9DQo8L2Rpdj4NCjxmb290ZXIgaWQ9ImZvb3RlciIgY2xhc3M9InRleHQtY2VudGVyIj4NCiAgICA8cD4NCiAgICAgICAgPGEgY2xhc3M9IndlaWJvIiBocmVmPSJ7e1NldHRpbmcgYGNfZm9vdGVyX3dlaWJvYH19IiB0YXJnZXQ9Il9ibGFuayI+PGkgY2xhc3M9ImZhIGZhLXdlaWJvIj48L2k+V2VpYm88L2E+DQogICAgICAgIDxhIGNsYXNzPSJnaXQiIGhyZWY9Int7U2V0dGluZyBgY19mb290ZXJfZ2l0aHViYH19IiB0YXJnZXQ9Il9ibGFuayI+PGkgY2xhc3M9ImZhIGZhLWdpdGh1YiI+PC9pPkdpdEh1YjwvYT4NCiAgICAgICAgPGEgY2xhc3M9ImVtYWlsIiBocmVmPSJ7e1NldHRpbmcgYGNfZm9vdGVyX2VtYWlsYH19IiB0YXJnZXQ9Il9ibGFuayI+PGkgY2xhc3M9ImZhIGZhLWVudmVsb3BlIj48L2k+RW1haWw8L2E+DQogICAgICAgIDxhIGNsYXNzPSJyc3MiIGhyZWY9Ii9mZWVkLyIgdGFyZ2V0PSJfYmxhbmsiPjxpIGNsYXNzPSJmYSBmYS1yc3MiPjwvaT5SU1M8L2E+e3tTZXR0aW5nIGBjX2Zvb3Rlcl9nYWAgfCBIdG1sfX0NCiAgICA8L3A+DQogICAgPHNwYW4+R28gwqkgMjAxNCBBbGwgcmlnaHRzIHJlc2VydmVkLiBQcm91ZGx5IFBvd2VyZWQgYnkgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2Z1eGlhb2hlaS9Hb0Jsb2ciIHRhcmdldD0iX2JsYW5rIj5GeGguR288L2E+Ljwvc3Bhbj4NCiAgICA8YSBpZD0iZ28tdG9wIiBocmVmPSIjIiBjbGFzcz0ibGJsIGhpZGUgbGJsLWJsdWUiIHRpdGxlPSLlm57l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bnQtdGl0bGUiPuaWh+eroOivhOiuujwvaDQ+DQogICAgPGRpdiBjbGFzcz0ibWV0YSBhYnNvbHV0ZSB0ZXh0LWNlbnRlciI+DQogICAgICAgIDxwIGNsYXNzPSJsYmwgbGJsLXJlZCBjb21tZW50cyI+PGEgaHJlZj0ie3suTGlua319I2NvbW1lbnQiPnt7LkNvbnRlbnQuQ29tbWVudE51bX19PC9hPjwvcD4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGlkPSJjb21tZW50LWxpc3QiPnt7cmFuZ2UgLkNvbW1lbnRzfX17e2lmIC5Jc1ZhbGlkfX0NCiAgICAgICAgPGRpdiBjbGFzcz0iY29tbWVudCBjbGVhciIgaWQ9ImNvbW1lbnQte3suSWR9fSI+DQogICAgICAgICAgICA8aW1nIGNsYXNzPSJjLWF2YXRhciBsZWZ0IiBzcmM9Int7LkF2YXRhcn19IiBhbHQ9Int7LkF1dGhvcn19Ii8+DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXNlY3Rpb24iPg0KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImMtbWV0YSBjbGVhciI+DQogICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJjLXJlcGx5IGxibCByaWdodCIgaHJlZj0iIyIgcmVsPSJ7ey5JZH19Ij7lm57lpI08L2E+DQogICAgICAgICAgICAgICAgICAgIDxwPjxhIGNsYXNzPSJjLWF1dGhvcnt7aWYgLklzQWRtaW59fSBhZG1pbnt7ZW5kfX0iIGhyZWY9Int7LlVybH19IiB0YXJnZXQ9Il9ibGFuayI+e3suQXV0aG9yfX17e2lmIC5Jc0FkbWlufX0mbmJzcDsmbmJzcDsoYWRtaW4pe3tlbmR9fTwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgIDxwPjxzcGFuIGNsYXNzPSJjLXRpbWUiPnt7RGF0ZUludDY0IC5DcmVhdGVUaW1lICJNTSDmnIggREQg5pelIEhIIOaXtiBtbSDliIYifX08L3NwYW4+PC9wPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxzZWN0aW9uIGNsYXNzPSJjLWNvbnRlbnQiPnt7SHRtbCAuQ29udGVudH19PC9zZWN0aW9uPnt7aWYgLlBhcmVudE1kfX0NCiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXAtbWQgbWFya2Rvd24iPnt7SHRtbCAuUGFyZW50TWR9fTwvZGl2Pnt7ZW5kfX0NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj57e2VuZH19e3tlbmR9fQ0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImNvbW1lbnQtc2hvdyIgY2xhc3M9InRleHQtY2VudGVyIj57e2lmIC5Db250ZW50LklzQ29tbWVudH19DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZ3JlZW4gZW5hYmxlIj7lj5Hooajor4Torro8L2J1dHRvbj57e2Vsc2V9fQ0KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXJlZCI+5pys5paH5YWz6Zet5LqG6K+E6K66PC9idXR0b24+e3tlbmR9fQ0KICAgIDwvZGl2Pnt7aWYgLkNvbnRlbnQuSXNDb21tZW50fX0NCiAgICA8Zm9ybSBpZD0iY29tbWVudC1mb3JtIiBjbGFzcz0iaGlkZSBjbGVhciB0ZXh0LWNlbnRlciBmb3JtIiBhY3Rpb249Ii9jb21tZW50L3t7LkNvbnRlbnQuSWR9fS8iIG1ldGhvZD0icG9zdCI+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtaW5mbyBsZWZ0IHRleHQtcmlnaHQiPg0KICAgICAgICAgICAgPHAgY2xhc3M9Iml0ZW0gYy1hdmF0YXItZmllbGQiPg0KICAgICAgICAgICAgICAgIDxpbWcgY2xhc3M9ImMtYXZhdGFyIG51bGwiIHNyYz0iL3N0YXRpYy9pbWcvc2l0ZS5wbmciIGFsdD0iIiBpZD0iY29tbWVudC1hdmF0YXIiLz4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0ibm90LW1lIGJsb2NrIiBocmVmPSIjIj7kuI3mmK/miJE/PC9hPg0KICAgICAgICAgICAgPC9wPg0KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1pbmZvLWZpZWxkcyBoaWRlIj4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InVzZXIiIHJlcXVpcmVkPSJyZXF1aXJlZCIgcGxhY2Vob2xkZXI9IuensOWRvCIgaWQ9ImNvbW1lbnQtYXV0aG9yIi8+PC9wPg0KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJpdGVtIj48aW5wdXQgY2xhc3M9ImlwdCIgdHlwZT0iZW1haWwiIG5hbWU9ImVtYWlsIiByZXF1aXJlZD0icmVxdWlyZWQiIHBsYWNlaG9sZGVyPSLpgq7nrrEiIGlkPSJjb21tZW50LWVtYWlsIi8+IDwvcD4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InVybCIgbmFtZT0idXJsIiBwbGFjZWhvbGRlcj0i572R5Z2AIiBpZD0iY29tbWVudC11cmwiLz48L3A+DQogICAgICAgICAgICAgICAgPGlucHV0IGlkPSJjb21tZW50LXBhcmVudCIgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iMCIgbmFtZT0icGlkIi8+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtY29udGVudCB0ZXh0LWxlZnQgcmlnaHQiPg0KICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPSJpcHQiIG5hbWU9ImNvbnRlbnQiIGlkPSJjb21tZW50LWNvbnRlbnQiIHJlcXVpcmVkPSJyZXF1aXJlZCI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5Y+R6KGo6K+E6K66PC9idXR0b24+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJsYmwgbGJsLWdyZWVuIGNhbmNlbC1yZXBseSIgdHlwZT0iYnV0dG9uIj7lj5bmtojlm57lpI08L2J1dHRvbj4NCiAgICAgICAgPC9kaXY+DQogICAgPC9mb3JtPnt7ZW5kfX0NCiAgICA8c2NyaXB0IHR5cGU9InRleHQvdGVtcGxhdGUiIGlkPSJjb21tZW50LXRwbCI+DQogICAg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dXRmLTgiLz4NCiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiLz4NCiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIHVzZXItc2NhbGFibGU9bm8iLz4NCiAgICA8dGl0bGU+e3tpZiAuVGl0bGV9fXt7LlRpdGxlfX0gLSB7e2VuZH19e3tTZXR0aW5nICJzaXRlX3RpdGxlIn19PC90aXRsZT4NCiAgICA8bWV0YSBuYW1lPSJrZXl3b3JkcyIgY29udGVudD0ie3tTZXR0aW5nIGBzaXRlX2tleXdvcmRzYH19Ii8+DQogICAgPG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9Int7U2V0dGluZyBgc2l0ZV9kZXNjcmlwdGlvbmB9fSIvPg0KICAgIDxtZXRhIG5hbWU9ImdlbmVyYXRvciIgY29udGVudD0iRnhoR28gQmxvZyIgLz4NCiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9zdGF0aWMvY3NzL2xpbmcuY3NzIi8+DQogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwOi8vbGlicy5iYWlkdS5jb20vZm9udGF3ZXNvbWUvNC4wLjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+DQogICAgPGxpbmsgcmVsPSJhbHRlcm5hdGUiIHR5cGU9ImFwcGxpY2F0aW9uL3Jzcyt4bWwiIHRpdGxlPSJ7e1NldHRpbmcgYHNpdGVfdGl0bGVgfX0gLSBSU1MgMi4wIiBocmVmPSIvZmVlZC8iLz4NCiAgICA8c2NyaXB0IHNyYz0iaHR0cDovL2xpYnMuYmFpZHUuY29tL2pxdWVyeS8xLjguMy9qcXVlcnkubWluLmpzIj48L3NjcmlwdD4NCiAgICA8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvanF1ZXJ5LmZvcm0ubWluLmpzIj48L3NjcmlwdD4NCiAgICA8c2NyaXB0IHNyYz0iL3N0YXRpYy9saWIvbWFya2VkLm1pbi5qcyI+PC9zY3JpcHQ+DQo8L2hlYWQ+DQo8Ym9keT4NCjxoZWFkZXIgaWQ9ImhlYWRlciIgY2xhc3M9ImNsZWFyIj4NCiAgICA8ZGl2IGNsYXNzPSJjb250YWluZXI5NjAiPg0KICAgICAgICA8aW1nIHNyYz0ie3tTZXR0aW5nIGBjX2hvbWVfYXZhdGFyYH19IiBhbHQ9InNpdGUiIGlkPSJoZWFkZXItaW1nIiBjbGFzcz0ibGVmdCIvPg0KICAgICAgICA8aDEgaWQ9ImhlYWRlci1oIiBjbGFzcz0ibGVmdCI+PGEgaHJlZj0iLyI+e3tTZXR0aW5nICJzaXRlX3RpdGxlIn19PC9hPjwvaDE+DQogICAgICAgIDxoNCBpZD0iaGVhZGVyLXN1YiIgY2xhc3M9ImxlZnQiPnt7U2V0dGluZyAic2l0ZV9zdWJfdGl0bGUifX08L2g0Pg0KICAgICAgICA8bmF2IGlkPSJuYXYiIGNsYXNzPSJyaWdodCI+DQogICAgICAgICAgICA8dWw+e3tyYW5nZSBOYXZpZ2F0b3J9fQ0KICAgICAgICAgICAgICAgIDxsaSBjbGFzcz0iaW5saW5lLWJsb2NrIj48YSBocmVmPSJ7ey5MaW5rfX0iIHRpdGxlPSJ7ey5UaXRsZX19Ij57ey5UZXh0fX08L2E+PC9saT57e2VuZH19DQogICAgICAgICAgICA8L3VsPg0KICAgICAgICA8L25hdj4NCiAgICA8L2Rpdj4NCjwvaGVhZGVyPg0KPGRpdiBpZD0ibWFpbiIgY2xhc3M9ImNvbnRhaW5lcjk2MCI+DQogICAge0BDb250ZW50fQ0KPC9kaXY+DQo8Zm9vdGVyIGlkPSJmb290ZXIiIGNsYXNzPSJ0ZXh0LWNlbnRlciI+DQogICAgPGRpdiBjbGFzcz0iY29udGFpbmVyOTYwIGNsZWFyIj4NCiAgICAgICAgPHNwYW4gY2xhc3M9ImxlZnQiPkdvIMKpIDIwMTQgQWxsIHJpZ2h0cyByZXNlcnZlZC48L3NwYW4+DQogICAgICAgIDxzcGFuIGNsYXNzPSJyaWdodCI+PGEgaHJlZj0iL2ZlZWQvIj5SU1M8L2E+IC4gUHJvdWRseSBQb3dlcmVkIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9mdXhpYW9oZWkvR29CbG9nIiB0YXJnZXQ9Il9ibGFuayI+RnhoLkdvPC9hPi48L3NwYW4+DQogICAgPC9kaXY+DQogICAgPGEgaWQ9ImdvLXRvcCIgaHJlZj0iIyIgY2xhc3M9ImxibCBoaWRlIGxibC1ibHVlIiB0aXRsZT0i5Zue5Yiw6aG26YOoIj48aSBjbGFzcz0iZmEgZmEtYXJyb3ctdXAgZmEtbGciPjwvaT48L2E+DQogICAge3tTZXR0aW5nIGBjX2Zvb3Rlcl9nYWAgfCBIdG1sfX0NCjwvZm9vdGVyPg0KPHNjcmlwdCBzcmM9Ii9zdGF0aWMvanMvaG9tZS5qcyI+PC9zY3JpcHQ+DQo8L2JvZHk+DQo8L2h0bWw+DQp7e0h0bWwgIjwhLS0gdGhhbmtzIGZvciB0aGVtZSBMaW5nb25iZXJyeShodHRwOi8vd3d3LmFuZGVyc25vcmVuLnNlLykgZm9yIFdvcmRQcmVzcy0tPiJ9fVBLBwgtIoo+wwgAAMMIAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABQAAAB2aWV3XGxpbmdcaW5kZXguaHRtbDxkaXYgaWQ9ImFydGljbGUtY29udGFpbmVyIiBjbGFzcz0iY2xlYXIiPnt7cmFuZ2UgLkFydGljbGVzfX0NCiAgICA8YXJ0aWNsZSBjbGFzcz0iY2xlYXIge3suU3RhdHVzfX0iIGlkPSJhcnRpY2xlLXt7LklkfX0iPg0KICAgICAgICA8ZGl2IGNsYXNzPSJtZXRhIGxlZnQgdGV4dC1jZW50ZXIgcmVsYXRpdmUiPg0KICAgICAgICAgICAgPHAgY2xhc3M9ImxibCBsYmwtcmVkIGNvbW1lbnRzIj48YSBocmVmPSJ7ey5MaW5rfX0jY29tbWVudCI+e3suQ29tbWVudE51bX19PC9hPjwvcD4NCiAgICAgICAgICAgIDxwIGNsYXNzPSJsYmwgbGJsLWdyZWVuIHZpZXdzIGFic29sdXRlIj57ey5IaXRzfX08L3A+DQogICAgICAgIDwvZGl2Pg0KICAgICAgICA8ZGl2IGNsYXNzPSJtYWluIHJlbGF0aXZlIj4NCiAgICAgICAgICAgIDxoMyBjbGFzcz0idGl0bGUiPjxhIGhyZWY9Int7Lkxpbmt9fSIgdGl0bGU9Int7LlRpdGxlfX0iPnt7LlRpdGxlfX08L2E+PC9oMz4NCiAgICAgICAgICAgIDxwIGNsYXNzPSJ0aW1lLWluZm8iPnt7aWYgLlVzZXJ9fTxzdHJvbmc+e3suVXNlci5OaWNrfX08L3N0cm9uZz4mbmJzcDsmbmJzcDsmbmJzcDt7e2VuZH195Y+R6KGo5LqOJm5ic3A7Jm5ic3A7Jm5ic3A7e3tEYXRlSW50NjQgLkNyZWF0ZVRpbWUgIllZWVkg5bm0IE1NIOaciCBERCDml6UifX08L3A+DQogICAgICAgICAgICA8c2VjdGlvbiBjbGFzcz0iY29udGVudCBtYXJrZG93biI+e3tIdG1sIC5TdW1tYXJ5fX08L3NlY3Rpb24+DQogICAgICAgICAgICA8cCBjbGFzcz0iaW5mbyBjbGVhciI+DQogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9InRhZyBpbmxpbmUtYmxvY2siPuagh+etvu+8mnt7cmFuZ2UgLkdldFRhZ3N9fTxhIGhyZWY9Int7Lkxpbmt9fSI+e3suTmFtZX19PC9hPnt7ZW5kfX08L3NwYW4+DQogICAgICAgICAgICAgICAgPGEgY2xhc3M9ImlubGluZS1ibG9jayByZWFkIHJpZ2h0IiBocmVmPSJ7ey5MaW5rfX0iPue7p+e7remYheivuzwvYT4NCiAgICAgICAgICAgIDwvcD4NCiAgICAgICAgPC9kaXY+DQogICAgPC9hcnRpY2xlPnt7ZW5kfX0NCiAgICA8ZGl2IGNsYXNzPSJwYWdlciB0ZXh0LWNlbnRlciIgaWQ9ImFydGljbGUtcGFnZXIiPg0KICAgICAgICB7e2lmIC5QYWdlci5Jc05leHR9fTxhIGhyZWY9Ii9wL3t7LlBhZ2VyLk5leHR9fS8iIGNsYXNzPSJpdGVtIGxlZnQiPui+g+aXp+eahOaWh+eroDwvYT57e2VuZH19DQogICAgICAgIHt7aWYgLlBhZ2VyLklzUHJldn19PGEgaHJlZj0iL3Ave3suUGFnZXIuUHJldn19LyIgY2xhc3M9Iml0ZW0gcmlnaHQiPui+g+aWsOeahOaWh+eroDwvYT57e2VuZH19DQogICAgPC9kaXY+DQo8L2Rpdj5QSwcIEfdx1DIFAAAy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PGRpdiBjbGFzcz0iY29tbWVudCBjbGVhciIgaWQ9ImNvbW1lbnQte3suSWR9fSI+DQogICAgICAgICAgICA8aW1nIGNsYXNzPSJjLWF2YXRhciBsZWZ0IiBzcmM9Int7LkF2YXRhcn19IiBhbHQ9Int7LkF1dGhvcn19Ii8+DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXNlY3Rpb24iPg0KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImMtbWV0YSBjbGVhciI+DQogICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJjLXJlcGx5IGxibCByaWdodCIgaHJlZj0iIyIgcmVsPSJ7ey5JZH19Ij7lm57lpI08L2E+DQogICAgICAgICAgICAgICAgICAgIDxwPjxhIGNsYXNzPSJjLWF1dGhvcnt7aWYgLklzQWRtaW59fSBhZG1pbnt7ZW5kfX0iIGhyZWY9Int7LlVybH19IiB0YXJnZXQ9Il9ibGFuayI+e3suQXV0aG9yfX17e2lmIC5Jc0FkbWlufX0mbmJzcDsmbmJzcDsoYWRtaW4pe3tlbmR9fTwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgIDxwPjxzcGFuIGNsYXNzPSJjLXRpbWUiPnt7RGF0ZUludDY0IC5DcmVhdGVUaW1lICJNTSDmnIggREQg5pelIEhIIOaXtiBtbSDliIYifX08L3NwYW4+PC9wPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxzZWN0aW9uIGNsYXNzPSJjLWNvbnRlbnQiPnt7SHRtbCAuQ29udGVudH19PC9zZWN0aW9uPnt7aWYgLlBhcmVudE1kfX0NCiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJjLXAtbWQgbWFya2Rvd24iPnt7SHRtbCAuUGFyZW50TWR9fTwvZGl2Pnt7ZW5kfX0NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj57e2VuZH19e3tlbmR9fQ0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImNvbW1lbnQtc2hvdyIgY2xhc3M9InRleHQtY2VudGVyIj57e2lmIC5Db250ZW50LklzQ29tbWVudH19DQogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tZ3JlZW4gZW5hYmxlIj7lj5Hooajor4Torro8L2J1dHRvbj57e2Vsc2V9fQ0KICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXJlZCI+5pys5paH5YWz6Zet5LqG6K+E6K66PC9idXR0b24+e3tlbmR9fQ0KICAgIDwvZGl2Pnt7aWYgLkNvbnRlbnQuSXNDb21tZW50fX0NCiAgICA8Zm9ybSBpZD0iY29tbWVudC1mb3JtIiBjbGFzcz0iaGlkZSBjbGVhciB0ZXh0LWNlbnRlciBmb3JtIiBhY3Rpb249Ii9jb21tZW50L3t7LkNvbnRlbnQuSWR9fS8iIG1ldGhvZD0icG9zdCI+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtaW5mbyBsZWZ0IHRleHQtcmlnaHQiPg0KICAgICAgICAgICAgPHAgY2xhc3M9Iml0ZW0gYy1hdmF0YXItZmllbGQiPg0KICAgICAgICAgICAgICAgIDxpbWcgY2xhc3M9ImMtYXZhdGFyIG51bGwiIHNyYz0iL3N0YXRpYy9pbWcvc2l0ZS5wbmciIGFsdD0iIiBpZD0iY29tbWVudC1hdmF0YXIiLz4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0ibm90LW1lIGJsb2NrIiBocmVmPSIjIj7kuI3mmK/miJE/PC9hPg0KICAgICAgICAgICAgPC9wPg0KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1pbmZvLWZpZWxkcyBoaWRlIj4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InRleHQiIG5hbWU9InVzZXIiIHJlcXVpcmVkPSJyZXF1aXJlZCIgcGxhY2Vob2xkZXI9IuensOWRvCIgaWQ9ImNvbW1lbnQtYXV0aG9yIi8+PC9wPg0KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJpdGVtIj48aW5wdXQgY2xhc3M9ImlwdCIgdHlwZT0iZW1haWwiIG5hbWU9ImVtYWlsIiByZXF1aXJlZD0icmVxdWlyZWQiIHBsYWNlaG9sZGVyPSLpgq7nrrEiIGlkPSJjb21tZW50LWVtYWlsIi8+IDwvcD4NCiAgICAgICAgICAgICAgICA8cCBjbGFzcz0iaXRlbSI+PGlucHV0IGNsYXNzPSJpcHQiIHR5cGU9InVybCIgbmFtZT0idXJsIiBwbGFjZWhvbGRlcj0i572R5Z2AIiBpZD0iY29tbWVudC11cmwiLz48L3A+DQogICAgICAgICAgICAgICAgPGlucHV0IGlkPSJjb21tZW50LXBhcmVudCIgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iMCIgbmFtZT0icGlkIi8+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgY2xhc3M9ImMtY29udGVudCB0ZXh0LWxlZnQgcmlnaHQiPg0KICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPSJpcHQiIG5hbWU9ImNvbnRlbnQiIGlkPSJjb21tZW50LWNvbnRlbnQiIHJlcXVpcmVkPSJyZXF1aXJlZCI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4tYmx1ZSI+5Y+R6KGo6K+E6K66PC9idXR0b24+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJsYmwgbGJsLWdyZWVuIGNhbmNlbC1yZXBseSIgdHlwZT0iYnV0dG9uIj7lj5bmtojlm57lpI08L2J1dHRvbj4NCiAgICAgICAgPC9kaXY+DQogICAgPC9mb3JtPnt7ZW5kfX0NCiAgICA8c2NyaXB0IHR5cGU9InRleHQvdGVtcGxhdGUiIGlkPSJjb21tZW50LXRwbCI+DQogICAgICAgIDxkaXYgY2xhc3M9ImNvbW1lbnQgY2xlYXIiPg0KICAgICAgICAgICAgPGltZyBjbGFzcz0iYy1hdmF0YXIgbGVmdCIgc3JjPSJ7ey5BdmF0YXJ9fSIgYWx0PSIiLz4NCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImMtc2VjdGlvbiI+DQogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iYy1tZXRhIGNsZWFyIj4NCiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9ImMtcmVwbHkgbGJsIHJpZ2h0IiBocmVmPSIjIiByZWw9IiI+5Zue5aSNPC9hPg0K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dGl0bGU+DQogICAgPG1ldGEgbmFtZT0ia2V5d29yZHMiIGNvbnRlbnQ9Int7U2V0dGluZyBgc2l0ZV9rZXl3b3Jkc2B9fSIvPg0KICAgIDxtZXRhIG5hbWU9ImRlc2NyaXB0aW9uIiBjb250ZW50PSJ7e1NldHRpbmcgYHNpdGVfZGVzY3JpcHRpb25gfX0iLz4NCiAgICA8bWV0YSBuYW1lPSJnZW5lcmF0b3IiIGNvbnRlbnQ9IkZ4aEdvIEJsb2ciIC8+DQogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvc3RhdGljL2Nzcy9zYWJlci5jc3MiLz4NCiAgICA8bGluayByZWw9ImFsdGVybmF0ZSIgdHlwZT0iYXBwbGljYXRpb24vcnNzK3htbCIgdGl0bGU9Int7U2V0dGluZyBgc2l0ZV90aXRsZWB9fSAtIFJTUyAyLjAiIGhyZWY9Ii9mZWVkLyIvPg0KICAgIDxzY3JpcHQgc3JjPSJodHRwOi8vbGlicy5iYWlkdS5jb20vanF1ZXJ5LzEuOC4zL2pxdWVyeS5taW4uanMiPjwvc2NyaXB0Pg0KICAgIDxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9qcXVlcnkuZm9ybS5taW4uanMiPjwvc2NyaXB0Pg0KICAgIDxzY3JpcHQgc3JjPSIvc3RhdGljL2xpYi9tYXJrZWQubWluLmpzIj48L3NjcmlwdD4NCjwvaGVhZD4NCjxib2R5Pg0KPGhlYWRlciBpZD0iaGVhZGVyIj4NCiAgICA8ZGl2IGNsYXNzPSJjb250YWluZXIgY2xlYXIiPg0KICAgICAgICA8aW1nIHNyYz0ie3tTZXR0aW5nIGBjX2hvbWVfYXZhdGFyYH19IiBhbHQ9InNpdGUiIGlkPSJoZWFkZXItaW1nIiBjbGFzcz0ibGVmdCIvPg0KICAgICAgICA8aDEgaWQ9ImhlYWRlci1oIiBjbGFzcz0ibGVmdCI+PGEgaHJlZj0iLyI+e3tTZXR0aW5nICJzaXRlX3RpdGxlIn19PC9hPjwvaDE+DQogICAgICAgIDxoNCBpZD0iaGVhZGVyLXN1YiIgY2xhc3M9ImxlZnQiPnt7U2V0dGluZyAic2l0ZV9zdWJfdGl0bGUifX08L2g0Pg0KICAgICAgICA8bmF2IGlkPSJuYXYiIGNsYXNzPSJyaWdodCI+DQogICAgICAgICAgICA8dWw+e3tyYW5nZSBOYXZpZ2F0b3J9fQ0KICAgICAgICAgICAgICAgIDxsaSBjbGFzcz0iaW5saW5lLWJsb2NrIj48YSBocmVmPSJ7ey5MaW5rfX0iIHRpdGxlPSJ7ey5UaXRsZX19Ij57ey5UZXh0fX08L2E+PC9saT57e2VuZH19DQogICAgICAgICAgICA8L3VsPg0KICAgICAgICA8L25hdj4NCiAgICA8L2Rpdj4NCjwvaGVhZGVyPg0KPGRpdiBpZD0ibWFpbiIgY2xhc3M9ImNvbnRhaW5lciBncmlkIGNsZWFyIHJlbGF0aXZlIj4NCiAgICB7QENvbnRlbnR9DQo8L2Rpdj4NCjxmb290ZXIgaWQ9ImZvb3RlciIgY2xhc3M9InRleHQtY2VudGVyIj4NCiAgICA8ZGl2IGNsYXNzPSJjb250YWluZXIgY2xlYXIiPg0KICAgICAgICA8c3BhbiBjbGFzcz0ibGVmdCI+R28gwqkgMjAxNCBBbGwgcmlnaHRzIHJlc2VydmVkLjwvc3Bhbj4NCiAgICAgICAgPHNwYW4gY2xhc3M9InJpZ2h0Ij4NCiAgICAgICAgICAgIDxhIGhyZWY9Int7U2V0dGluZyBgY19mb290ZXJfZ2l0aHViYH19IiB0YXJnZXQ9Il9ibGFuayI+R2l0SHViPC9hPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgPGEgaHJlZj0iL2ZlZWQvIj5GZWVkPC9hPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KICAgICAgICAgICAgUHJvdWRseSBQb3dlcmVkIGJ5IEZ4aC5Hby4NCiAgICAgICAgPC9zcGFuPg0KICAgIDwvZGl2Pg0KICAgIDxhIGlkPSJnby10b3AiIGhyZWY9IiMiIGNsYXNzPSJsYmwgaGlkZSBsYmwtYmx1ZSIgdGl0bGU9IuWbnuWIsOmhtumDqCI+VG9wPC9hPg0KICAgIHt7U2V0dGluZyBgY19mb290ZXJfZ2FgIHwgSHRtbH19DQo8L2Zvb3Rlcj4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2pzL2hvbWUuanMiPjwvc2NyaXB0Pg0KPC9ib2R5Pg0KPC9odG1sPlBLBwicL8xQRwgAAEcIAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABUAAAB2aWV3XHNhYmVyXGluZGV4Lmh0bWw8ZGl2IGlkPSJhcnRpY2xlLWNvbnRhaW5lciIgY2xhc3M9ImNsZWFyIGdyaWQtMy00IGxlZnQiPnt7aWYgLlRhZ319DQogICAgPGRpdiBjbGFzcz0idGFnLWJhbm5lciI+5qCH562+77yae3suVGFnfX08L2Rpdj57e2VuZH19e3tyYW5nZSAuQXJ0aWNsZXN9fQ0KICAgIDxhcnRpY2xlIGNsYXNzPSJjbGVhciB7ey5TdGF0dXN9fSIgaWQ9ImFydGljbGUte3suSWR9fSI+DQogICAgICAgIDxkaXYgY2xhc3M9Im1ldGEgbGVmdCB0ZXh0LWNlbnRlciByZWxhdGl2ZSI+DQogICAgICAgICAgICA8cCBjbGFzcz0ibGJsIGxibC1yZWQgY29tbWVudHMiPjxhIGhyZWY9Int7Lkxpbmt9fSNjb21tZW50Ij57ey5Db21tZW50TnVtfX08L2E+PC9wPg0KICAgICAgICAgICAgPHAgY2xhc3M9ImxibCBsYmwtZ3JlZW4gdmlld3MgYWJzb2x1dGUiPnt7LkhpdHN9fTwvcD4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgY2xhc3M9Im1haW4iPg0KICAgICAgICAgICAgPGgzIGNsYXNzPSJ0aXRsZSI+PGEgaHJlZj0ie3suTGlua319IiB0aXRsZT0ie3suVGl0bGV9fSI+e3suVGl0bGV9fTwvYT48L2gzPg0KICAgICAgICAgICAgPHNlY3Rpb24gY2xhc3M9ImNvbnRlbnQgbWFya2Rvd24iPnt7SHRtbCAuU3VtbWFyeX19PC9zZWN0aW9uPg0KICAgICAgICAgICAgPHAgY2xhc3M9ImluZm8gY2xlYXIiPg0KICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJ0aW1lLWluZm8iPnt7aWYgLlVzZXJ9fTxzdHJvbmc+e3suVXNlci5OaWNrfX08L3N0cm9uZz4mbmJzcDsmbmJzcDsmbmJzcDt7e2VuZH195Y+R6KGo5LqOJm5ic3A7Jm5ic3A7Jm5ic3A7e3tEYXRlSW50NjQgLkNyZWF0ZVRpbWUgIllZWVkg5bm0IE1NIOaciCBERCDml6UifX08L3NwYW4+DQogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9InRhZyI+5qCH562+77yae3tyYW5nZSAuR2V0VGFnc319PGEgaHJlZj0ie3suTGlua319Ij57ey5OYW1lfX08L2E+e3tlbmR9fTwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8YSBjbGFzcz0iaW5saW5lLWJsb2NrIHJlYWQgcmlnaHQiIGhyZWY9Int7Lkxpbmt9fSI+57un57ut6ZiF6K+7PC9hPg0KICAgICAgICAgICAgPC9wPg0KICAgICAgICA8L2Rpdj4NCiAgICA8L2FydGljbGU+e3tlbmR9fQ0KICAgIDxkaXYgY2xhc3M9InBhZ2VyIHRleHQtY2VudGVyIiBpZD0iYXJ0aWNsZS1wYWdlciI+DQogICAgICAgIHt7aWYgLlBhZ2VyLklzTmV4dH19PGEgaHJlZj0iL3Ave3suUGFnZXIuTmV4dH19LyIgY2xhc3M9Iml0ZW0gbGVmdCI+6L6D5pen55qE5paH56ugPC9hPnt7ZW5kfX0NCiAgICAgICAge3tpZiAuUGFnZXIuSXNQcmV2fX08YSBocmVmPSIvcC97ey5QYWdlci5QcmV2fX0vIiBjbGFzcz0iaXRlbSByaWdodCI+6L6D5paw55qE5paH56ugPC9hPnt7ZW5kfX0NCiAgICA8L2Rpdj4NCjwvZGl2Pg0Ke3tIdG1sIC5TaWRlYmFySHRtbH19UEsHCO4la4+SBQAAkgUAAFBLAwQUAAgAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAHZpZXdcc2FiZXJccGFnZS5odG1sPGRpdiBpZD0iYXJ0aWNsZS1jb250YWluZXIiIGNsYXNzPSJjbGVhciBjb250YWluZXI5NjAiPg0KICAgIDxhcnRpY2xlIGNsYXNzPSJjbGVhciBhcnRpY2xlLXNpbmdsZSByZWxhdGl2ZSIgaWQ9ImFydGljbGUte3suUGFnZS5JZH19Ij57e3dpdGggLlBhZ2V9fQ0KICAgICAgICA8ZGl2IGNsYXNzPSJtYWluIGNsZWFyIj4NCiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJpbmxpbmUtYmxvY2sgbGJsIGxibC1ncmVlbiB2aWV3cyByaWdodCB0ZXh0LWNlbnRlciI+e3suSGl0c319PC9zcGFuPg0KICAgICAgICAgICAgPGgzIGNsYXNzPSJ0aXRsZSI+PGEgaHJlZj0ie3suTGlua319IiB0aXRsZT0ie3suVGl0bGV9fSI+e3suVGl0bGV9fTwvYT48L2gzPg0KICAgICAgICAgICAgPHNlY3Rpb24gY2xhc3M9ImNvbnRlbnQgbWFya2Rvd24iPnt7SHRtbCAuQ29udGVudH19PC9zZWN0aW9uPg0KICAgICAgICAgICAgPHAgY2xhc3M9ImluZm8gY2xlYXIiPg0KICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJ0aW1lLWluZm8iPnt7aWYgLlVzZXJ9fTxzdHJvbmc+e3suVXNlci5OaWNrfX08L3N0cm9uZz4mbmJzcDsmbmJzcDsmbmJzcDt7e2VuZH195Y+R6KGo5LqOJm5ic3A7Jm5ic3A7Jm5ic3A7e3tEYXRlSW50NjQgLkNyZWF0ZVRpbWUgIllZWVkg5bm0IE1NIOaciCBERCDml6UifX08L3NwYW4+DQogICAgICAgICAgICA8L3A+DQogICAgICAgIDwvZGl2Pnt7ZW5kfX0NCiAgICA8L2FydGljbGU+DQo8L2Rpdj5QSwcI242T7eECAADhAgAAUEsDBBQACAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAdmlld1xzYWJlclxzaWRlYmFyLmh0bWw8ZGl2IGlkPSJhcnRpY2xlLXNpZGViYXIiIGNsYXNzPSJncmlkLTEtNSByaWdodCI+DQogICAgPGRpdiBjbGFzcz0ic2lkZWJhciIgaWQ9InBvcC1hcnRpY2xlLXNpZGViYXIiPg0KICAgICAgICA8aDUgY2xhc3M9InRpdGxlIj7ng63or4Tmlofnq6A8L2g1Pg0KICAgICAgICA8dWwgY2xhc3M9Imxpc3QiPnt7cmFuZ2UgLlBvcHVsYXJ9fQ0KICAgICAgICAgICAgPGxpPg0KICAgICAgICAgICAgICAgIDxhIGhyZWY9Int7Lkxpbmt9fSIgdGl0bGU9Int7LlRpdGxlfX0iPnt7LlRpdGxlfX08L2E+DQogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9InBvcC1udW0gbGJsIj57ey5Db21tZW50TnVtfX08L3NwYW4+DQogICAgICAgICAgICA8L2xpPnt7ZW5kfX0NCiAgICAgICAgPC91bD4NCiAgICA8L2Rpdj4NCiAgICA8ZGl2IGNsYXNzPSJzaWRlYmFyIiBpZD0icmVjZW50LWNvbW1lbnQtc2lkZWJhciI+DQogICAgICAgIDxoNSBjbGFzcz0idGl0bGUiPuacgOaWsOivhOiuujwvaDU+DQogICAgICAgIDx1bCBjbGFzcz0ibGlzdCI+e3tyYW5nZSAuUmVjZW50Q29tbWVudH19DQogICAgICAgICAgICA8bGk+DQogICAgICAgICAgICAgICAgPGEgY2xhc3M9ImF1dGhvciBsYmwgbGJsLWJsdWUiIGhyZWY9Int7LkdldENvbnRlbnQuTGlua319I2NvbW1lbnQte3suSWR9fSI+e3suQXV0aG9yfX08L2E+DQogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImNvbnRlbnQiPnt7SHRtbDJzdHIgLkNvbnRlbnR9fTwvc3Bhbj4NCiAgICAgICAgICAgIDwvbGk+e3tlbmR9fQ0KICAgICAgICA8L3VsPg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9InNpZGViYXIiIGlkPSJ0YWdzLXNpZGViYXIiPg0KICAgICAgICA8aDUgY2xhc3M9InRpdGxlIj7mlofnq6DmoIfnrb48L2g1Pg0KICAgICAgICA8dWwgY2xhc3M9Imxpc3QiPnt7cmFuZ2UgLlRhZ3N9fQ0KICAgICAgICAgICAgPGxpIGNsYXNzPSJpbmxpbmUtYmxvY2siPg0KICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJhdXRob3IgbGJsIGxibC1ncmVlbiIgaHJlZj0ie3suTGlua319Ij57ey5OYW1lfX08L2E+DQogICAgICAgICAgICA8L2xpPnt7ZW5kfX0NCiAgICAgICAgPC91bD4NCiAgICA8L2Rpdj4NCjwvZGl2PlBLBwjtVDa6VQQAAFUEAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAAAB2aWV3XHNpdGVtYXAueG1se3tIdG1sIGA8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PmB9fXt7SHRtbCBgPD94bWwtc3R5bGVzaGVldCB0eXBlPSJ0ZXh0L3hzbCIgaHJlZj0iL3N0YXRpYy9jc3Mvc2l0ZW1hcC54c2wiPz5gfX0NCjx1cmxzZXQgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45IGh0dHA6Ly93d3cuc2l0ZW1hcHMub3JnL3NjaGVtYXMvc2l0ZW1hcC8wLjkvc2l0ZW1hcC54c2QiIHhtbG5zPSJodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45Ij4NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPmRhaWx5PC9jaGFuZ2VmcmVxPg0KICAgICAgICA8cHJpb3JpdHk+MS4wPC9wcmlvcml0eT4NCiAgICA8L3VybD57e3JhbmdlIC5OYXZpZ2F0b3JzfX0NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPndlZWtseTwvY2hhbmdlZnJlcT4NCiAgICAgICAgPHByaW9yaXR5PjAuNjwvcHJpb3JpdHk+DQogICAgPC91cmw+e3tlbmR9fXt7cmFuZ2UgLkFydGljbGVzfX0NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPm1vbnRobHk8L2NoYW5nZWZyZXE+DQogICAgICAgIDxwcmlvcml0eT4wLjM8L3ByaW9yaXR5Pg0KICAgIDwvdXJsPnt7ZW5kfX0NCjwvdXJsc2V0PlBLBwgkMJGCpgMAAKYDAABQ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" ================================================ FILE: app/cmd.go ================================================ package app import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoBlog/app/handler" _ "github.com/fuxiaohei/GoBlog/app/upgrade" "os" ) // Cmd starts command line application. // It captures command line arguments and executes proper operation. // Some operations will exit application when finished. func Cmd() { args := os.Args if len(args) > 1 { switch args[1] { case "install": cmd.DoInstall() case "update": file, _ := cmd.DoBackup(App, false) cmd.DoUpdateZipBytes(file) case "backup": cmd.DoBackup(App, true) case "upgrade": cmd.DoUpgrade(VERSION, App) } os.Exit(1) } // do install and run server together if !cmd.CheckInstall() { cmd.DoInstall() return } // check app version if cmd.CheckUpgrade(VERSION, true) { os.Exit(1) return } // begin cmd init cmd.Init(App) } func registerCmdHandler() { App.Route("GET,POST,DELETE", "/cmd/backup/", handler.Auth, handler.CmdBackup) App.Get("/cmd/backup/file/", handler.Auth, handler.CmdBackupFile) App.Route("GET,POST,DELETE", "/cmd/message/", handler.Auth, handler.CmdMessage) App.Route("GET,DELETE", "/cmd/logs/", handler.Auth, handler.CmdLogs) App.Get("/cmd/monitor/", handler.Auth, handler.CmdMonitor) App.Route("GET,POST", "/cmd/theme/", handler.Auth, handler.CmdTheme) App.Route("GET,POST", "/cmd/reader/", handler.Auth, handler.CmdReader) } ================================================ FILE: app/handler/admin.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/plugin" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" "strconv" "strings" ) func Admin(context *GoInk.Context) { uid, _ := strconv.Atoi(context.Cookie("token-user")) user := model.GetUserById(uid) context.Layout("admin/admin") context.Render("admin/home", map[string]interface{}{ "Title": "控制台", "Statis": model.NewStatis(), "User": user, "Messages": model.GetUnreadMessages(), }) } func AdminProfile(context *GoInk.Context) { uid, _ := strconv.Atoi(context.Cookie("token-user")) user := model.GetUserById(uid) if context.Method == "POST" { data := context.Input() if !user.ChangeEmail(data["email"]) { Json(context, false).Set("msg", "邮箱与别的用户重复").End() return } user.Name = data["user"] user.Email = data["email"] user.Avatar = utils.Gravatar(user.Email, "180") user.Url = data["url"] user.Nick = data["nick"] user.Bio = data["bio"] Json(context, true).End() go model.SyncUsers() go model.UpdateCommentAdmin(user) context.Do("profile_update", user) return } context.Layout("admin/admin") context.Render("admin/profile", map[string]interface{}{ "Title": "个性资料", "User": user, }) } func AdminPassword(context *GoInk.Context) { if context.Method == "POST" { uid, _ := strconv.Atoi(context.Cookie("token-user")) user := model.GetUserById(uid) if !user.CheckPassword(context.String("old")) { Json(context, false).Set("msg", "旧密码错误").End() return } user.ChangePassword(context.String("new")) go model.SyncUsers() Json(context, true).End() context.Do("password_update", user) return } context.Layout("admin/admin") context.Render("admin/password", map[string]interface{}{ "Title": "修改密码", //"User":user, }) } func AdminArticle(context *GoInk.Context) { articles, pager := model.GetArticleList(context.Int("page"), 10) context.Layout("admin/admin") context.Render("admin/articles", map[string]interface{}{ "Title": "文章", "Articles": articles, "Pager": pager, }) } func ArticleWrite(context *GoInk.Context) { if context.Method == "POST" { c := new(model.Content) c.Id = 0 data := context.Input() if !c.ChangeSlug(data["slug"]) { Json(context, false).Set("msg", "固定链接重复").End() return } c.Title = data["title"] c.Text = data["content"] c.Tags = strings.Split(strings.Replace(data["tag"], ",", ",", -1), ",") c.IsComment = data["comment"] == "1" c.IsLinked = false c.AuthorId, _ = strconv.Atoi(context.Cookie("token-user")) c.Template = "blog.html" c.Status = data["status"] c.Format = "markdown" c.Hits = 1 var e error c, e = model.CreateContent(c, "article") if e != nil { Json(context, false).Set("msg", e.Error()).End() return } Json(context, true).Set("content", c).End() context.Do("article_created", c) //c.Type = "article" return } context.Layout("admin/admin") context.Render("admin/write_article", map[string]interface{}{ "Title": "撰写文章", }) } func ArticleEdit(context *GoInk.Context) { id, _ := strconv.Atoi(context.Param("id")) c := model.GetContentById(id) if c == nil { context.Redirect("/admin/articles/") return } if context.Method == "DELETE" { model.RemoveContent(c) Json(context, true).End() return } if context.Method == "POST" { data := context.Input() if !c.ChangeSlug(data["slug"]) { Json(context, false).Set("msg", "固定链接重复").End() return } c.Title = data["title"] c.Text = data["content"] c.Tags = strings.Split(strings.Replace(data["tag"], ",", ",", -1), ",") c.IsComment = data["comment"] == "1" //c.IsLinked = false //c.AuthorId, _ = strconv.Atoi(context.Cookie("token-user")) //c.Template = "blog.html" c.Status = data["status"] //c.Format = "markdown" model.SaveContent(c) Json(context, true).Set("content", c).End() context.Do("article_modified", c) //c.Type = "article" return } context.Layout("admin/admin") context.Render("admin/edit_article", map[string]interface{}{ "Title": "编辑文章", "Article": c, }) } func PageWrite(context *GoInk.Context) { if context.Method == "POST" { c := new(model.Content) c.Id = 0 data := context.Input() if !c.ChangeSlug(data["slug"]) { Json(context, false).Set("msg", "固定链接重复").End() return } c.Title = data["title"] c.Text = data["content"] c.Tags = make([]string, 0) c.IsComment = data["comment"] == "1" c.IsLinked = data["link"] == "1" c.AuthorId, _ = strconv.Atoi(context.Cookie("token-user")) c.Template = "page.html" c.Status = data["status"] c.Format = "markdown" c.Hits = 1 var e error c, e = model.CreateContent(c, "page") if e != nil { Json(context, false).Set("msg", e.Error()).End() return } Json(context, true).Set("content", c).End() //c.Type = "article" context.Do("page_created", c) return } context.Layout("admin/admin") context.Render("admin/write_page", map[string]interface{}{ "Title": "撰写页面", }) } func AdminPage(context *GoInk.Context) { pages, pager := model.GetPageList(context.Int("page"), 10) context.Layout("admin/admin") context.Render("admin/pages", map[string]interface{}{ "Title": "页面", "Pages": pages, "Pager": pager, }) } func PageEdit(context *GoInk.Context) { id, _ := strconv.Atoi(context.Param("id")) c := model.GetContentById(id) if c == nil { context.Redirect("/admin/pages/") return } if context.Method == "DELETE" { model.RemoveContent(c) Json(context, true).End() return } if context.Method == "POST" { data := context.Input() if !c.ChangeSlug(data["slug"]) { Json(context, false).Set("msg", "固定链接重复").End() return } c.Title = data["title"] c.Text = data["content"] //c.Tags = strings.Split(strings.Replace(data["tag"], ",", ",", -1), ",") c.IsComment = data["comment"] == "1" c.IsLinked = data["link"] == "1" //c.AuthorId, _ = strconv.Atoi(context.Cookie("token-user")) //c.Template = "blog.html" c.Status = data["status"] //c.Format = "markdown" model.SaveContent(c) Json(context, true).Set("content", c).End() context.Do("page_modified", c) //c.Type = "article" return } context.Layout("admin/admin") context.Render("admin/edit_page", map[string]interface{}{ "Title": "编辑文章", "Page": c, }) } func AdminSetting(context *GoInk.Context) { if context.Method == "POST" { data := context.Input() for k, v := range data { if v == "" { if data[k+"_def"] != "" { v = data[k+"_def"] } } model.SetSetting(k, v) } model.SyncSettings() Json(context, true).End() context.Do("setting_saved") return } context.Layout("admin/admin") context.Render("admin/setting", map[string]interface{}{ "Title": "配置", "Custom": model.GetCustomSettings(), "Navigators": model.GetNavigators(), }) } func CustomSetting(context *GoInk.Context) { keys := context.Strings("key") values := context.Strings("value") for i, k := range keys { if len(k) < 1 { continue } model.SetSetting("c_"+k, values[i]) } model.SyncSettings() Json(context, true).End() context.Do("setting_saved") return } func NavigatorSetting(context *GoInk.Context) { order := context.Strings("order") text := context.Strings("text") title := context.Strings("title") link := context.Strings("link") model.SetNavigators(order, text, title, link) Json(context, true).End() context.Do("setting_saved") return } func AdminComments(context *GoInk.Context) { if context.Method == "DELETE" { id := context.Int("id") cmt := model.GetCommentById(id) model.RemoveComment(cmt.Cid, id) Json(context, true).End() context.Do("comment_delete", id) return } if context.Method == "PUT" { id := context.Int("id") cmt2 := model.GetCommentById(id) cmt2.Status = "approved" cmt2.GetReader().Active = true model.SaveComment(cmt2) Json(context, true).End() context.Do("comment_change_status", cmt2) return } if context.Method == "POST" { // get required data pid := context.Int("pid") cid := model.GetCommentById(pid).Cid uid, _ := strconv.Atoi(context.Cookie("token-user")) user := model.GetUserById(uid) co := new(model.Comment) co.Author = user.Nick co.Email = user.Email co.Url = user.Url co.Content = context.String("content") co.Avatar = utils.Gravatar(co.Email, "50") co.Pid = pid co.Ip = context.Ip co.UserAgent = context.UserAgent co.IsAdmin = true model.CreateComment(cid, co) Json(context, true).Set("comment", co.ToJson()).End() model.CreateMessage("comment", co) context.Do("comment_reply", co) return } page := context.IntOr("page", 1) comments, pager := model.GetCommentList(page, 10) context.Layout("admin/admin") context.Render("admin/comments", map[string]interface{}{ "Title": "评论", "Comments": comments, "Pager": pager, }) } func AdminPlugin(context *GoInk.Context) { if context.Method == "POST" { action := context.String("action") if action == "" { Json(context, false).End() return } pln := context.String("plugin") if action == "activate" { plugin.Activate(pln) plugin.Update(context.App()) Json(context, true).End() context.Do("plugin_activated", pln) return } if action == "deactivate" { plugin.Deactivate(pln) Json(context, true).End() context.Do("plugin_deactivated", pln) return } context.Status = 405 Json(context, false).End() return } context.Layout("admin/admin") context.Render("admin/plugin", map[string]interface{}{ "Title": "插件", "Plugins": plugin.GetPlugins(), }) } func PluginSetting(context *GoInk.Context) { key := context.Param("plugin_key") if key == "" { context.Redirect("/admin/plugins/") return } p := plugin.GetPluginByKey(key) if p == nil { context.Redirect("/admin/plugins/") return } if context.Method == "POST" { p.SetSetting(context.Input()) Json(context, true).End() context.Do("plugin_setting_saved", p) return } context.Layout("admin/admin") context.Render("admin/plugin_setting", map[string]interface{}{ "Title": "插件 - " + p.Name(), "Form": p.Form(), }) } func AdminMessageRead(context *GoInk.Context) { id := context.Int("id") if id < 0 { Json(context, false).End() return } m := model.GetMessage(id) if m == nil { Json(context, false).End() return } model.SaveMessageRead(m) Json(context, true).End() } ================================================ FILE: app/handler/cmd.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" ) func CmdBackup(context *GoInk.Context) { if context.Method == "POST" { file, e := cmd.DoBackup(context.App(), true) if e != nil { Json(context, false).Set("msg", e.Error()).End() return } Json(context, true).Set("file", file).End() context.Do("bakcup_success", file) model.CreateMessage("backup", "[1]"+file) return } if context.Method == "DELETE" { file := context.String("file") if file == "" { Json(context, false).End() return } cmd.RemoveBackupFile(file) Json(context, true).End() context.Do("backup_delete", file) return } files, _ := cmd.GetBackupFiles() context.Layout("admin/cmd") context.Render("admin/cmd/backup", map[string]interface{}{ "Files": files, "Title": "备份", }) } func CmdBackupFile(context *GoInk.Context) { file := context.String("file") context.Download(cmd.GetBackupFileAbsPath(file)) context.Do("backup_download", file) } func CmdMessage(context *GoInk.Context) { context.Layout("admin/cmd") context.Render("admin/cmd/message", map[string]interface{}{ "Title": "消息", "Messages": model.GetMessages(), }) } func CmdLogs(context *GoInk.Context) { if context.Method == "DELETE" { cmd.RemoveLogFile(context.App(), context.String("file")) Json(context, true).End() return } context.Layout("admin/cmd") context.Render("admin/cmd/log", map[string]interface{}{ "Title": "日志", "Logs": cmd.GetLogs(context.App()), }) } func CmdMonitor(ctx *GoInk.Context) { ctx.Layout("admin/cmd") ctx.Render("admin/cmd/monitor", map[string]interface{}{ "Title": "系统监控", "M": cmd.ReadMemStats(), }) } func CmdTheme(ctx *GoInk.Context) { if ctx.Method == "POST" { change := ctx.String("cache") if change != "" { cmd.SetThemeCache(ctx, change == "true") Json(ctx, true).End() return } theme := ctx.String("theme") if theme != "" { model.SetSetting("site_theme", theme) model.SyncSettings() Json(ctx, true).End() return } return } ctx.Layout("admin/cmd") ctx.Render("admin/cmd/theme", map[string]interface{}{ "Title": "主题", "Themes": cmd.GetThemes(ctx.App().Get("view_dir")), "CurrentTheme": model.GetSetting("site_theme"), }) } func CmdReader(ctx *GoInk.Context) { if ctx.Method == "POST" { email := ctx.String("email") model.RemoveReader(email) Json(ctx, true).End() return } ctx.Layout("admin/cmd") ctx.Render("admin/cmd/reader", map[string]interface{}{ "Title": "读者", "Readers": model.GetReaders(), }) } ================================================ FILE: app/handler/func.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "path" "strconv" ) type jsonContext struct { context *GoInk.Context data map[string]interface{} } // Json creates a json context response. func Json(context *GoInk.Context, res bool) *jsonContext { c := new(jsonContext) c.context = context c.data = make(map[string]interface{}) c.data["res"] = res return c } func (jc *jsonContext) Set(key string, v interface{}) *jsonContext { jc.data[key] = v return jc } func (jc *jsonContext) End() { jc.context.Json(jc.data) } type themeContext struct { context *GoInk.Context theme string } // Theme creates themed context response. func Theme(context *GoInk.Context) *themeContext { t := new(themeContext) t.context = context t.theme = model.GetSetting("site_theme") if t.theme == "" { t.theme = "default" } return t } func (tc *themeContext) Layout(layout string) *themeContext { if layout == "" { tc.context.Layout("") return tc } tc.context.Layout(path.Join(tc.theme, layout)) return tc } func (tc *themeContext) Render(tpl string, data map[string]interface{}) { tc.context.Render(path.Join(tc.theme, tpl), data) } func (tc *themeContext) Tpl(tpl string, data map[string]interface{}) string { return tc.context.Tpl(path.Join(tc.theme, tpl), data) } func (tc *themeContext) Has(tpl string) bool { file := path.Join(tc.theme, tpl) return tc.context.App().View().Has(file) } // CommentHtml returns rendered comment template html with own content. func CommentHtml(context *GoInk.Context, c *model.Content) string { thm := Theme(context) if !thm.Has("comment.html") { return "" } return thm.Tpl("comment", map[string]interface{}{ "Content": c, "Comments": c.Comments, }) } // SidebarHtml returns rendered sidebar template html. func SidebarHtml(context *GoInk.Context) string { thm := Theme(context) if !thm.Has("sidebar.html") { return "" } popSize, _ := strconv.Atoi(model.GetSetting("popular_size")) if popSize < 1 { popSize = 4 } cmtSize, _ := strconv.Atoi(model.GetSetting("recent_comment_size")) if cmtSize < 1 { cmtSize = 3 } return thm.Tpl("sidebar", map[string]interface{}{ "Popular": model.GetPopularArticleList(popSize), "RecentComment": model.GetCommentRecentList(cmtSize), "Tags": model.GetContentTags(), }) } ================================================ FILE: app/handler/home.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" "net/url" "strconv" "strings" ) func Login(context *GoInk.Context) { if context.Method == "POST" { data := context.Input() user := model.GetUserByName(data["user"]) if user == nil { Json(context, false).End() return } if !user.CheckPassword(data["password"]) { Json(context, false).End() return } exp := 3600 * 24 * 3 expStr := strconv.Itoa(exp) s := model.CreateToken(user, context, int64(exp)) context.Cookie("token-user", strconv.Itoa(s.UserId), expStr) context.Cookie("token-value", s.Value, expStr) Json(context, true).End() return } if context.Cookie("token-value") != "" { context.Redirect("/admin/") return } context.Render("admin/login", nil) } func Auth(context *GoInk.Context) { tokenValue := context.Cookie("token-value") token := model.GetTokenByValue(tokenValue) if token == nil { context.Redirect("/logout/") context.End() return } if !token.IsValid() { context.Redirect("/logout/") context.End() return } } func Logout(context *GoInk.Context) { context.Cookie("token-user", "", "-3600") context.Cookie("token-value", "", "-3600") context.Redirect("/login/") } func TagArticles(ctx *GoInk.Context) { ctx.Layout("home") page, _ := strconv.Atoi(ctx.Param("page")) tag, _ := url.QueryUnescape(ctx.Param("tag")) size := getArticleListSize() articles, pager := model.GetTaggedArticleList(tag, page, getArticleListSize()) // fix dotted tag if len(articles) < 1 && strings.Contains(tag, "-") { articles, pager = model.GetTaggedArticleList(strings.Replace(tag, "-", ".", -1), page, size) } Theme(ctx).Layout("home").Render("index", map[string]interface{}{ "Articles": articles, "Pager": pager, "SidebarHtml": SidebarHtml(ctx), "Tag": tag, "Title": tag, }) } func Home(context *GoInk.Context) { context.Layout("home") page, _ := strconv.Atoi(context.Param("page")) articles, pager := model.GetPublishArticleList(page, getArticleListSize()) data := map[string]interface{}{ "Articles": articles, "Pager": pager, "SidebarHtml": SidebarHtml(context), } if page > 1 { data["Title"] = "第 " + strconv.Itoa(page) + " 页" } Theme(context).Layout("home").Render("index", data) } func Article(context *GoInk.Context) { id, _ := strconv.Atoi(context.Param("id")) slug := context.Param("slug") article := model.GetContentById(id) if article == nil { context.Redirect("/") return } if article.Slug != slug || article.Type != "article" { context.Redirect("/") return } article.Hits++ Theme(context).Layout("home").Render("article", map[string]interface{}{ "Title": article.Title, "Article": article, "CommentHtml": CommentHtml(context, article), }) } func Page(context *GoInk.Context) { id, _ := strconv.Atoi(context.Param("id")) slug := context.Param("slug") article := model.GetContentById(id) if article == nil || article.Status != "publish" { context.Redirect("/") return } if article.Slug != slug || article.Type != "page" { context.Redirect("/") return } article.Hits++ Theme(context).Layout("home").Render("page", map[string]interface{}{ "Title": article.Title, "Page": article, //"CommentHtml": Comments(context, article), }) } func TopPage(context *GoInk.Context) { slug := context.Param("slug") page := model.GetContentBySlug(slug) if page == nil || page.Status != "publish" { context.Redirect("/") return } if page.IsLinked && page.Type == "page" { Theme(context).Layout("home").Render("page", map[string]interface{}{ "Title": page.Title, "Page": page, }) page.Hits++ return } context.Redirect("/") } func Comment(context *GoInk.Context) { cid, _ := strconv.Atoi(context.Param("id")) if cid < 1 { Json(context, false).End() return } if model.GetContentById(cid) == nil { Json(context, false).End() return } data := context.Input() msg := validateComment(data) if msg != "" { Json(context, false).Set("msg", msg).End() return } co := new(model.Comment) co.Author = data["user"] co.Email = data["email"] co.Url = data["url"] co.Content = data["content"] co.Avatar = utils.Gravatar(co.Email, "50") co.Pid, _ = strconv.Atoi(data["pid"]) co.Ip = context.Ip co.UserAgent = context.UserAgent co.IsAdmin = false model.CreateComment(cid, co) Json(context, true).Set("comment", co.ToJson()).End() model.CreateMessage("comment", co) context.Do("comment_created", co) } func validateComment(data map[string]string) string { if utils.IsEmptyString(data["user"]) || utils.IsEmptyString(data["content"]) { return "称呼,邮箱,内容必填" } if !utils.IsEmail(data["email"]) { return "邮箱格式错误" } if !utils.IsEmptyString(data["url"]) && !utils.IsURL(data["url"]) { return "网址格式错误" } return "" } func getArticleListSize() int { size, _ := strconv.Atoi(model.GetSetting("article_size")) if size < 1 { size = 5 } return size } ================================================ FILE: app/handler/rss.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" "strings" "time" ) func SiteMap(ctx *GoInk.Context) { baseUrl := model.GetSetting("site_url") println(baseUrl) article, _ := model.GetPublishArticleList(1, 50) navigators := model.GetNavigators() now := time.Unix(utils.Now(), 0).Format(time.RFC3339) articleMap := make([]map[string]string, len(article)) for i, a := range article { m := make(map[string]string) m["Link"] = strings.Replace(baseUrl+a.Link(), baseUrl+"/", baseUrl, -1) m["Created"] = time.Unix(a.CreateTime, 0).Format(time.RFC3339) articleMap[i] = m } navMap := make([]map[string]string, 0) for _, n := range navigators { m := make(map[string]string) if n.Link == "/" { continue } if strings.HasPrefix(n.Link, "/") { m["Link"] = strings.Replace(baseUrl+n.Link, baseUrl+"/", baseUrl, -1) } else { m["Link"] = n.Link } m["Created"] = now navMap = append(navMap, m) } ctx.ContentType("text/xml") bytes, e := ctx.App().View().Render("sitemap.xml", map[string]interface{}{ "Title": model.GetSetting("site_title"), "Link": baseUrl, "Created": now, "Articles": articleMap, "Navigators": navMap, }) if e != nil { panic(e) } ctx.Body = bytes } func Rss(ctx *GoInk.Context) { baseUrl := model.GetSetting("site_url") article, _ := model.GetPublishArticleList(1, 20) author := model.GetUsersByRole("ADMIN")[0] articleMap := make([]map[string]string, len(article)) for i, a := range article { m := make(map[string]string) m["Title"] = a.Title m["Link"] = strings.Replace(baseUrl+a.Link(), baseUrl+"/", baseUrl, -1) m["Author"] = author.Nick str := utils.Markdown2Html(a.Content()) str = strings.Replace(str, `src="/`, `src="`+strings.TrimSuffix(baseUrl, "/")+"/", -1) str = strings.Replace(str, `href="/`, `href="`+strings.TrimSuffix(baseUrl, "/")+"/", -1) m["Desc"] = str m["Created"] = time.Unix(a.CreateTime, 0).Format(time.RFC822) articleMap[i] = m } ctx.ContentType("application/rss+xml;charset=UTF-8") bytes, e := ctx.App().View().Render("rss.xml", map[string]interface{}{ "Title": model.GetSetting("site_title"), "Link": baseUrl, "Desc": model.GetSetting("site_description"), "Created": time.Unix(utils.Now(), 0).Format(time.RFC822), "Articles": articleMap, }) if e != nil { panic(e) } ctx.Body = bytes } ================================================ FILE: app/handler/upload.go ================================================ package handler import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "io/ioutil" "net/http" "os" "path" "strconv" "strings" ) func AdminFiles(context *GoInk.Context) { if context.Method == "DELETE" { id := context.Int("id") model.RemoveFile(id) Json(context, true).End() context.Do("attach_delete", id) return } files, pager := model.GetFileList(context.Int("page"), 10) context.Layout("admin/admin") context.Render("admin/files", map[string]interface{}{ "Title": "媒体文件", "Files": files, "Pager": pager, }) } func FileUpload(context *GoInk.Context) { var req *http.Request req = context.Request req.ParseMultipartForm(32 << 20) f, h, e := req.FormFile("file") if e != nil { Json(context, false).Set("msg", e.Error()).End() return } data, _ := ioutil.ReadAll(f) maxSize := context.App().Config().Int("app.upload_size") defer func() { f.Close() data = nil h = nil }() if len(data) >= maxSize { Json(context, false).Set("msg", "文件应小于10M").End() return } if !strings.Contains(context.App().Config().String("app.upload_files"), path.Ext(h.Filename)) { Json(context, false).Set("msg", "文件只支持Office文件,图片和zip存档").End() return } ff := new(model.File) ff.Name = h.Filename ff.Type = context.StringOr("type", "image") ff.Size = int64(len(data)) ff.ContentType = h.Header["Content-Type"][0] ff.Author, _ = strconv.Atoi(context.Cookie("token-user")) ff.Url = model.CreateFilePath(context.App().Get("upload_dir"), ff) e = ioutil.WriteFile(ff.Url, data, os.ModePerm) if e != nil { Json(context, false).Set("msg", e.Error()).End() return } model.CreateFile(ff) Json(context, true).Set("file", ff).End() context.Do("attach_created", ff) } ================================================ FILE: app/log.go ================================================ package app import ( "github.com/fuxiaohei/GoBlog/app/utils" "io/ioutil" "os" "path" ) // LogErrors logs error bytes to tmp/log directory. func LogError(bytes []byte) { dir := App.Config().String("app.log_dir") file := path.Join(dir, utils.DateInt64(utils.Now(), "MMDDHHmmss.log")) ioutil.WriteFile(file, bytes, os.ModePerm) } ================================================ FILE: app/model/article.go ================================================ package model import "github.com/fuxiaohei/GoBlog/app/utils" func generatePublishArticleIndex() { arr := make([]int, 0) for _, id := range contentsIndex["article"] { c := GetContentById(id) if c.Status == "publish" { arr = append(arr, id) } } contentsIndex["article-publish"] = arr } // GetPublishArticleList gets published article list and pager. func GetPublishArticleList(page, size int) ([]*Content, *utils.Pager) { index := contentsIndex["article-publish"] pager := utils.NewPager(page, size, len(index)) articles := make([]*Content, 0) if len(index) < 1 { return articles, pager } if page > pager.Pages { return articles, pager } for i := pager.Begin; i <= pager.End; i++ { articles = append(articles, GetContentById(index[i-1])) } return articles, pager } // GetArticleList gets articles list and pager no matter article status. func GetArticleList(page, size int) ([]*Content, *utils.Pager) { index := contentsIndex["article"] pager := utils.NewPager(page, size, len(index)) articles := make([]*Content, 0) if len(index) < 1 { return articles, pager } if page > pager.Pages { return articles, pager } for i := pager.Begin; i <= pager.End; i++ { articles = append(articles, GetContentById(index[i-1])) } return articles, pager } // GetPopularArticleList returns popular articles list. // Popular articles are ordered by comment number. func GetPopularArticleList(size int) []*Content { index := contentsIndex["article-pop"] pager := utils.NewPager(1, size, len(index)) articles := make([]*Content, 0) if len(index) < 1 { return articles } if 1 > pager.Pages { return articles } for i := pager.Begin; i <= pager.End; i++ { articles = append(articles, GetContentById(index[i-1])) } return articles } // GetTaggedArticleList returns tagged articles list. // These articles contains same one tag. func GetTaggedArticleList(tag string, page, size int) ([]*Content, *utils.Pager) { index := contentsIndex["t-"+tag] pager := utils.NewPager(page, size, len(index)) articles := make([]*Content, 0) if len(index) < 1 { return articles, pager } if page > pager.Pages { return articles, pager } for i := pager.Begin; i <= pager.End; i++ { articles = append(articles, GetContentById(index[i-1])) } return articles, pager } ================================================ FILE: app/model/comment.go ================================================ package model import ( "github.com/fuxiaohei/GoBlog/app/utils" "html/template" "sort" "strings" ) var ( readers map[string]*Reader comments map[int]*Comment commentsIndex []int commentMaxId int ) // Comment Reader struct. // Saving comment reader for visiting wall usage or other statics. type Reader struct { Author string Email string Url string Active bool Comments int Rank int } // Inc increases Reader's rank. func (r *Reader) Inc() { r.Rank++ if r.Rank > 1 { r.Active = true } } // Dec decreases Reader's rank. func (r *Reader) Dec() { r.Rank-- if r.Rank < 1 { r.Active = false } } // Comment struct defines a comment item data. type Comment struct { Id int Author string Email string Url string Avatar string Content string CreateTime int64 // Content id Cid int // Parent Comment id Pid int Status string Ip string UserAgent string // Is comment of admin IsAdmin bool } // ParentMd returns parent comment simple message as markdown text. func (c *Comment) ParentMd() string { if c.Pid < 1 { return "" } co := GetCommentById(c.Pid) if co == nil { return "> 已失效" } str := "> @" + co.Author + "\n\n" str += "> " + co.Content + "\n" return str } // ToJson converts comment struct to public json map. // It can hide some private fields, such as email. func (c *Comment) ToJson() map[string]interface{} { m := make(map[string]interface{}) m["id"] = c.Id m["author"] = c.Author //m["email"] = c.Email m["url"] = c.Url m["avatar"] = c.Avatar m["content"] = c.Content m["create_time"] = c.CreateTime m["pid"] = c.Pid m["status"] = c.Status m["ip"] = c.Ip m["user_agent"] = c.UserAgent m["parent_md"] = c.ParentMd() return m } // IsValid returns whether this comment is valid to show. // If this comment is not approved or its parent is missing, return false. func (c *Comment) IsValid() bool { if c.Status != "approved" { return false } if c.Pid > 0 { if GetCommentById(c.Pid) == nil { return false } } return true } // IsRemovable returns whether this comment can remove. // If content or parent comment of this comment is removed, return true. func (c *Comment) IsRemovable() bool { if GetContentById(c.Cid) == nil { return true } if c.Pid > 0 { if GetCommentById(c.Pid) == nil { return true } } return false } // GetReader returns the reader item of this comment. func (c *Comment) GetReader() *Reader { for _, r := range readers { if r.Email == c.Email { return r } } return nil } // GetContent returns the content item of this comment. func (c *Comment) GetContent() *Content { return GetContentById(c.Cid) } // CreateReader creates a reader from a comment. func CreateReader(c *Comment) { r := new(Reader) r.Author = c.Author r.Email = c.Email r.Url = c.Url r.Active = false r.Comments = 1 r.Rank = 0 readers[r.Email] = r go SyncReaders() } // CreateComment creates a comment and links it to the cid content. func CreateComment(cid int, c *Comment) { commentMaxId += Storage.TimeInc(4) c.Id = commentMaxId c.CreateTime = utils.Now() c.Status = "check" c.Cid = cid // escape content c.Content = strings.Replace(utils.Html2str(template.HTMLEscapeString(c.Content)), "\n", "
", -1) // if empty url, use # instead. if c.Url == "" { c.Url = "#" } // if admin comment, must be approved. if c.IsAdmin { c.Status = "approved" } else { // if common comment, get reader status for checking status. r := c.GetReader() if r != nil { if r.Active { c.Status = "approved" } } else { CreateReader(c) } } // update comment memory data comments[c.Id] = c commentsIndex = append([]int{c.Id}, commentsIndex...) // append to content content := GetContentById(cid) content.Comments = append(content.Comments, c) go SyncContent(content) } // SaveComment saves a comment and related updates content and reader data. func SaveComment(c *Comment) { cnt := GetContentById(c.Cid) go SyncContent(cnt) go SyncReaders() } func removeOneComment(cid int, id int) { delete(comments, id) for n, c := range commentsIndex { if c == id { commentsIndex = append(commentsIndex[:n], commentsIndex[n+1:]...) break } } cnt := GetContentById(cid) if cnt == nil { return } for n, c := range cnt.Comments { if c.Id == id { cnt.Comments = append(cnt.Comments[:n], cnt.Comments[n+1:]...) } } } // RemoveComment removes a comment by id and updates content iten by cid. func RemoveComment(cid int, id int) { removeOneComment(cid, id) cnt := GetContentById(cid) if cnt == nil { return } go SyncContent(cnt) } // GetCommentById returns a comment by id. func GetCommentById(id int) *Comment { return comments[id] } // GetCommentList returns a comments list and pager. // This list scans all comments no matter its status. func GetCommentList(page, size int) ([]*Comment, *utils.Pager) { index := commentsIndex pager := utils.NewPager(page, size, len(index)) comments := make([]*Comment, 0) if page > pager.Pages { return comments, pager } for i := pager.Begin; i <= pager.End; i++ { comments = append(comments, GetCommentById(index[i-1])) } return comments, pager } // GetCommentRecentList returns a comments list of recent comments. // Recent comments are approved and no parent and not admin comment. // It's ordered by comment id desc. func GetCommentRecentList(size int) []*Comment { comments, i := make([]*Comment, 0), 0 for _, id := range commentsIndex { if i >= size { return comments } c := GetCommentById(id) if c.Pid < 1 && c.IsAdmin == false && c.Status == "approved" { comments = append(comments, c) i++ } } return comments } // SyncReaders writes all readers data. func SyncReaders() { Storage.Set("readers", readers) } // LoadReaders loads all readers from storage json. func LoadReaders() { readers = make(map[string]*Reader) Storage.Get("readers", &readers) } // GetReaders returns slice of all readers func GetReaders() []*Reader { r, i := make([]*Reader, len(readers)), 0 for _, rd := range readers { r[i] = rd i++ } return r } // RemoveReader removes a reader by his email. func RemoveReader(email string) { delete(readers, email) SyncReaders() } // LoadComments loads all comments from contents. func LoadComments() { comments = make(map[int]*Comment) commentsIndex = make([]int, 0) commentMaxId = 0 for _, c := range contents { if len(c.Comments) < 1 { continue } for _, cm := range c.Comments { comments[cm.Id] = cm commentsIndex = append(commentsIndex, cm.Id) if cm.Id > commentMaxId { commentMaxId = cm.Id } } } sort.Sort(sort.Reverse(sort.IntSlice(commentsIndex))) } // UpdateCommentAdmin updates comment author data if admin user data updated. // It only updates admin comments. func UpdateCommentAdmin(user *User) { for _, co := range comments { if co.IsAdmin { co.Author = user.Nick co.Email = user.Email co.Url = user.Url co.Avatar = utils.Gravatar(co.Email, "50") } } } // RecycleComments cleans removable comments. func RecycleComments() { readerTmp := make(map[string][]int) for _, co := range comments { if co.IsRemovable() { removeOneComment(co.Cid, co.Id) continue } r := co.GetReader() if r == nil { continue } if _, ok := readerTmp[r.Email]; !ok { readerTmp[r.Email] = make([]int, 0) } readerTmp[r.Email] = append(readerTmp[r.Email], co.Id) } for _, r := range readers { if _, ok := readerTmp[r.Email]; ok { r.Comments = len(readerTmp[r.Email]) } } SyncContents() SyncReaders() } func startCommentsTimer() { SetTimerFunc("comment-recycle", 36, func() { println("recycle comments in 6 hours timer") RecycleComments() }) } ================================================ FILE: app/model/content.go ================================================ package model import ( "errors" "fmt" "github.com/fuxiaohei/GoBlog/app/utils" "net/url" "os" "path/filepath" "sort" "strings" ) var ( contents map[int]*Content contentMaxId int contentsIndex map[string][]int tags []*Tag ) // Content instance, defines content data items. type Content struct { Id int Title string Slug string Text string // Rendered string textRendered string //Category string Tags []string CreateTime int64 EditTime int64 UpdateTime int64 // IsComment opens or closes comment IsComment bool // IsLinked makes pager link as top level link /link.html IsLinked bool //IsTop bool AuthorId int // Template makes pager use own template file Template string Type string Status string // Format defines the content text format type. Now only support markdown. Format string Comments []*Comment Hits int } // TagString returns content tags in a string that's joined by ",". func (cnt *Content) TagString() string { return strings.Join(cnt.Tags, ",") } // GetTags returns tags struct in this content. func (cnt *Content) GetTags() []*Tag { tgs := make([]*Tag, len(cnt.Tags)) for i, t := range cnt.Tags { tgs[i] = &Tag{Name: t} } return tgs } // Link returns content link as {type}/{id}/{slug}.html. // If content isn't published, return "#". // If content is page and top linked, return {slug}.html as top level link. func (cnt *Content) Link() string { if cnt.Status != "publish" { return "#" } if cnt.IsLinked { return "/" + cnt.Slug + ".html" } return fmt.Sprintf("/%s/%d/%s.html", cnt.Type, cnt.Id, cnt.Slug) } // Content returns whole content text. // If enable go-markdown, return markdown-rendered content. func (cnt *Content) Content() string { txt := strings.Replace(cnt.Text, "", "", -1) if GetSetting("enable_go_markdown") == "true" { if cnt.textRendered == "" { cnt.textRendered = utils.Markdown2Html(txt) } return cnt.textRendered } return txt } // Summary returns content summary. // Summary text means the part before page-break . // It can be go-markdown rendered. func (cnt *Content) Summary() string { text := strings.Split(cnt.Text, "")[0] if GetSetting("enable_go_markdown") == "true" { return utils.Markdown2Html(text) } return text } // CommentNum returns content comments number. // If comment are checking or, its parent are lost, do not count it. func (cnt *Content) CommentNum() int { max := len(cnt.Comments) for _, c := range cnt.Comments { if !c.IsValid() { max-- } } return max } // ChangeSlug changes content's slug. // It checks whether this slug is unique. func (cnt *Content) ChangeSlug(slug string) bool { c2 := GetContentBySlug(slug) if c2 == nil { cnt.Slug = slug return true } if c2.Id != cnt.Id { return false } cnt.Slug = slug return true } // User returns content author user instance. func (cnt *Content) User() *User { return GetUserById(cnt.AuthorId) } // Content Tag struct. It convert tag string to proper struct or link. type Tag struct { Name string Cid []int } // Link returns tag name url-encoded link. func (t *Tag) Link() string { return "/tag/" + url.QueryEscape(strings.Replace(t.Name, ".", "-", -1)) } // GetContentById gets a content by given id. func GetContentById(id int) *Content { return contents[id] } // GetContentBySlug gets a content by given slug. func GetContentBySlug(slug string) *Content { for _, c := range contents { if c.Slug == slug { return c } } return nil } // CreateContent creates new content. // t means content type, article or page. func CreateContent(c *Content, t string) (*Content, error) { c2 := GetContentBySlug(c.Slug) if c2 != nil { return nil, errors.New("slug-repeat") } contentMaxId += Storage.TimeInc(3) c.Id = contentMaxId c.CreateTime = utils.Now() c.EditTime = c.CreateTime c.UpdateTime = c.CreateTime c.Comments = make([]*Comment, 0) c.Type = t c.Hits = 1 c.textRendered = "" contents[c.Id] = c contentsIndex[c.Type] = append([]int{c.Id}, contentsIndex[c.Type]...) generatePublishArticleIndex() go SyncContent(c) return c, nil } // SaveContent saves changed content. // It will re-generate related indexes. func SaveContent(c *Content) { c.EditTime = utils.Now() // clean rendered cache text c.textRendered = "" generatePublishArticleIndex() go SyncContent(c) } // RemoveContent removes a content. // Not delete file really, just change status to DELETE. // This content can't be loaded in memory from storage json. func RemoveContent(c *Content) { delete(contents, c.Id) for i, id := range contentsIndex[c.Type] { if c.Id == id { contentsIndex[c.Type] = append(contentsIndex[c.Type][:i], contentsIndex[c.Type][i+1:]...) break } } c.Status = "DELETE" generatePublishArticleIndex() go SyncContent(c) } // SyncContent writes a content to storage json. func SyncContent(c *Content) { key := fmt.Sprintf("content/%s-%d", c.Type, c.Id) Storage.Set(key, c) } // SyncContents writes all contents to storage json. func SyncContents() { for _, c := range contents { SyncContent(c) } } // LoadContents loads all contents, then generates indexes. func LoadContents() { contents = make(map[int]*Content) contentsIndex = make(map[string][]int) contentMaxId = 0 articleIndex := make([]int, 0) pageIndex := make([]int, 0) // walk files in directory filepath.Walk(filepath.Join(Storage.dir, "content"), func(_ string, info os.FileInfo, err error) error { if err == nil { // ignore dir and sub-dir if info.IsDir() { return nil } c := new(Content) file := strings.Replace("content/"+info.Name(), filepath.Ext(info.Name()), "", -1) Storage.Get(file, c) if c.Id > 0 { // ignore DELETE status if c.Status != "DELETE" { contents[c.Id] = c if c.Type == "article" { articleIndex = append(articleIndex, c.Id) } if c.Type == "page" { pageIndex = append(pageIndex, c.Id) } } if c.Id > contentMaxId { contentMaxId = c.Id } } } return nil }) // sort indexes as desc order sort.Sort(sort.Reverse(sort.IntSlice(articleIndex))) sort.Sort(sort.Reverse(sort.IntSlice(pageIndex))) contentsIndex["article"] = articleIndex contentsIndex["page"] = pageIndex } func startContentSyncTimer() { SetTimerFunc("content-sync", 6, func() { println("write contents in 1 hour timer") SyncContents() }) } func generateContentTmpIndexes() { var ( popTmp = make([][2]int, 0) popIndex = make([]int, 0) tagIndexes = make(map[string][]int) data = make(map[string][]int) ) for _, c := range contents { if c.Status == "publish" && c.Type == "article" { // pop temp index popTmp = append(popTmp, [2]int{c.Id, c.CommentNum()}) if len(c.Tags) > 0 { for _, t := range c.Tags { if tagIndexes[t] == nil { tagIndexes[t] = make([]int, 0) } tagIndexes[t] = append(tagIndexes[t], c.Id) } } } } // sort popular list utils.SortInt(popTmp) for _, p := range popTmp { popIndex = append(popIndex, p[0]) } contentsIndex["article-pop"] = popIndex // assemble indexes map data["pop-index"] = popIndex tags = make([]*Tag, 0) for tag, index := range tagIndexes { if strings.TrimSpace(tag) == "" { continue } sort.Sort(sort.Reverse(sort.IntSlice(index))) data["t-"+tag] = index contentsIndex["t-"+tag] = index t := new(Tag) t.Name = tag t.Cid = index tags = append(tags, t) } // write to tmp data TmpStorage.Set("contents", data) } // GetContentTags returns all tags. func GetContentTags() []*Tag { return tags } func startContentTmpIndexesTimer() { SetTimerFunc("content-indexes", 36, func() { println("write content indexes in 6 hours timer") generateContentTmpIndexes() }) } ================================================ FILE: app/model/file.go ================================================ package model import ( "github.com/fuxiaohei/GoBlog/app/utils" "os" "path" "strconv" ) var ( files []*File fileMaxId int ) type File struct { Id int Name string UploadTime int64 Url string ContentType string Author int IsUsed bool Size int64 Type string Hits int } func CreateFile(f *File) *File { fileMaxId += Storage.TimeInc(3) f.Id = fileMaxId f.UploadTime = utils.Now() f.IsUsed = true f.Hits = 0 files = append([]*File{f}, files...) go SyncFiles() return f } func CreateFilePath(dir string, f *File) string { os.MkdirAll(dir, os.ModePerm) name := utils.DateInt64(utils.Now(), "YYYYMMDDHHmmss") name += strconv.Itoa(Storage.TimeInc(10)) + path.Ext(f.Name) return path.Join(dir, name) } func GetFileList(page, size int) ([]*File, *utils.Pager) { pager := utils.NewPager(page, size, len(files)) f := make([]*File, 0) if page > pager.Pages || len(files) < 1 { return f, pager } for i := pager.Begin; i <= pager.End; i++ { f = files[pager.Begin-1 : pager.End] } return f, pager } func RemoveFile(id int) { for i, f2 := range files { if id == f2.Id { files = append(files[:i], files[i+1:]...) os.Remove(f2.Url) } } go SyncFiles() } func SyncFiles() { Storage.Set("files", files) } func LoadFiles() { files = make([]*File, 0) fileMaxId = 0 Storage.Get("files", &files) for _, f := range files { if f.Id > fileMaxId { fileMaxId = f.Id } } } ================================================ FILE: app/model/locker.go ================================================ package model import "sync" var locker sync.Mutex func init() { locker = sync.Mutex{} } ================================================ FILE: app/model/message.go ================================================ package model import ( "github.com/fuxiaohei/GoBlog/app/utils" "strings" ) var ( messages []*Message messageMaxId int messageGenerator map[string]func(v interface{}) string ) func init() { messageGenerator = make(map[string]func(v interface{}) string) messageGenerator["comment"] = generateCommentMessage messageGenerator["backup"] = generateBackupMessage } type Message struct { Id int Type string CreateTime int64 Data string IsRead bool } func CreateMessage(tp string, data interface{}) *Message { m := new(Message) m.Type = tp m.Data = messageGenerator[tp](data) if m.Data == "" { println("message generator returns empty") return nil } m.CreateTime = utils.Now() m.IsRead = false messageMaxId += Storage.TimeInc(3) m.Id = messageMaxId messages = append([]*Message{m}, messages...) SyncMessages() return m } func SetMessageGenerator(name string, fn func(v interface{}) string) { messageGenerator[name] = fn } func GetMessage(id int) *Message { for _, m := range messages { if m.Id == id { return m } } return nil } func GetUnreadMessages() []*Message { ms := make([]*Message, 0) for _, m := range messages { if m.IsRead { continue } ms = append(ms, m) } return ms } func GetMessages() []*Message { return messages } func GetTypedMessages(tp string, unread bool) []*Message { ms := make([]*Message, 0) for _, m := range messages { if m.Type == tp { if unread { if !m.IsRead { ms = append(ms, m) } } else { ms = append(ms, m) } } } return ms } func SaveMessageRead(m *Message) { m.IsRead = true SyncMessages() } func SyncMessages() { Storage.Set("messages", messages) } func LoadMessages() { messages = make([]*Message, 0) messageMaxId = 0 Storage.Get("messages", &messages) for _, m := range messages { if m.Id > messageMaxId { messageMaxId = m.Id } } } func RecycleMessages() { for i, m := range messages { if m.CreateTime+3600*24*3 < utils.Now() { messages = messages[:i] return } } } func generateCommentMessage(co interface{}) string { c, ok := co.(*Comment) if !ok { return "" } cnt := GetContentById(c.Cid) s := "" if c.Pid < 1 { s = "

" + c.Author + "同学,在文章《" + cnt.Title + "》发表评论:" s += utils.Html2str(c.Content) + "

" } else { p := GetCommentById(c.Pid) s = "

" + p.Author + "同学,在文章《" + cnt.Title + "》的评论:" s += utils.Html2str(p.Content) + "

" s += "

" + c.Author + "同学的回复:" s += utils.Html2str(c.Content) + "

" } return s } func generateBackupMessage(co interface{}) string { str := co.(string) if strings.HasPrefix(str, "[0]") { return "备份全站失败: " + strings.TrimPrefix(str, "[0]") + "." } return "备份全站到 " + strings.TrimPrefix(str, "[1]") + " 成功." } func startMessageTimer() { SetTimerFunc("message-sync", 9, func() { println("write messages in 1.5 hour timer") RecycleMessages() SyncMessages() }) } ================================================ FILE: app/model/page.go ================================================ package model import "github.com/fuxiaohei/GoBlog/app/utils" // GetPageList gets pages list and pager no matter page status. // In common cases, no need to get a list or pagers for public page. func GetPageList(page, size int) ([]*Content, *utils.Pager) { index := contentsIndex["page"] pager := utils.NewPager(page, size, len(index)) pages := make([]*Content, 0) if len(index) < 1 { return pages, pager } if page > pager.Pages { return pages, pager } for i := pager.Begin; i <= pager.End; i++ { pages = append(pages, GetContentById(index[i-1])) } return pages, pager } ================================================ FILE: app/model/setting.go ================================================ package model import ( "strconv" "strings" ) type navItem struct { Order int Text string Title string Link string } var ( settings map[string]string navigators []*navItem ) func GetSetting(key string) string { return settings[key] } func GetCustomSettings() map[string]string { m := make(map[string]string) for k, v := range settings { if strings.HasPrefix(k, "c_") { m[strings.TrimPrefix(k, "c_")] = v } } return m } func SetSetting(key string, v string) { settings[key] = v } func SyncSettings() { Storage.Set("settings", settings) } func LoadSettings() { settings = make(map[string]string) Storage.Get("settings", &settings) } func SortNavigators() { l := len(navigators) for i := 1; i < l; i++ { for j := i; j > 0; j-- { if navigators[j].Order < navigators[j-1].Order { navigators[j], navigators[j-1] = navigators[j-1], navigators[j] } } } } func LoadNavigators() { navigators = make([]*navItem, 0) Storage.Get("navigators", &navigators) SortNavigators() } func SetNavigators(order []string, text []string, title []string, link []string) { navs := make([]*navItem, len(text)) for i, t := range text { n := new(navItem) n.Order, _ = strconv.Atoi(order[i]) n.Text = t n.Title = title[i] n.Link = link[i] navs[i] = n } navigators = navs SyncNavigators() } func DefaultNavigators() { n := new(navItem) n.Order = 1 n.Text = "文章" n.Title = "文章" n.Link = "/" n2 := new(navItem) n2.Order = 2 n2.Text = "关于" n2.Title = "关于" n2.Link = "/about-me.html" n3 := new(navItem) n3.Order = 3 n3.Text = "好友" n3.Title = "好友" n3.Link = "/friends.html" navigators = []*navItem{n, n2, n3} Storage.Set("navigators", navigators) } func SyncNavigators() { Storage.Set("navigators", navigators) SortNavigators() } func GetNavigators() []*navItem { return navigators } ================================================ FILE: app/model/statis.go ================================================ package model type Statis struct { Comments int Articles int Pages int Files int Version int Readers int } func NewStatis() *Statis { s := new(Statis) s.Comments = len(commentsIndex) s.Articles = len(contentsIndex["article"]) s.Pages = len(contentsIndex["page"]) s.Files = len(files) s.Version = GetVersion().Version s.Readers = len(GetReaders()) return s } ================================================ FILE: app/model/storage.go ================================================ package model import ( "encoding/json" "github.com/fuxiaohei/GoBlog/app/utils" "io/ioutil" "os" "path" "strconv" ) var ( appVersion int // global data storage instance Storage *jsonStorage // global tmp data storage instance. Temp data are generated for special usages, will not backup. TmpStorage *jsonStorage ) type jsonStorage struct { dir string } func (jss *jsonStorage) Init(dir string) { jss.dir = dir } func (jss *jsonStorage) Has(key string) bool { file := path.Join(jss.dir, key+".json") _, e := os.Stat(file) return e == nil } func (jss *jsonStorage) Get(key string, v interface{}) { file := path.Join(jss.dir, key+".json") bytes, e := ioutil.ReadFile(file) if e != nil { println("read storage '" + key + "' error") return } e = json.Unmarshal(bytes, v) if e != nil { println("json decode '" + key + "' error") } } func (jss *jsonStorage) Set(key string, v interface{}) { locker.Lock() defer locker.Unlock() bytes, e := json.Marshal(v) if e != nil { println("json encode '" + key + "' error") return } file := path.Join(jss.dir, key+".json") e = ioutil.WriteFile(file, bytes, 0777) if e != nil { println("write storage '" + key + "' error") } } func (jss *jsonStorage) Dir(name string) { os.MkdirAll(path.Join(jss.dir, name), os.ModePerm) } func writeDefaultData() { // write user u := new(User) u.Id = Storage.TimeInc(10) u.Name = "admin" u.Password = utils.Sha1("adminxxxxx") u.Nick = "管理员" u.Email = "admin@example.com" u.Url = "http://example.com/" u.CreateTime = utils.Now() u.Bio = "这是站点的管理员,你可以添加一些个人介绍,支持换行不支持markdown" u.LastLoginTime = u.CreateTime u.Role = "ADMIN" Storage.Set("users", []*User{u}) // write token Storage.Set("tokens", map[string]*Token{}) // write contents a := new(Content) a.Id = Storage.TimeInc(9) a.Title = "欢迎使用 Fxh.Go" a.Slug = "welcome-fxh-go" a.Text = "如果您看到这篇文章,表示您的 blog 已经安装成功." a.Tags = []string{"Fxh.Go"} a.CreateTime = utils.Now() a.EditTime = a.CreateTime a.UpdateTime = a.CreateTime a.IsComment = true a.IsLinked = false a.AuthorId = u.Id a.Type = "article" a.Status = "publish" a.Format = "markdown" a.Template = "blog.html" a.Hits = 1 // write comments co := new(Comment) co.Author = u.Nick co.Email = u.Email co.Url = u.Url co.Content = "欢迎加入使用 Fxh.Go" co.Avatar = utils.Gravatar(co.Email, "50") co.Pid = 0 co.Ip = "127.0.0.1" co.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17" co.IsAdmin = true co.Id = Storage.TimeInc(7) co.CreateTime = utils.Now() co.Status = "approved" co.Cid = a.Id a.Comments = []*Comment{co} Storage.Set("content/article-"+strconv.Itoa(a.Id), a) // write pages p := new(Content) p.Id = a.Id + Storage.TimeInc(6) p.Title = "关于" p.Slug = "about-me" p.Text = "本页面由 Fxh.Go 创建, 这只是个测试页面." p.Tags = []string{} p.CreateTime = utils.Now() p.EditTime = p.CreateTime p.UpdateTime = p.UpdateTime p.IsComment = true p.IsLinked = true p.AuthorId = u.Id p.Type = "page" p.Status = "publish" p.Format = "markdown" p.Comments = make([]*Comment, 0) p.Template = "page.html" p.Hits = 1 Storage.Set("content/page-"+strconv.Itoa(p.Id), p) p2 := new(Content) p2.Id = p.Id + Storage.TimeInc(6) p2.Title = "好友" p2.Slug = "friends" p2.Text = "本页面由 Fxh.Go 创建, 这只是个测试页面." p2.Tags = []string{} p2.CreateTime = utils.Now() p2.EditTime = p2.CreateTime p2.UpdateTime = p2.UpdateTime p2.IsComment = true p2.IsLinked = true p2.AuthorId = u.Id p2.Type = "page" p2.Status = "publish" p2.Format = "markdown" p2.Comments = make([]*Comment, 0) p2.Template = "page.html" p2.Hits = 1 Storage.Set("content/page-"+strconv.Itoa(p2.Id), p2) // write new reader Storage.Set("readers", map[string]*Reader{}) // write version v := new(version) v.Name = "Fxh.Go" v.BuildTime = utils.Now() v.Version = appVersion Storage.Set("version", v) // write settings s := map[string]string{ "site_title": "Fxh.Go", "site_sub_title": "Go开发的简单博客", "site_keywords": "Fxh.Go,Golang,Blog", "site_description": "Go语言开发的简单博客程序", "site_url": "http://localhost/", "article_size": "4", "site_theme": "default", "enable_go_markdown": "false", "c_footer_weibo": "#", "c_footer_github": "#", "c_footer_email": "#", "c_home_avatar": "/static/img/site.png", "c_footer_ga": "", } Storage.Set("settings", s) // write files Storage.Set("files", []*File{}) // write message Storage.Set("messages", []*Message{}) // write navigators n := new(navItem) n.Order = 1 n.Text = "文章" n.Title = "文章" n.Link = "/" n2 := new(navItem) n2.Order = 2 n2.Text = "关于" n2.Title = "关于" n2.Link = "/about-me.html" n3 := new(navItem) n3.Order = 3 n3.Text = "好友" n3.Title = "好友" n3.Link = "/friends.html" Storage.Set("navigators", []*navItem{n, n2, n3}) // write default tmp data writeDefaultTmpData() } func writeDefaultTmpData() { TmpStorage.Set("contents", make(map[string][]int)) } func loadAllData() { loadVersion() LoadSettings() LoadNavigators() LoadUsers() LoadTokens() LoadContents() LoadMessages() LoadReaders() LoadComments() LoadFiles() } // TimeInc returns time step value devided by d int with time unix stamp. func (jss *jsonStorage) TimeInc(d int) int { return int(utils.Now())%d + 1 } // Init does model initialization. // If first run, write default data. // v means app.Version number. It's needed for version data. func Init(v int) { appVersion = v Storage = new(jsonStorage) Storage.Init("data") TmpStorage = new(jsonStorage) TmpStorage.dir = "tmp/data" if !Storage.Has("version") { os.Mkdir(Storage.dir, os.ModePerm) os.Mkdir(path.Join(Storage.dir, "content"), os.ModePerm) os.Mkdir(path.Join(Storage.dir, "plugin"), os.ModePerm) writeDefaultData() } } // All loads all data from storage to memory. // Start timers for content, comment and message. func All() { loadAllData() // generate indexes SyncIndexes() // start model timer, do all timer stuffs StartModelTimer() } func SyncIndexes() { // generate indexes generatePublishArticleIndex() generateContentTmpIndexes() } // SyncAll writes all current memory data to storage files. func SyncAll() { SyncContents() SyncMessages() SyncFiles() SyncReaders() SyncSettings() SyncNavigators() SyncTokens() SyncUsers() SyncVersion() } ================================================ FILE: app/model/timer.go ================================================ package model import ( "time" ) type timerFunc struct { Fn func() Ticker int } var ( timerCount int timerFuncs map[string]*timerFunc ) func init() { timerCount = 0 timerFuncs = make(map[string]*timerFunc) } // SetTimerFunc adds timer func for time ticker. // Ticker means step time, after ticker size step passed, do function. // Name is unique name of func.If set same name func, use the last one. func SetTimerFunc(name string, ticker int, fn func()) { tfn := new(timerFunc) tfn.Fn = fn tfn.Ticker = ticker timerFuncs[name] = tfn } // ChangeTimerFunc can change timer func by given name. // If the func of name is none, do not change anything, print error message. func ChangeTimerFunc(name string, ticker int, fn func()) { if _, ok := timerFuncs[name]; ok { timerFuncs[name].Fn = fn timerFuncs[name].Ticker = ticker } else { println("change invalid timer func : " + name) } } // DelTimerFunc deletes timer func. func DelTimerFunc(name string) { delete(timerFuncs, name) } // GetTimerFuncs returns registered timer func with its name and ticker int. func GetTimerFuncs() map[string]int { m := make(map[string]int) for n, f := range timerFuncs { m[n] = f.Ticker } return m } // StartModelTimer adds models' timer and starts time ticker. // The default step is 10 min once. func StartModelTimer() { // start all timers startCommentsTimer() startContentSyncTimer() startContentTmpIndexesTimer() startMessageTimer() // start time ticker ticker := time.NewTicker(time.Duration(10) * time.Minute) go doTimers(ticker.C) } func doTimers(c <-chan time.Time) { for { <-c timerCount++ for _, tfn := range timerFuncs { if timerCount%tfn.Ticker == 0 { tfn.Fn() } } if timerCount > 999 { timerCount = 0 } } } ================================================ FILE: app/model/token.go ================================================ package model import ( "fmt" "github.com/fuxiaohei/GoBlog/app/utils" "github.com/fuxiaohei/GoInk" ) var tokens map[string]*Token type Token struct { Value string UserId int CreateTime int64 ExpireTime int64 } // check token is valid or expired. func (t *Token) IsValid() bool { if GetUserById(t.UserId) == nil { return false } return t.ExpireTime > utils.Now() } // create new token from user and context. func CreateToken(u *User, context *GoInk.Context, expire int64) *Token { t := new(Token) t.UserId = u.Id t.CreateTime = utils.Now() t.ExpireTime = t.CreateTime + expire t.Value = utils.Sha1(fmt.Sprintf("%s-%s-%d-%d", context.Ip, context.UserAgent, t.CreateTime, t.UserId)) tokens[t.Value] = t go SyncTokens() return t } // get token by token value. func GetTokenByValue(v string) *Token { return tokens[v] } // get tokens of given user. func GetTokensByUser(u *User) []*Token { ts := make([]*Token, 0) for _, t := range tokens { if t.UserId == u.Id { ts = append(ts, t) } } return ts } // remove a token by token value. func RemoveToken(v string) { delete(tokens, v) go SyncTokens() } // clean all expired tokens in memory. // do not write to json. func CleanTokens() { for k, t := range tokens { if !t.IsValid() { delete(tokens, k) } } } // write tokens to json. // it calls CleanTokens before writing. func SyncTokens() { CleanTokens() Storage.Set("tokens", tokens) } // load all tokens from json. func LoadTokens() { tokens = make(map[string]*Token) Storage.Get("tokens", &tokens) } ================================================ FILE: app/model/user.go ================================================ package model import ( "errors" "github.com/fuxiaohei/GoBlog/app/utils" ) var ( users []*User userMaxId int ) type User struct { Id int Name string Password string Nick string Email string Avatar string Url string Bio string CreateTime int64 LastLoginTime int64 Role string } // check user password. func (u *User) CheckPassword(pwd string) bool { return utils.Sha1(pwd+"xxxxx") == u.Password } // change user email. // check unique. func (u *User) ChangeEmail(email string) bool { u2 := GetUserByEmail(u.Email) if u2.Id != u.Id { return false } u.Email = email return true } // change user password. func (u *User) ChangePassword(pwd string) { u.Password = utils.Sha1(pwd + "xxxxx") } // get a user by given id. func GetUserById(id int) *User { for _, u := range users { if u.Id == id { return u } } return nil } // get a user by given name. func GetUserByName(name string) *User { for _, u := range users { if u.Name == name { return u } } return nil } // get a user by given email. func GetUserByEmail(email string) *User { for _, u := range users { if u.Email == email { return u } } return nil } // get users of given role. func GetUsersByRole(role string) []*User { us := make([]*User, 0) for _, u := range users { if u.Role == role { us = append(us, u) } } return us } // create new user. func CreateUser(u *User) error { if GetUserByName(u.Email) != nil { return errors.New("email-repeat") } userMaxId += Storage.TimeInc(5) u.Id = userMaxId u.CreateTime = utils.Now() u.LastLoginTime = u.CreateTime users = append(users, u) go SyncUsers() return nil } // remove a user. func RemoveUser(u *User) { for i, u2 := range users { if u2.Id == u.Id { users = append(users[:i], users[i+1:]...) break } } go SyncUsers() } // write users to json. func SyncUsers() { Storage.Set("users", users) } func LoadUsers() { users = make([]*User, 0) userMaxId = 0 Storage.Get("users", &users) for _, u := range users { if u.Id > userMaxId { userMaxId = u.Id } } } ================================================ FILE: app/model/version.go ================================================ package model var ver *version type version struct { Name string BuildTime int64 Version int CurrentVersion int } func loadVersion() { ver = new(version) Storage.Get("version", ver) } func GetVersion() *version { if ver == nil { loadVersion() } return ver } func SyncVersion() { Storage.Set("version", ver) } ================================================ FILE: app/plugin/email.go ================================================ package plugin import ( "bytes" "encoding/base64" "fmt" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "html/template" "net/mail" "net/smtp" "path" "strings" ) var ( // email template original from http://ben-lab.com/tech/1789.html emailReplyTemplate = `

> 您在 {{.site}} 上的留言有回复啦!

{{.author_p}} 同学,您曾在文章《{{.title}}》上发表评论:

{{.text_p}}

{{.author}} 给您的回复如下:

{{.text}}

您可以点击 查看回复的完整內容 ,欢迎再次光临 {{.site}}

` emailCreatedTemplate = `

> {{.author}} 在 {{.site}} 上的文章 《{{.title}}》 发表了评论!

{{.author}} 同学,在文章《{{.title}}》上发表评论:

{{.text}}

您可以点击 查看完整內容 ,欢迎再次光临 {{.site}}

` ) // Email plugin instance, contains activation status, handler status, settings and templates. type EmailPlugin struct { isActive bool isHandlerRegistered bool settings map[string]string templates map[string]*template.Template } func init() { EmailPlugin := new(EmailPlugin) EmailPlugin.isActive = false EmailPlugin.isHandlerRegistered = false EmailPlugin.settings = make(map[string]string) EmailPlugin.templates = make(map[string]*template.Template) // load templates t1, e := template.New("reply").Parse(emailReplyTemplate) if e != nil { panic(e) } EmailPlugin.templates["reply"] = t1 t2, e2 := template.New("created").Parse(emailCreatedTemplate) if e2 != nil { panic(e) } EmailPlugin.templates["created"] = t2 register(EmailPlugin) } // Name returns email plugin name func (p *EmailPlugin) Name() string { return "邮件提醒" } // Key returns email plugin unique key. func (p *EmailPlugin) Key() string { return "email_notify_plugin" } // Desc returns email plugin descripition. func (p *EmailPlugin) Desc() string { return "评论及回复等邮件提醒" } // ToStorage creates plugin storage map for plugin list json. func (p *EmailPlugin) ToStorage() map[string]interface{} { m := make(map[string]interface{}) m["name"] = p.Name() m["description"] = p.Desc() m["is_activate"] = p.isActive return m } // Activate activates email plugin. // It will change activate status to on. // If the handlers are not registered, it will add handlers to router table. func (p *EmailPlugin) Activate() { if p.isHandlerRegistered { p.isActive = true return } if model.Storage.Has("plugin/" + p.Key()) { model.Storage.Get("plugin/"+p.Key(), &p.settings) } // email middleware handler fn := func(context *GoInk.Context) { context.On("comment_created", func(co interface{}) { if !p.isActive { return } go func() { if len(p.settings["smtp_host"]) < 1 || len(p.settings["smtp_email_user"]) < 1 || len(p.settings["smtp_email_password"]) < 1 { println("no setting in smtp email plugin") return } p.sendEmail(co.(*model.Comment), true) }() }) context.On("comment_reply", func(co interface{}) { if !p.isActive { return } go func() { if len(p.settings["smtp_host"]) < 1 || len(p.settings["smtp_email_user"]) < 1 || len(p.settings["smtp_email_password"]) < 1 { fmt.Println("no setting in smtp email plugin") return } p.sendEmail(co.(*model.Comment), false) }() }) } Handler("comment_email_notify", fn, false) p.SetSetting(p.settings) p.isActive = true p.isHandlerRegistered = true } // Deactivate closes this email plugin. func (p *EmailPlugin) Deactivate() { p.isActive = false } // IsActive returns plugin activation status. func (p *EmailPlugin) IsActive() bool { return p.isActive } // Version returns plugin version string. func (p *EmailPlugin) Version() string { return "0.1.5" } // HasSetting returns bool of setting form existing. func (p *EmailPlugin) HasSetting() bool { return true } // Form returns the form template string for email plugin. func (p *EmailPlugin) Form() string { return `

SMTP 邮箱提醒设置

暂不支持验证,请自行保证正确

` } // SetSettings saves plugin settings to json. func (p *EmailPlugin) SetSetting(settings map[string]string) { p.settings = settings model.Storage.Set("plugin/"+p.Key(), p.settings) } func (p *EmailPlugin) sendEmail(co *model.Comment, isCreate bool) { var ( tpl *template.Template buff bytes.Buffer pco *model.Comment content *model.Content err error user *model.User title string from mail.Address to mail.Address ) // get article or page content instance content = model.GetContentById(co.Cid) if content == nil { println("error content getting in email plugin") return } // email for notify new commment creation if co.Pid < 1 { tpl = p.templates["created"] err = tpl.Execute(&buff, map[string]interface{}{ "link": model.GetSetting("site_url"), "site": model.GetSetting("site_title"), "author": co.Author, "text": template.HTML(co.Content), "title": content.Title, "permalink": path.Join(model.GetSetting("site_url"), content.Link()), }) if err != nil { fmt.Println(err) return } user = model.GetUsersByRole("ADMIN")[0] from = mail.Address{"no-reply@" + model.GetSetting("site_url"), p.settings["smtp_email_user"]} to = mail.Address{user.Nick, user.Email} title = co.Author + "在您的网站发表新评论" p.sendSmtp(from, to, title, buff.Bytes()) return } // send mail for the author of comment replying to pco = model.GetCommentById(co.Pid) tpl = p.templates["reply"] err = tpl.Execute(&buff, map[string]interface{}{ "link": model.GetSetting("site_url"), "site": model.GetSetting("site_title"), "author_p": pco.Author, "text_p": template.HTML(pco.Content), "author": co.Author, "text": template.HTML(co.Content), "title": content.Title, "permalink": path.Join(model.GetSetting("site_url"), content.Link()), }) if err != nil { fmt.Println(err) return } user = model.GetUsersByRole("ADMIN")[0] from = mail.Address{pco.Author + "@" + model.GetSetting("site_url"), p.settings["smtp_email_user"]} to = mail.Address{pco.Author, pco.Email} title = "您的评论有了回复" p.sendSmtp(from, to, title, buff.Bytes()) // send email to notice admin new comment creation // this comment is a reply comment if isCreate { go func() { tpl = p.templates["created"] err = tpl.Execute(&buff, map[string]interface{}{ "link": model.GetSetting("site_url"), "site": model.GetSetting("site_title"), "author": co.Author, "text": template.HTML("回复" + pco.Author + ":
" + co.Content), "title": content.Title, "permalink": path.Join(model.GetSetting("site_url"), content.Link()), }) if err != nil { fmt.Println(err) return } user = model.GetUsersByRole("ADMIN")[0] from = mail.Address{"no-reply@" + model.GetSetting("site_url"), p.settings["smtp_email_user"]} to = mail.Address{user.Nick, user.Email} title = co.Author + "在您的网站发表新评论" p.sendSmtp(from, to, title, buff.Bytes()) }() } } // send email via smtp func (p *EmailPlugin) sendSmtp(from mail.Address, to mail.Address, title string, body []byte) { // set email vars b64 := base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") host := p.settings["smtp_host"] email := p.settings["smtp_email_user"] header := make(map[string]string) header["From"] = from.String() header["To"] = to.String() header["Subject"] = fmt.Sprintf("=?UTF-8?B?%s?=", b64.EncodeToString([]byte(title))) header["MIME-Version"] = "1.0" header["Content-Type"] = "text/html; charset=UTF-8" header["Content-Transfer-Encoding"] = "base64" message := "" for k, v := range header { message += fmt.Sprintf("%s: %s\r\n", k, v) } message += "\r\n" + b64.EncodeToString(body) auth := smtp.PlainAuth( "", email, p.settings["smtp_email_password"], strings.Split(host, ":")[0], ) err := smtp.SendMail( host, auth, email, []string{to.Address}, []byte(message), ) println("send to email ", to.String(), fmt.Sprint(err)) } ================================================ FILE: app/plugin/hello.go ================================================ package plugin import ( "fmt" "github.com/fuxiaohei/GoInk" "time" ) type HelloPlugin struct { isActive bool isHandlerRegistered bool } func init() { helloPlugin := new(HelloPlugin) helloPlugin.isActive = true helloPlugin.isHandlerRegistered = false register(helloPlugin) } func (p *HelloPlugin) Name() string { return "Sample Hello Plugin" } func (p *HelloPlugin) Key() string { return "hello_plugin" } func (p *HelloPlugin) Desc() string { return "插件样例,页面最后输出执行时间 注释" } func (p *HelloPlugin) ToStorage() map[string]interface{} { m := make(map[string]interface{}) m["name"] = p.Name() m["description"] = p.Desc() m["is_activate"] = p.isActive return m } func (p *HelloPlugin) Activate() { if p.isHandlerRegistered { p.isActive = true return } fn := func(context *GoInk.Context) { now := time.Now() context.On(GoInk.CONTEXT_RENDERED, func() { if p.isActive { duration := time.Since(now) str := fmt.Sprint(duration) //context.Body = append(context.Body, []byte(str)...) context.Header["X-Exec-Time"] = str } }) } Handler("hello_plugin", fn, false) /*Route("hello_handler", "GET", "/hello/", func(context *GoInk.Context) { context.Body = []byte("Hello!") })*/ p.isHandlerRegistered = true p.isActive = true } func (p *HelloPlugin) Deactivate() { p.isActive = false } func (p *HelloPlugin) IsActive() bool { return p.isActive } func (p *HelloPlugin) Version() string { return "0.0.1" } func (p *HelloPlugin) HasSetting() bool { return false } func (p *HelloPlugin) Form() string { return "" } func (p *HelloPlugin) SetSetting(settings map[string]string) { } ================================================ FILE: app/plugin/plugin.go ================================================ package plugin import ( "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" ) type PluginInterface interface { Name() string Key() string Desc() string Version() string Activate() Deactivate() IsActive() bool HasSetting() bool Form() string SetSetting(settings map[string]string) ToStorage() map[string]interface{} } type pluginRoute struct { Method string Pattern string Handler GoInk.Handler } var ( pluginStorage map[string]map[string]interface{} pluginMap map[string]PluginInterface middleHandler map[string]GoInk.Handler interHandler map[string]GoInk.Handler usedHandler map[string]map[string]bool routeHandler map[string]pluginRoute ) func init() { if pluginMap == nil { pluginMap = make(map[string]PluginInterface) } //pluginMap = make(map[string]PluginInterface) pluginStorage = make(map[string]map[string]interface{}) middleHandler = make(map[string]GoInk.Handler) routeHandler = make(map[string]pluginRoute) interHandler = make(map[string]GoInk.Handler) usedHandler = make(map[string]map[string]bool) usedHandler["middle"] = make(map[string]bool) usedHandler["inter"] = make(map[string]bool) usedHandler["route"] = make(map[string]bool) } func Init() { var isChanged = false if model.Storage.Has("plugins") { model.Storage.Get("plugins", &pluginStorage) } // activate for k, p := range pluginMap { _, ok := pluginStorage[k] if !ok { pluginStorage[k] = p.ToStorage() isChanged = true } if pluginStorage[k]["is_activate"].(bool) { p.Activate() } else { p.Deactivate() } } // clean deleted for k, _ := range pluginStorage { if pluginMap[k] == nil { delete(pluginStorage, k) isChanged = true } } if isChanged { model.Storage.Set("plugins", pluginStorage) } } func register(plugin PluginInterface) { if pluginMap == nil { pluginMap = make(map[string]PluginInterface) } pluginMap[plugin.Key()] = plugin } func Handler(name string, h GoInk.Handler, inter bool) { if inter { interHandler[name] = h } else { middleHandler[name] = h } } func Route(name string, method string, pattern string, handler GoInk.Handler) { pr := pluginRoute{} pr.Method = method pr.Handler = handler pr.Pattern = pattern routeHandler[name] = pr } func Handlers() (map[string]map[string]GoInk.Handler, map[string]pluginRoute) { m := make(map[string]map[string]GoInk.Handler) m["middle"] = middleHandler m["inter"] = interHandler return m, routeHandler } func GetPlugins() map[string]PluginInterface { return pluginMap } func GetPluginByKey(key string) PluginInterface { return pluginMap[key] } func Activate(name string) { p, ok := pluginMap[name] if !ok { println("activate null plugin " + name) return } p.Activate() pluginStorage[p.Key()] = p.ToStorage() model.Storage.Set("plugins", pluginStorage) println("activate", p.Key()) } func Deactivate(name string) { p, ok := pluginMap[name] if !ok { println("deactivate null plugin " + name) return } p.Deactivate() pluginStorage[p.Key()] = p.ToStorage() model.Storage.Set("plugins", pluginStorage) println("deactivate", p.Key()) } func Update(app *GoInk.App) { pluginHandlers, routeHandlers := Handlers() if len(routeHandlers) > 0 { for n, h := range routeHandlers { if usedHandler["route"][n] { continue } app.Route(h.Method, h.Pattern, h.Handler) usedHandler["route"][n] = true } } if len(pluginHandlers["middle"]) > 0 { for n, h := range pluginHandlers["middle"] { if usedHandler["middle"][n] { continue } app.Use(h) usedHandler["middle"][n] = true //println("use plugin middle handler",n) } //fmt.Println(usedHandler) } if len(pluginHandlers["inter"]) > 0 { for name, h := range pluginHandlers["inter"] { if usedHandler["inter"][name] { continue } if name == "static" { app.Static(h) usedHandler["inter"][name] = true continue } if name == "recover" { app.Recover(h) usedHandler["inter"][name] = true continue } if name == "notfound" { app.NotFound(h) usedHandler["inter"][name] = true continue } } } } ================================================ FILE: app/upgrade/v20140130.go ================================================ package upgrade import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoBlog/app/plugin" "github.com/fuxiaohei/GoInk" "os" "path" ) func init() { cmd.SetUpgradeScript(20140130, upgrade_20140130) } func upgrade_20140130(app *GoInk.App) bool { // change settings model.LoadSettings() model.SetSetting("c_footer_ga", "") model.SetSetting("enable_go_markdown", "false") model.SetSetting("enable_go_markdown_def", "false") model.SetSetting("site_theme", "default") model.SetSetting("site_theme_def", "default") model.SetSetting("c_home_avatar", "/static/img/site.png") model.SyncSettings() // init plugin plugin.Init() model.Storage.Dir("plugin") // remove static files os.RemoveAll(app.Get("view_dir")) os.RemoveAll(path.Join(app.Get("static_dir"), "less")) os.RemoveAll(path.Join(app.Get("static_dir"), "css")) os.RemoveAll(path.Join(app.Get("static_dir"), "img")) os.RemoveAll(path.Join(app.Get("static_dir"), "js")) os.RemoveAll(path.Join(app.Get("static_dir"), "lib")) os.Remove(path.Join(app.Get("static_dir"), "favicon.ico")) // extract current static files cmd.ExtractBundleBytes() // "c_footer_ga": "", // "enable_go_markdown": "true", // "enable_go_markdown_def": "false", // "site_theme": "ling", // "site_theme_def": "default", return true } ================================================ FILE: app/upgrade/v20140131.go ================================================ package upgrade import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoInk" "os" "path" ) func init() { cmd.SetUpgradeScript(20140131, upgrade_20140131) } func upgrade_20140131(app *GoInk.App) bool { // re-write all data to non-indent json /*model.All() model.SyncContents() model.SyncFiles() model.SyncReaders() model.SyncSettings() model.SyncTokens() model.SyncUsers() model.SyncVersion()*/ // update ling template os.RemoveAll(path.Join(app.Get("view_dir"), "ling")) cmd.ExtractBundleBytes() return true } ================================================ FILE: app/upgrade/v20140209.go ================================================ package upgrade import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" "os" "path" ) func init() { cmd.SetUpgradeScript(20140209, upgrade_20140209) } func upgrade_20140209(app *GoInk.App) bool { // clean template vDir := app.Get("view_dir") os.Remove(path.Join(vDir, "admin.layout")) os.Remove(path.Join(vDir, "cmd.layout")) // write default menu setting model.DefaultNavigators() // write message storage model.Storage.Set("messages",[]*model.Message{}) cmd.ExtractBundleBytes() return true } ================================================ FILE: app/upgrade/v20140228.go ================================================ package upgrade import ( "github.com/fuxiaohei/GoBlog/app/cmd" "github.com/fuxiaohei/GoBlog/app/model" "github.com/fuxiaohei/GoInk" ) func init() { cmd.SetUpgradeScript(20140228, upgrade_20140228) } func upgrade_20140228(_ *GoInk.App) bool { // change settings model.LoadSettings() model.SetSetting("popular_size", "4") model.SetSetting("recent_comment_size", "3") model.SetSetting("theme_cache", "false") model.SyncSettings() // overwrite zip bundle bytes cmd.ExtractBundleBytes() return true } ================================================ FILE: app/utils/avatar.go ================================================ package utils import ( "crypto/md5" "fmt" ) // generate gravatar link by email. func Gravatar(email string, size string) string { u := "http://1.gravatar.com/avatar/" u += encodeAvatarEmail(email) + "?s=" + size return u } // encode user password by sha1 with salt string from config. func encodeAvatarEmail(email string) string { h := md5.New() h.Write([]byte(email)) bs := h.Sum(nil) return fmt.Sprintf("%x", bs) } ================================================ FILE: app/utils/crypto.go ================================================ package utils import ( "crypto/sha1" "fmt" "io" ) func Sha1(raw string) string { t := sha1.New() io.WriteString(t, raw) return fmt.Sprintf("%x", t.Sum(nil)) } ================================================ FILE: app/utils/date.go ================================================ package utils import ( "fmt" "strconv" "strings" "time" ) // Format unix time int64 to string func DateInt64(ti int64, format string) string { t := time.Unix(int64(ti), 0) return DateTime(t, format) } // Format unix time string to string func DateString(ts string, format string) string { i, _ := strconv.ParseInt(ts, 10, 64) return DateInt64(i, format) } // Format time.Time struct to string // MM - month - 01 // M - month - 1, single bit // DD - day - 02 // D - day 2 // YYYY - year - 2006 // YY - year - 06 // HH - 24 hours - 03 // H - 24 hours - 3 // hh - 12 hours - 03 // h - 12 hours - 3 // mm - minute - 04 // m - minute - 4 // ss - second - 05 // s - second = 5 func DateTime(t time.Time, format string) string { res := strings.Replace(format, "MM", t.Format("01"), -1) res = strings.Replace(res, "M", t.Format("1"), -1) res = strings.Replace(res, "DD", t.Format("02"), -1) res = strings.Replace(res, "D", t.Format("2"), -1) res = strings.Replace(res, "YYYY", t.Format("2006"), -1) res = strings.Replace(res, "YY", t.Format("06"), -1) res = strings.Replace(res, "HH", fmt.Sprintf("%02d", t.Hour()), -1) res = strings.Replace(res, "H", fmt.Sprintf("%d", t.Hour()), -1) res = strings.Replace(res, "hh", t.Format("03"), -1) res = strings.Replace(res, "h", t.Format("3"), -1) res = strings.Replace(res, "mm", t.Format("04"), -1) res = strings.Replace(res, "m", t.Format("4"), -1) res = strings.Replace(res, "ss", t.Format("05"), -1) res = strings.Replace(res, "s", t.Format("5"), -1) return res } // Get unix stamp int64 of now func Now() int64 { return time.Now().Unix() } ================================================ FILE: app/utils/file.go ================================================ package utils import ( "fmt" "os" ) func FileSize(size int64) string { s := float64(size) if s > 1024*1024 { return fmt.Sprintf("%.1f M", s/(1024*1024)) } if s > 1024 { return fmt.Sprintf("%.1f K", s/1024) } return fmt.Sprintf("%f B", s) } func IsFile(path string) bool { f, e := os.Stat(path) if e != nil { return false } if f.IsDir() { return false } return true } func IsDir(path string) bool { f, e := os.Stat(path) if e != nil { return false } return f.IsDir() } ================================================ FILE: app/utils/html.go ================================================ package utils import ( "github.com/russross/blackfriday" "html/template" "regexp" "strings" ) func Html2str(html string) string { src := string(html) //将HTML标签全转换成小写 re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllStringFunc(src, strings.ToLower) //去除STYLE re, _ = regexp.Compile("\\") src = re.ReplaceAllString(src, "") //去除SCRIPT re, _ = regexp.Compile("\\") src = re.ReplaceAllString(src, "") //去除所有尖括号内的HTML代码,并换成换行符 re, _ = regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllString(src, "\n") //去除连续的换行符 re, _ = regexp.Compile("\\s{2,}") src = re.ReplaceAllString(src, "\n") return strings.TrimSpace(src) } func Markdown2Html(text string) string { return string(blackfriday.MarkdownCommon([]byte(text))) } func Markdown2HtmlTemplate(text string) template.HTML { return template.HTML(Markdown2Html(text)) } ================================================ FILE: app/utils/pager.go ================================================ package utils type Pager struct { Current int Size int Total int Pages int PageSlice []int Begin int End int Prev int Next int IsPrev bool IsNext bool } func NewPager(page, size, total int) *Pager { if page < 1 { page = 1 } p := new(Pager) p.Current = page p.Size = size p.Total = total p.Pages = total / size if total%size > 0 { p.Pages += 1 } p.PageSlice = make([]int, p.Pages) for i := 1; i <= p.Pages; i++ { p.PageSlice[i-1] = i } p.Begin = (page-1)*size + 1 if p.Begin < 1 { p.Begin = 1 } if p.Begin > p.Total { p.Begin = p.Total } p.End = page * size if p.End > p.Total { p.End = p.Total } p.Prev = p.Current - 1 p.IsPrev = true if p.Prev < 1 { p.Prev = 1 p.IsPrev = false } p.Next = p.Current + 1 p.IsNext = true if p.Next > p.Pages { p.Next = p.Pages p.IsNext = false } return p } ================================================ FILE: app/utils/sorter.go ================================================ package utils import "sort" type intSorter [][2]int func (is intSorter) Len() int { return len(is) } func (is intSorter) Swap(i, j int) { is[i], is[j] = is[j], is[i] } func (is intSorter) Less(i,j int)bool{ return is[i][1] > is[j][1] } // Sort [][2]int by the second element of [2]. func SortInt(s [][2]int){ sort.Sort(intSorter(s)) } ================================================ FILE: app/utils/validator.go ================================================ package utils import ( "regexp" "strings" ) var ( regexEmail *regexp.Regexp regexASCII *regexp.Regexp regexEnglish *regexp.Regexp regexURL *regexp.Regexp ) func init() { regexEmail, _ = regexp.Compile(`(?i)[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}`) regexASCII, _ = regexp.Compile(`^[a-zA-Z0-9-]+$`) regexEnglish, _ = regexp.Compile(`^[a-zA-Z]+$`) regexURL, _ = regexp.Compile(`(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?`) } func IsEmptyString(str string) bool { return len(str) == 0 } func IsEmail(str string) bool { return regexEmail.MatchString(str) } func IsURL(str string) bool { return regexURL.MatchString(str) } func IsLonger(str string, length int) bool { return len(str) > length } func IsShorter(str string, length int) bool { return len(str) < length } func IsASCII(str string) bool { return regexASCII.MatchString(str) } func IsEnglish(str string) bool { return regexEnglish.MatchString(str) } func IsContain(str string, contain string) bool { return strings.Contains(str, contain) } ================================================ FILE: main.go ================================================ package main import "github.com/fuxiaohei/GoBlog/app" func main() { app.Cmd() app.Init() app.Run() } ================================================ FILE: static/css/admin.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad}#header{height:39px;background-color:#fff;border-bottom:1px solid #999;line-height:39px;box-shadow:0 0 2px #ccc;-moz-box-shadow:0 0 2px #ccc;-webkit-box-shadow:0 0 2px #ccc}#header .nav>a{display:inline-block;padding:0 18px;border-left:1px solid #ccc;border-right:1px solid #ccc;color:#666;margin-left:-1px}#header .nav>a:hover{border-color:#0079bc;background-color:#0079bc;color:#fbfbfb}#header .logo{line-height:36px;padding:0 14px 0 0;margin:0;font-size:14px}#header .nav-item{display:inline-block;padding:0 18px;border-left:1px solid #ccc;border-right:1px solid #ccc;color:#666;margin-right:-1px}#header .nav-item:hover{background-color:#eee}#header .out{color:#c7383a}#header .out:hover{border-color:#e64346;background-color:#e64346;color:#fbfbfb}#footer{padding:24px;background:#f6f6f6;border-top:1px solid #ddd;margin-top:30px;color:#999;font-size:12px}#footer p{margin-bottom:0}#footer a{color:#999;padding:6px 12px}#footer a:hover{border-bottom:1px dashed #bbb}.admin{margin:24px auto 48px auto}#profile{width:800px;margin:24px auto 48px auto}#profile .avatar img{width:180px;padding:4px;background-color:#fff;border:1px solid #ddd;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;height:180px}#profile .ipt{width:280px}#profile .invalid{margin-left:75px}#profile .bio{margin-left:75px;height:160px}#password{width:400px;margin:24px auto 48px auto}#password .invalid{margin-left:75px}#article-list{margin-bottom:24px}#article-list li{margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd}#article-list li>*{margin-right:16px}#article-list li .time,#article-list li .comment{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;color:#999}#article-list li .comment{color:#649462}#article-list li .comment .fa{margin-right:6px}#article-list li .is-comment{color:#ff4447}#article-list li .is-comment .fa{margin-right:6px}#article-list li .del,#article-list li .edit{opacity:0}#article-list li:hover .del,#article-list li:hover .edit{opacity:1}#article-list li:first-child h4{padding-top:0}#article-form{margin:24px auto 48px auto}#article-form input.title{width:100%;box-sizing:border-box;border-bottom:none;margin-bottom:-1px;font-size:18px}#article-form select{padding:4px 6px}#article-form .preview{border:1px solid #999;background-color:#fff;box-sizing:border-box;padding:0 12px;height:700px;margin-left:-1px;border-radius:2px;overflow-x:scroll}#article-form .form-vertical{width:100%;margin-top:18px}#article-form .form-vertical input.ipt{width:300px}#article-form .form-vertical .item{float:left;margin-right:18px}#article-form .form-vertical .btn{margin-right:16px}#article-form .form-vertical .invalid{display:inline}#article-form .file-progress{padding:0 12px;background:rgba(0,150,223,0.2);color:#666;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;box-sizing:border-box;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}#article-form .file-progress.err{background:rgba(255,68,71,0.2);color:#aa393c}#setting-nav{width:1000px;margin-top:24px;margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#setting-nav li{display:inline-block;margin:0 12px}#setting-nav li a{padding:3px 10px}#setting-nav li a:hover,#setting-nav li a.current{border-bottom:2px solid #005b9b}.setting-panel{display:none}.setting-form{width:820px;margin:24px auto 48px auto}.setting-form .ipt{width:480px}.setting-form .invalid{margin-left:75px}.setting-form label{min-width:10em}.setting-form .tip.block{margin-left:12em}#setting-custom-form{width:1000px}#setting-custom-form input.key{width:240px}#setting-custom-form input.value{width:640px}#setting-custom-form .item{margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#setting-custom-form .del{margin-left:12px;color:#e64346;font-size:12px}#setting-custom-form .tip{margin-left:0}#setting-nav-form{width:1000px}#setting-nav-form .item{margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#setting-nav-form span.label{margin-right:6px}#setting-nav-form input.order{width:2.5em;min-width:0}#setting-nav-form input.text{width:80px;min-width:0}#setting-nav-form input.title{width:150px;min-width:0}#setting-nav-form input.link{width:340px}#setting-nav-form .del{margin-left:12px;color:#e64346}#comment-list .c-avatar{width:48px;height:48px;padding:2px;border:1px solid #ccc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;margin-right:18px}#comment-list .comment{margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#comment-list .c-meta>*{margin-right:16px}#comment-list .c-time{color:#999;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#comment-list .c-time .fa{margin-right:6px}#comment-list .c-cnt,#comment-list .c-email{color:#999;font-size:12px}#comment-list .c-author{font-size:13px}#comment-list .c-author.admin{background-color:#e64346;color:#fbfbfb}#comment-list .c-p-md{margin-top:8px;font-size:12px;line-height:18px;color:#666}#comment-list .c-section{max-width:830px}#comment-list .c-check,#comment-list .c-del{color:#e64346}#comment-list .c-check .fa,#comment-list .c-del .fa{margin-right:6px}#comment-list .c-check:hover,#comment-list .c-del:hover{color:#aa393c}#comment-list .c-reply,#comment-list .c-check,#comment-list .c-del{font-size:12px}#comment-form{padding-top:12px;display:none;margin-left:72px}#comment-form .btn{margin-right:24px}#comment-content{width:500px;height:80px;margin-right:24px}#files-list li.file{margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd}#files-list li.file>*{margin-right:16px}#files-list li.file:hover .del{opacity:1 !important}#files-list .upload-time{color:#999;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#files-list .del{color:#e64346}#files-list .file-progress{padding:0 12px;background:rgba(0,150,223,0.2);color:#666;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;box-sizing:border-box;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}#files-list .file-progress.err{background:rgba(255,68,71,0.2);color:#aa393c}#files-list .size{width:4em;display:inline-block}#plugin-list li{margin-bottom:16px;padding-bottom:16px;border-bottom:1px dashed #ddd}#plugin-list li .desc{margin-bottom:0;width:99%;color:#999}#plugin-list li a.lbl{padding:0 8px;margin-left:16px}#plugin-list li .version{color:#507650;margin-left:16px}#plugin-list li .name{font-size:16px}#plugin-list li .active{width:12px;height:12px;margin-right:16px;padding:0;margin-top:10px}#plugin-list li .setting{margin-left:16px}#plugin-setting-form p.item{clear:both}#plugin-setting-form label{float:left;min-width:6em;text-align:right;margin-right:2em}#plugin-setting-form .title{padding-top:0;margin-bottom:18px}#plugin-setting-form input.ipt{width:600px}#dashboard .grid-1-5{margin-right:2%}#dashboard .quick-link li{list-style:inside disc;margin-bottom:6px;padding-bottom:6px;border-bottom:1px dashed #ddd}#dashboard .stats .lbl{padding:1px 5px;margin:0 3px}#dashboard .activity .msg{padding:8px 12px;margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd;line-height:24px;font-size:12px}#dashboard .activity .msg .time{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#dashboard .activity .msg .data{color:#666;margin-left:1.2em}#dashboard .activity .msg .data p{margin-bottom:0;line-height:24px}#dashboard .activity .msg .read{top:0;right:12px;opacity:0}#dashboard .activity .msg .read:hover{color:#e64346}#dashboard .activity .msg:hover{background:rgba(0,150,223,0.06)}#dashboard .activity .msg:hover .read{opacity:1} ================================================ FILE: static/css/cmd.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad}.cmd{margin:24px 48px}.cmd-header{margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#backup-btn,#theme-cache-btn{margin:10px 0 0 30px;min-width:0;padding:0 2em}#theme-cache-btn{background-color:#e64346;color:#fbfbfb}#theme-cache-btn:hover{background-color:#c7383a}#theme-cache-btn.true{background-color:#7ab277;color:#fbfbfb}#theme-cache-btn.true:hover{background-color:#649462}.cmd-list li{margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed #ddd}#backup-list li{list-style:disc inside;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#backup-list li>span,#backup-list li>a{margin-right:16px}#backup-list li .del{color:#e64346;opacity:0}#backup-list li .link{margin-left:12px}#backup-list li:hover .del{opacity:1}#message-list .message{padding:8px 12px;margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd;line-height:24px;font-size:12px}#message-list .message .time{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#message-list .message .data{color:#666;margin-left:1.2em}#message-list .message .data p{margin-bottom:0;line-height:24px}#message-list .message .read{top:0;right:12px;opacity:0}#message-list .message .read:hover{color:#e64346}#message-list .message:hover .read{opacity:1}#log-list .log{font-size:12px}#log-list .name{margin-right:1.5em;font-weight:bold}#log-list .time,#log-list .name{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#log-list .text{line-height:20px;font-family:Consolas,"Courier New",Arial;color:#666;padding:8px 12px;background:#f3f3f3}#log-list .remove{top:0;right:12px;color:#e64346}#theme-list span{margin-left:12px}#theme-list span.file{color:#0079bc}#theme-list span.error-file{color:#c7383a}#theme-list h5{cursor:pointer}#reader-list li>*{margin-right:18px}#reader-list .email{color:#999}#reader-list .comments{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;font-size:12px;padding:2px 6px} ================================================ FILE: static/css/codemirror.css ================================================ /* BASICS */ .CodeMirror { /* Set height, width, borders, and global font properties here */ font-family: Consolas, "Microsoft YaHei", "Courier New", Arial; height: 660px; font-size: 13px; border:1px solid #999; } .CodeMirror-scroll { /* Set scrolling behaviour here */ overflow: auto; } /* PADDING */ .CodeMirror-lines { padding: 4px 0; /* Vertical padding around content */ } .CodeMirror pre { padding: 0 4px; /* Horizontal padding of content */ } .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { background-color: white; /* The little square between H and V scrollbars */ } /* GUTTER */ .CodeMirror-gutters { border-right: 1px solid #ddd; background-color: #f7f7f7; white-space: nowrap; } .CodeMirror-linenumbers { } .CodeMirror-linenumber { padding: 0 3px 0 5px; min-width: 20px; text-align: right; color: #555; line-height: 20px; } /* CURSOR */ .CodeMirror div.CodeMirror-cursor { border-left: 1px solid black; z-index: 3; } /* Shown when moving in bi-directional text */ .CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; } .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { width: auto; border: 0; background: #7e7; z-index: 1; } /* Can style cursor different in overwrite (non-insert) mode */ .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite { } .cm-tab { display: inline-block; } /* DEFAULT THEME */ .cm-s-default .cm-keyword { color: #708; } .cm-s-default .cm-atom { color: #219; } .cm-s-default .cm-number { color: #164; } .cm-s-default .cm-def { color: #00f; } .cm-s-default .cm-variable { color: black; } .cm-s-default .cm-variable-2 { color: #05a; } .cm-s-default .cm-variable-3 { color: #085; } .cm-s-default .cm-property { color: black; } .cm-s-default .cm-operator { color: black; } .cm-s-default .cm-comment { color: #a50; } .cm-s-default .cm-string { color: #a11; } .cm-s-default .cm-string-2 { color: #f50; } .cm-s-default .cm-meta { color: #555; } .cm-s-default .cm-qualifier { color: #555; } .cm-s-default .cm-builtin { color: #30a; } .cm-s-default .cm-bracket { color: #997; } .cm-s-default .cm-tag { color: #170; } .cm-s-default .cm-attribute { color: #00c; } .cm-s-default .cm-header { color: blue; } .cm-s-default .cm-quote { color: #090; } .cm-s-default .cm-hr { color: #999; } .cm-s-default .cm-link { color: #00c; } .cm-negative { color: #d44; } .cm-positive { color: #292; } .cm-header, .cm-strong { font-weight: bold; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-s-default .cm-error { color: #f00; } .cm-invalidchar { color: #f00; } div.CodeMirror span.CodeMirror-matchingbracket { color: #0f0; } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: #f22; } .CodeMirror-activeline-background { background: #e8f2ff; } /* STOP */ /* The rest of this file contains styles related to the mechanics of the editor. You probably shouldn't touch them. */ .CodeMirror { line-height: 1; position: relative; overflow: hidden; background: white; color: black; } .CodeMirror-scroll { /* 30px is the magic margin used to hide the element's real scrollbars */ /* See overflow: hidden in .CodeMirror */ margin-bottom: -30px; margin-right: -30px; padding-bottom: 30px; padding-right: 30px; height: 100%; outline: none; /* Prevent dragging from highlighting the element */ position: relative; -moz-box-sizing: content-box; box-sizing: content-box; } .CodeMirror-sizer { position: relative; } /* The fake, visible scrollbars. Used to force redraw during scrolling before actuall scrolling happens, thus preventing shaking and flickering artifacts. */ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 6; display: none; } .CodeMirror-vscrollbar { right: 0; top: 0; overflow-x: hidden; overflow-y: scroll; } .CodeMirror-hscrollbar { bottom: 0; left: 0; overflow-y: hidden; overflow-x: scroll; } .CodeMirror-scrollbar-filler { right: 0; bottom: 0; } .CodeMirror-gutter-filler { left: 0; bottom: 0; } .CodeMirror-gutters { position: absolute; left: 0; top: 0; padding-bottom: 30px; z-index: 3; } .CodeMirror-gutter { white-space: normal; height: 100%; -moz-box-sizing: content-box; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; /* Hack to make IE7 behave */ *zoom: 1; *display: inline; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-lines { cursor: text; } .CodeMirror pre { /* Reset some styles that the rest of the page might have set */ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border-width: 0; background: transparent; font-family: inherit; font-size: inherit; margin: 0; line-height: 20px; color: inherit; z-index: 2; position: relative; overflow: visible; word-wrap: break-word; white-space: pre-wrap; word-break: break-all; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-code pre { width: -webkit-fit-content; width: -moz-fit-content; width: fit-content; } .CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; } .CodeMirror-linebackground { position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-widget { } .CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; } .CodeMirror-measure { position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden; } .CodeMirror-measure pre { position: static; } .CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0; } .CodeMirror-focused div.CodeMirror-cursor { visibility: visible; } .CodeMirror-selected { background: #d9d9d9; } .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } .cm-searching { background: #ffa; background: rgba(255, 255, 0, .4); } /* IE7 hack to prevent it from returning funny offsetTops on the spans */ .CodeMirror span { *vertical-align: text-bottom; } @media print { /* Hide the cursor when printing */ .CodeMirror div.CodeMirror-cursor { visibility: hidden; } } .cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; } .cm-s-base16-dark div.CodeMirror-selected { background: #202020 !important; } .cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; } .cm-s-base16-dark .CodeMirror-linenumber { color: #555; } .cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0 !important; } .cm-s-base16-dark span.cm-comment { color: #8f5536; } .cm-s-base16-dark span.cm-atom { color: #aa759f; } .cm-s-base16-dark span.cm-number { color: #aa759f; } .cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; } .cm-s-base16-dark span.cm-keyword { color: #ac4142; } .cm-s-base16-dark span.cm-string { color: #f4bf75; } .cm-s-base16-dark span.cm-variable { color: #90a959; } .cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; } .cm-s-base16-dark span.cm-def { color: #d28445; } .cm-s-base16-dark span.cm-bracket { color: #e0e0e0; } .cm-s-base16-dark span.cm-tag { color: #ac4142; } .cm-s-base16-dark span.cm-link { color: #aa759f; } .cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; } .cm-s-base16-dark .CodeMirror-activeline-background { background: #2F2F2F !important; } .cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } ================================================ FILE: static/css/common.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad} ================================================ FILE: static/css/highlight.css ================================================ /* Sunburst-like style (c) Vasily Polovnyov */ pre code { display: block; padding: 0.5em; background: #000; color: #f8f8f8; } pre .comment, pre .template_comment, pre .javadoc { color: #aeaeae; font-style: italic; } pre .keyword, pre .ruby .function .keyword, pre .request, pre .status, pre .nginx .title { color: #E28964; } pre .function .keyword, pre .sub .keyword, pre .method, pre .list .title { color: #99CF50; } pre .string, pre .tag .value, pre .cdata, pre .filter .argument, pre .attr_selector, pre .apache .cbracket, pre .date, pre .tex .command, pre .coffeescript .attribute { color: #65B042; } pre .subst { color: #DAEFA3; } pre .regexp { color: #E9C062; } pre .title, pre .sub .identifier, pre .pi, pre .tag, pre .tag .keyword, pre .decorator, pre .shebang, pre .prompt { color: #89BDFF; } pre .class .title, pre .haskell .type, pre .smalltalk .class, pre .javadoctag, pre .yardoctag, pre .phpdoc { text-decoration: underline; } pre .symbol, pre .ruby .symbol .string, pre .number { color: #3387CC; } pre .params, pre .variable, pre .clojure .attribute { color: #3E87E3; } pre .css .tag, pre .rules .property, pre .pseudo, pre .tex .special { color: #CDA869; } pre .css .class { color: #9B703F; } pre .rules .keyword { color: #C5AF75; } pre .rules .value { color: #CF6A4C; } pre .css .id { color: #8B98AB; } pre .annotation, pre .apache .sqbracket, pre .nginx .built_in { color: #9B859D; } pre .preprocessor, pre .pragma { color: #8996A8; } pre .hexcolor, pre .css .value .number { color: #DD7B3B; } pre .css .function { color: #DAD085; } pre .diff .header, pre .chunk, pre .tex .formula { background-color: #0E2231; color: #F8F8F8; font-style: italic; } pre .diff .change { background-color: #4A410D; color: #F8F8F8; } pre .addition { background-color: #253B22; color: #F8F8F8; } pre .deletion { background-color: #420E09; color: #F8F8F8; } pre .coffeescript .javascript, pre .javascript .xml, pre .tex .formula, pre .xml .javascript, pre .xml .vbscript, pre .xml .css, pre .xml .cdata { opacity: 0.5; } pre .go .typename{ color: #ffbc54; } ================================================ FILE: static/css/ling.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad}html,body{background:#f3f3f3}#header{background:#0093c4;min-width:120px;padding:40px 0 48px 0;color:#fbfbfb}#header a:hover{color:#fff;text-shadow:0 0 3px #333;-moz-text-shadow:0 0 3px #333;-webkit-text-shadow:0 0 3px #333}#header-img{width:96px;height:96px;border-radius:50px;-moz-border-radius:50px;-webkit-border-radius:50px}#header-h{line-height:94px;color:#fbfbfb;padding:0;margin-left:24px}#header-h a{color:#fbfbfb}#header-sub{color:#f3f3f3;margin-left:1.2em;font-size:16px}#nav{line-height:90px}#nav li{line-height:50px;margin-left:44px}#nav li a{font-size:18px;color:#f3f3f3;display:block}#nav li a:hover{color:#fff;text-shadow:0 0 3px #333;-moz-text-shadow:0 0 3px #333;-webkit-text-shadow:0 0 3px #333}#footer{padding:30px 40px;color:#999}#main{margin:30px auto}#go-top{bottom:50px;right:40px;position:fixed;color:#fff;padding-top:6px;padding-bottom:8px;opacity:.4}#article-container{height:100%}#article-container .comments,#article-container .views{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#article-container .comments{width:56px;height:56px;border-radius:36px;-moz-border-radius:36px;-webkit-border-radius:36px;line-height:56px;font-size:24px;padding:0;margin-top:40px;margin-left:8px;border:6px solid #fff;box-shadow:0 0 2px #999;-moz-box-shadow:0 0 2px #999;-webkit-box-shadow:0 0 2px #999}#article-container .comments a{color:#fff}#article-container .comments:hover{box-shadow:0 0 4px #666;-moz-box-shadow:0 0 4px #666;-webkit-box-shadow:0 0 4px #666}#article-container .views{top:14px;left:0;width:36px;height:36px;line-height:36px;border-radius:30px;-moz-border-radius:30px;-webkit-border-radius:30px;padding:0;border:4px solid #fff;box-shadow:0 0 2px #999;-moz-box-shadow:0 0 2px #999;-webkit-box-shadow:0 0 2px #999}#article-container .main{margin-left:116px;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;box-shadow:0 1px 2px #bbb;-moz-box-shadow:0 1px 2px #bbb;-webkit-box-shadow:0 1px 2px #bbb;background:#fff;padding:18px 24px}#article-container .main:before{content:"";display:block;border:11px solid transparent;border-right-color:#fff;position:absolute;top:63px;left:-22px}#article-container .main h3.title{font-size:28px;padding-bottom:24px}#article-container .main .time-info{color:#999;margin-bottom:20px;padding-bottom:20px;border-bottom:1px dashed #ddd;text-indent:1em;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#article-container article{margin-bottom:50px}#article-container .article-single .main{margin-left:0}#article-container .article-single .main:before{display:none}#article-container .article-single .meta{right:44px;top:-36px}#article-container .article-single .views{width:56px;height:56px;border-radius:36px;-moz-border-radius:36px;-webkit-border-radius:36px;line-height:56px;font-size:24px;padding:0;border:6px solid #fff}#article-container .tag a{margin:0 4px;color:#999}#article-pager{margin-left:116px}#article-pager .item{margin:0;color:#fff;background:#999;padding:12px 18px;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px}#article-pager .item:hover{background:#0079bc}#comment{border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;box-shadow:0 1px 2px #bbb;-moz-box-shadow:0 1px 2px #bbb;-webkit-box-shadow:0 1px 2px #bbb;background:#fff;padding:18px 24px}#comment .meta{right:-24px;top:-30px}#comment .meta .comments{margin-left:0;margin-top:0}#comment-list .comment{margin-bottom:32px}#comment-list .c-avatar{margin-right:18px;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;margin-top:6px}#comment-list .c-meta p{margin-bottom:0}#comment-list .c-meta .c-time{color:#999;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#comment-list .c-meta .c-author{font-size:16px;color:#333;display:block}#comment-list .c-meta .c-author:hover{color:#005b9b}#comment-list .c-meta .c-reply{color:#fff;background:#ddd;padding:3px 10px}#comment-list .c-meta .c-reply:hover{background-color:#0079bc}#comment-list .c-content{padding-top:4px}#comment-list .c-check{font-size:13px;color:#e64346;margin-left:12px}#comment-list .c-p-md{margin-top:12px;font-size:12px;line-height:20px;color:#666}#comment-show{margin-bottom:32px}#comment-title{margin-bottom:20px;padding-bottom:20px;border-bottom:1px dashed #ddd}#comment-form{width:80%;margin:auto;margin-bottom:30px}#comment-form .c-info{width:26%}#comment-form .c-info .ipt{width:100%;box-sizing:border-box;min-width:0}#comment-form .c-content{width:70%}#comment-form .c-avatar{border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;margin-top:6px;width:50px}#comment-form .reply-md{margin-bottom:16px;font-size:12px;line-height:20px;color:#666}#comment-form .cancel-reply{border:none;margin-left:18px;display:none}#comment-form .cancel-reply:hover{cursor:pointer}#comment-content{width:100%;box-sizing:border-box;height:180px;resize:none}@media only screen and (max-width:960px){.container960{padding:0 24px;width:auto}}@media only screen and (max-width:760px){.container960{padding:0 24px;width:auto}#article-container .main{margin-left:0}#article-container .meta{display:none}#article-container .main:before{display:none}#comment-form .c-info,#comment-form .c-content{width:100%;float:left}#comment-form .c-info{text-align:left}#nav,#header-h{line-height:50px}#footer span{float:none;text-align:center}#article-pager{margin-left:0}}@media only screen and (max-width:560px){.container960{padding:0;width:auto}#article-pager{margin:0 12px}#header-h{margin-left:24px}#header-img{display:none}#comment-form{width:100%}#nav{float:left;margin-left:24px}#nav li{margin-left:0;margin-right:44px}#footer span{float:none;display:block}}@media only screen and (max-width:480px){#header-sub{display:none}} ================================================ FILE: static/css/saber.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad}html,body{background:#f9f9f9}#header{background:#fff;box-shadow:0 0 4px #666;line-height:60px;padding:12px 0 18px 0;position:fixed;width:100%;top:0;z-index:99}#header-img{width:60px;height:60px;margin-right:24px;border-radius:30px;vertical-align:middle}#header-h,#header-sub{padding:0 18px 0 0}#header-sub{font-size:13px;color:#999}#nav{margin-right:-18px}#nav li a{margin-left:24px;padding:0 18px;font-size:15px}#nav li a:hover{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;background-color:#0079bc;color:#fbfbfb;padding:6px 18px}#footer{padding:30px 40px;color:#999}#main{margin-top:132px;margin-bottom:48px}#go-top{bottom:50px;right:40px;position:fixed;color:#fff;padding-top:6px;padding-bottom:8px;opacity:.4}#article-container article{margin-bottom:40px;padding-bottom:40px;border-bottom:1px dashed #bbb;margin-bottom:50px}#article-container .tag-banner{font-size:16px;margin-bottom:20px;padding-bottom:20px;border-bottom:1px dashed #bbb;margin-bottom:28px}#article-container .meta .comments{margin-bottom:0;margin-top:8px;margin-right:18px;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;padding-bottom:2px}#article-container .meta .comments a{color:#fff;font-size:18px;display:block;cursor:pointer}#article-container .meta .views{top:-8px;left:-12px;padding:2px 6px;line-height:20px;text-align:center;font-size:12px;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;margin-bottom:0}#article-container .title{margin-bottom:24px;padding-bottom:24px;border-bottom:1px dashed #ddd;font-size:24px}#article-container .content{margin-top:-12px}#article-container .info{margin-bottom:0;color:#999;font-size:12px}#article-container .info span{border-right:1px dashed #999;padding-right:12px;margin-right:12px}#article-container .info .tag a{margin-left:4px}#article-container .article-single h3.title{padding-top:0}#article-container .article-single .views{color:#fff;font-size:18px}#article-pager a{margin:0}#article-pager a:hover{color:#fbfbfb}#article-sidebar .sidebar{margin-bottom:24px}#article-sidebar .sidebar .title{padding-top:0}#pop-article-sidebar .list li{margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd}#pop-article-sidebar .pop-num{padding:4px;margin-left:12px;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif;font-size:12px}#recent-comment-sidebar .list li{margin-bottom:8px;padding-bottom:8px;border-bottom:1px dashed #ddd}#recent-comment-sidebar .author{padding:4px 6px;margin-right:6px}#comment h4{padding-top:0}#comment .comments a{color:#fff;font-size:18px}#comment-list .comment{margin-bottom:32px}#comment-list .c-avatar{margin-right:18px;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;margin-top:6px}#comment-list .c-meta p{margin-bottom:0}#comment-list .c-meta .c-time{color:#999;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#comment-list .c-meta .c-author{font-size:16px;color:#333;display:block}#comment-list .c-meta .c-author:hover{color:#005b9b}#comment-list .c-meta .c-reply{color:#fff;background:#ddd;padding:3px 10px}#comment-list .c-meta .c-reply:hover{background-color:#0079bc}#comment-list .c-content{padding-top:4px}#comment-list .c-check{font-size:13px;color:#e64346;margin-left:12px}#comment-list .c-p-md{margin-top:12px;font-size:12px;line-height:20px;color:#666}#comment-show{margin-bottom:32px}#comment-title{margin-bottom:20px;padding-bottom:20px;border-bottom:1px dashed #ddd}#comment-form{width:80%;margin:auto;margin-bottom:30px}#comment-form .c-info{width:26%}#comment-form .c-info .ipt{width:100%;box-sizing:border-box;min-width:0}#comment-form .c-content{width:70%}#comment-form .c-avatar{border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;margin-top:6px;width:50px}#comment-form .reply-md{margin-bottom:16px;font-size:12px;line-height:20px;color:#666}#comment-form .cancel-reply{border:none;margin-left:18px;display:none}#comment-form .cancel-reply:hover{cursor:pointer}#comment-content{width:100%;box-sizing:border-box;height:180px;resize:none}@media only screen and (max-width:1248px){.container{padding:0 24px;width:auto}}@media only screen and (max-width:960px){.container960{padding:0 24px;width:auto}#article-container.left{width:100%}#article-sidebar{display:none}}@media only screen and (max-width:760px){#header-sub{display:none}#header{padding:12px 0}#article-container .main{margin-left:0}#article-container .meta{display:none}#article-container .main:before{display:none}#comment-form .c-info,#comment-form .c-content{width:100%;float:left}#comment-form .c-info{text-align:left}#footer span{display:block;float:none;text-align:center}#article-pager{margin-left:0}}@media only screen and (max-width:560px){#article-container .views{display:none}} ================================================ FILE: static/css/sitemap.xsl ================================================ XML Sitemap

XML Sitemap

This is a XML Sitemap which is supposed to be processed by search engines like Google, MSN Search and YAHOO.
You can find more information about XML sitemaps on sitemaps.org and Google's list of sitemap programs.

high
URL Priority Change Frequency LastChange (GMT)
================================================ FILE: static/css/style.css ================================================ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block}audio,canvas,video{display:inline-block}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}legend{color:#000}html,body{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif;font-size:14px;line-height:30px;color:#333;background-color:#fbfbfb}a{text-decoration:none;color:#0079bc}a:hover{color:#005b9b}p{margin-bottom:18px}h1,h2,h3,h4,h5,h6{padding:12px 0}h1{font-size:28px}h2{font-size:24px}h3{font-size:21px}h4{font-size:19px}h5{font-size:16px}h6{font-size:14px}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.left{float:left}.right{float:right}.absolute{position:absolute}.relative{position:relative}.clear:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.vertical-middle{vertical-align:middle}.inline{display:inline}.inline-block{display:inline-block}.block{display:block}.fade-out{opacity:0}.hide{display:none !important}.container{max-width:1200px;margin:auto}.container960{max-width:960px;margin:auto}.grid-1-2{width:50%}.grid-1-3{width:33.3333%}.grid-1-4{width:25%}.grid-1-5{width:20%}.grid-1-6{width:16.6666%}.grid-2-3{width:66.6666%}.grid-3-4{width:75%}.grid-3-5{width:60%}.grid-4-5{width:80%}.grid-5-6{width:83.3333%}input,textarea,select,button{font-family:Ubuntu,Consolas,"Microsoft YaHei",Verdana,Tahoma,Arial,sans-serif}.form legend{font-size:18px;margin-bottom:14px}.form label{display:inline-block;margin-right:12px}.form .ipt{padding:8px 12px;border:1px solid #999;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;min-width:180px}.form .ipt:focus{border-color:#0079bc}.form .chk{display:inline-block;margin:2px 6px 0 0;line-height:normal}.form .field{margin-bottom:24px}.form .invalid{margin-right:12px}.form .tip{font-size:13px;color:#999;margin-left:12px}.form-vertical label{display:block;margin-bottom:8px}.form-vertical .ipt{width:100%;box-sizing:border-box}.form-vertical .invalid{margin-right:0;margin-top:6px}.form-align label{display:inline-block;min-width:60px;text-align:right}.form-align .invalid{margin-right:0;margin-top:6px}.btn{min-width:120px;height:36px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;outline:none;border:none;margin:0}.btn:hover{background-color:#999;cursor:pointer}a.btn{line-height:36px;color:#fff}.btn-red{background-color:#e64346;color:#fbfbfb}.btn-red:hover{background-color:#c7383a}.btn-blue{background-color:#0079bc;color:#fbfbfb}.btn-blue:hover{background-color:#005b9b}.btn-green{background-color:#7ab277;color:#fbfbfb}.btn-green:hover{background-color:#649462}.lbl{padding:4px 12px;background-color:#ccc;color:#333;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.lbl-red{background-color:#e64346;color:#fbfbfb}a.lbl{line-height:26px}a.lbl-red:hover{background-color:#c7383a;color:#fbfbfb}.lbl-blue{background-color:#0079bc;color:#fbfbfb}a.lbl-blue:hover{background-color:#005b9b;color:#fbfbfb}.lbl-green{background-color:#7ab277;color:#fbfbfb}a.lbl-green:hover{background-color:#649462;color:#fbfbfb}.pager .item{padding:2px 8px;margin:0 6px;color:#333;display:inline-block;line-height:20px}.pager .item a{color:#333}.pager .item:hover{background-color:#0079bc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .item:hover a{color:#fff}.pager .current{background-color:#666;color:#fbfbfb;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.pager .current a{color:#fbfbfb}.pager .current:hover{background-color:#0079bc}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{padding:18px 0 9px 0;font-weight:bold}.markdown h1{font-size:24px}.markdown h2{font-size:21px}.markdown h1,.markdown h2{margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed #ddd}.markdown h3{font-size:19px}.markdown h4{font-size:18px}.markdown h5{font-size:16px}.markdown h6{font-size:14px}.markdown p{margin-bottom:10px}.markdown ul{list-style:disc inside}.markdown ol{list-style:decimal inside}.markdown code{font-family:Consolas,"Courier New",Arial}.markdown p code{color:#c7383a}.markdown blockquote{padding:8px 18px;border-left:4px solid #ccc;background-color:#fbfbfb}.markdown blockquote p{margin-bottom:0}.markdown pre code{font-size:12px;line-height:18px !important;padding:8px 18px;display:block;margin:12px 0 18px 0}.markdown ol,.markdown ul{margin:12px 24px}.markdown p img{max-width:99%;height:auto;margin:0 auto;display:block}.markdown table{margin:12px 0;width:98%}.markdown table th,.markdown table td{border:1px solid #ccc;padding:4px 12px}.markdown table thead{background:#f6f6f6}::-webkit-scrollbar{width:8px;margin-right:2px}::-webkit-scrollbar-track-piece{background-color:#f5f5f5;border-left:1px solid #d2d2d2}::-webkit-scrollbar-thumb{background:#9fa09c;width:8px}::-webkit-scrollbar-thumb:hover{background:#b7b8ad}html,body{background:url("../img/bg.png") repeat}#header{background:url("../img/header.gif") repeat #4c7298;min-width:120px;padding:30px 0;color:#fbfbfb}#header-img{width:96px;height:96px;background-color:#fff;border:1px solid #ccc;border-radius:50px;-moz-border-radius:50px;-webkit-border-radius:50px}#header-h{padding-top:24px;font-size:32px}#header-h a{color:#fff;font-weight:bold}#nav{height:54px;background-color:#fbfbfb;box-shadow:0 0 2px #bbb;-moz-box-shadow:0 0 2px #bbb;-webkit-box-shadow:0 0 2px #bbb;border-bottom:1px solid #ccc}#nav li{line-height:50px;padding:0 18px}#nav li a{font-size:16px;color:#333;padding:0 32px;display:block}#nav li a:hover{border-bottom:4px solid #0079bc}#nav.fixed{position:fixed;width:100%;top:0}#main{margin:30px auto}#footer{color:#ccc;background-color:#1c2429;padding:24px 0}#footer a{color:#ccc}#footer p{margin-bottom:9px;font-weight:bold;letter-spacing:1px}#footer p a{margin:0 16px}#footer p a:hover{color:#fbfbfb}#footer p a .fa{margin-right:8px}#go-top{bottom:50px;right:40px;position:fixed;color:#fff;padding-top:6px;padding-bottom:8px;opacity:.4}#article-container .meta{width:108px;line-height:24px}#article-container .meta .fa{margin-right:8px}#article-container .meta .comments,#article-container .meta .views,#article-container .meta .time{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#article-container .meta .time{color:#fff}#article-container .meta a{color:#fff}#article-container .meta a:hover{color:#fff}#article-container .main{margin-left:140px}#article-container h3.title{padding:8px 16px;background-color:#4c7298;border-top-left-radius:2px;border-top-right-radius:2px}#article-container h3.title a{color:#eee}#article-container h3.title a:hover{color:#fff}#article-container .content{background-color:#fff;border:1px solid #ccc;border-top:none;padding:18px 24px 24px}#article-container .info{margin-bottom:0;background-color:#fbfbfb;border:1px solid #ccc;border-top:none;border-bottom-left-radius:2px;border-bottom-right-radius:2px;color:#999}#article-container .info .fa{margin-right:8px}#article-container .info .share .fa{margin-right:0}#article-container .info>*{padding:6px 18px}#article-container .info>span{border-right:1px solid #ccc}#article-container .info .right{border-left:1px solid #ccc;border-right:none}#article-container .info .read{color:#999}#article-container .info .read:hover{background-color:#0079bc;color:#fbfbfb}#article-container .info .time,#article-container .info .views span{font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#article-container .info .tag a{margin:0 4px;color:#999}#article-container .info .tag a:hover{color:#333}#article-container article{margin-bottom:48px}#article-container .tag-banner{text-align:center;font-size:18px;margin-bottom:30px}#comment{margin-top:-24px;border:1px solid #ccc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;padding:24px;background:#fff}#comment-form{width:80%;margin:auto}#comment-form .c-info{width:26%}#comment-form .c-info .ipt{width:100%;box-sizing:border-box;min-width:0}#comment-form .c-content{width:70%}#comment-form .c-avatar{width:48px;height:48px;padding:2px;border:1px solid #ccc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}#comment-form .reply-md{margin-bottom:16px;font-size:12px;line-height:20px;color:#666}#comment-form .cancel-reply{border:none;margin-left:18px;display:none}#comment-form .cancel-reply:hover{cursor:pointer}#comment-content{width:100%;box-sizing:border-box;height:180px;resize:none}#comment-list .c-avatar{width:48px;height:48px;padding:2px;border:1px solid #ccc;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;margin-right:18px}#comment-list .comment{margin-bottom:18px;padding-bottom:18px;border-bottom:1px dashed #ddd}#comment-list .c-meta>*{margin-right:16px}#comment-list .c-time{color:#999;font-family:Verdana,Tahoma,'微软雅黑','宋体',sans-serif}#comment-list .c-time .fa{margin-right:6px}#comment-list .c-reply{color:#999}#comment-list .c-reply:hover{color:#333}#comment-list .c-author{font-size:13px}#comment-list .c-author.admin{background-color:#e64346;color:#fbfbfb}#comment-list .c-p-md{margin-top:12px;font-size:12px;line-height:20px;color:#666}#comment-list .c-section{max-width:830px}#comment-list .c-check{font-size:13px;color:#e64346}#comment-list .c-check .fa{margin-right:6px}@media only screen and (max-width:960px){.container960{padding:0 24px;width:auto}}@media only screen and (max-width:760px){.container960{padding:0 24px;width:auto}#article-container .main{margin-left:0}#article-container .meta.left{display:none}#comment-form .c-info,#comment-form .c-content{width:100%;float:left}#comment-form .c-info{text-align:left}}@media only screen and (max-width:560px){.container960{padding:0;width:auto}#nav li{padding:0 10px}#header-img{float:left;width:64px;height:64px;margin-left:24px}#header-h{padding:17px;font-size:24px;float:left}#header-sub{display:none}#article-container .tag,#article-container .time{display:none}#comment-form{width:100%}}@media only screen and (max-width:480px){.container960{padding:0;width:auto}#header-h{float:none}#header-img{display:none}#header-sub{display:none}#comment-list .c-avatar{display:none}#nav li a{padding:0 16px}} ================================================ FILE: static/js/home.js ================================================ $(document).ready(function () { //fixHeader(); topButton(); renderMarkdown(); initComment(); }); function fixHeader() { var $nav = $('#nav'); var top = $nav.offset().top; console.log(top); $(window).scroll(function () { if (top < $(this).scrollTop()) { $nav.addClass("fixed").removeClass("text-center"); } else { $nav.removeClass("fixed").addClass("text-center"); } }); } function topButton() { var top = $('#nav').offset().top; var $top = $('#go-top'); $(window).scroll(function () { if (top < $(this).scrollTop()) { $top.removeClass("hide"); } else { $top.addClass('hide'); } }); $top.on("click", function () { $('body,html').animate({scrollTop: 0}, 500); return false; }) } function renderMarkdown() { var $md = $('.markdown'); $md.each(function (i, item) { $(item).html(marked($(item).html().replace(/>/g, '>'))); }); var code = $md.find('pre code'); if (code.length) { $("").attr({ rel: "stylesheet", type: "text/css", href: "/static/css/highlight.css"}).appendTo("head"); $.getScript("/static/lib/highlight.min.js", function () { code.each(function (i, item) { hljs.highlightBlock(item) }); }); } } function initComment() { var $list = $('#comment-list'); if (!$list.length) { return; } if (localStorage.getItem("comment-author")) { $('#comment-author').val(localStorage.getItem("comment-author")); $('#comment-email').val(localStorage.getItem("comment-email")); $('#comment-url').val(localStorage.getItem("comment-url")); $('#comment-avatar').attr("src", localStorage.getItem("comment-avatar")); $('.c-avatar').removeClass("null"); } $('#comment-content').on("focus", function () { if ($('.c-avatar').hasClass("null")) { $('.c-avatar-field').remove(); $('.c-info-fields').removeClass("hide"); } }); $('.not-me').on("click", function () { $('.c-avatar-field').remove(); $('.c-info-fields').removeClass("hide"); return false; }); $('#comment-show').on("click", ".enable", function () { $("#comment-show").remove(); $('#comment-form').removeClass("hide"); }); $('#comment-form').ajaxForm(function (json) { if (json.res) { localStorage.setItem("comment-author", $('#comment-author').val()); localStorage.setItem("comment-email", $('#comment-email').val()); localStorage.setItem("comment-url", $('#comment-url').val()); localStorage.setItem("comment-avatar", json.comment.avatar); var tpl = $($('#comment-tpl').html()); tpl.find(".c-avatar").attr("src", json.comment.avatar).attr("alt", json.comment.author); tpl.find(".c-author").attr("href", json.comment.url).text(json.comment.author); tpl.find(".c-reply").attr("rel", json.comment.id); tpl.find(".c-content").html(json.comment.content); if (json.comment.parent_md) { tpl.find(".c-p-md").html(marked(json.comment.parent_md)); } else { tpl.find(".c-p-md").remove(); } tpl.attr("id", "comment-" + json.comment.id); if (json.comment.status == "approved") { tpl.find(".c-check").remove(); } $list.append(tpl); $('.cancel-reply').trigger("click"); $('#comment-content').val(""); } else { alert("提交失败!"); } }); $list.on("click", ".c-reply", function () { $('.reply-md').remove(); var id = $(this).attr("rel"); var pc = $('#comment-' + id); var md = "> @" + pc.find(".c-author").text() + "\n\n"; md += "> " + pc.find(".c-content").html() + "\n"; $('#comment-content').before('
' + marked(md) + '
'); $('#comment-parent').val(id); if ($('#comment-show').length) { $('#comment-show .enable').trigger("click"); } $('.cancel-reply').show(); var top = $('#comment-form').offset().top; $('body,html').animate({scrollTop: top}, 500); return false; }); $('.cancel-reply').on("click", function () { $('.reply-md').remove(); $('#comment-parent').val(0); $(this).hide(); return false; }); } ================================================ FILE: static/js/upload.js ================================================ function initUpload(p) { $('#attach-show').on("click", function () { $('#attach-upload').trigger("click"); }); $('#attach-upload').on("change", function () { if (confirm("立即上传?")) { var bar = $('

0%

'); $('#attach-form').ajaxSubmit({ "beforeSubmit": function () { $(p).before(bar); }, "uploadProgress": function (event, position, total, percentComplete) { var percentVal = percentComplete + '%'; bar.css("width", percentVal).html(percentVal); }, "success": function (json) { if (!json.res) { bar.html(json.msg).addClass("err"); setTimeout(function () { bar.remove(); }, 5000); } else { bar.html("/" + json.file.Url + "   (@" + json.file.Name + ")"); } $('#attach-upload').val(""); } }); } else { $(this).val(""); } }); } ================================================ FILE: static/koala-config.json ================================================ { "mappings": [ { "src": "less", "dest": "css" } ], "ignores": ["*.css"], "options": { "outputStyle": "compress", "lineComments": true, "debugInfo": false, "strictMath": true, "strictUnits": false }, "customOptions": [], "includePaths": [] } ================================================ FILE: static/less/admin.less ================================================ @import "common"; #header { height: 39px; background-color: @white0; border-bottom: 1px solid @black3; line-height: 39px; .box-shadow(0, 0, 2px, @gray1); .nav { > a { display: inline-block; padding: 0 18px; border-left: 1px solid @gray1; border-right: 1px solid @gray1; color: @black2; &:hover { border-color: @blue1; background-color: @blue1; color: @white1; } margin-left: -1px; } } .logo { line-height: 36px; padding: 0 14px 0 0; margin: 0; font-size: 14px; } .nav-item { display: inline-block; padding: 0 18px; border-left: 1px solid @gray1; border-right: 1px solid @gray1; color: @black2; margin-right: -1px; &:hover { background-color: @gray3; } } .out { color: @red2; &:hover { border-color: @red1; background-color: @red1; color: @white1; } } } #footer{ padding: 24px; background: @white3; border-top: 1px solid @gray2; margin-top: 30px; color: @black3; font-size: 12px; p{ margin-bottom: 0; } a{ color: @black3; padding:6px 12px; &:hover{ border-bottom: 1px dashed @gray0; } } } .admin { margin: 24px auto 48px auto; } #profile { width: 800px; .admin; .avatar { img { width: 180px; padding: 4px; background-color: @white0; border: 1px solid @gray2; .border-radius(4px); height: 180px; } } .ipt { width: 280px; } .invalid { margin-left: 75px; } .bio{ margin-left: 75px; height: 160px; } } #password { width: 400px; .admin; .invalid { margin-left: 75px; } } #article-list { li { .bottom-line(8px); > * { margin-right: 16px; } .time, .comment { font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; color: @black3; } .comment { color: @green2; .fa { margin-right: 6px; } } .is-comment { color: @red0; .fa { margin-right: 6px; } } .del, .edit { opacity: 0; } &:hover { .del, .edit { opacity: 1; } } &:first-child { h4 { padding-top: 0; } } } margin-bottom: 24px; } #article-form { .admin; input.title { width: 100%; box-sizing: border-box; border-bottom: none; margin-bottom: -1px; font-size: 18px; } select { padding: 4px 6px; } .preview { border: 1px solid #999; background-color: @white0; box-sizing: border-box; padding: 0 12px; height: 700px; margin-left: -1px; border-radius: 2px; overflow-x: scroll; } .form-vertical{ width: 100%; margin-top: 18px; input.ipt{ width: 300px; } .item{ float: left; margin-right: 18px; } .btn{ margin-right: 16px; } .invalid{ display: inline; } } .file-progress{ padding: 0 12px; background: fade(@blue0,20%); color: @black2; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; box-sizing: border-box; .border-radius(2px); } .file-progress.err{ background: fade(@red0,20%); color: @red3; } } #setting-nav{ width: 1000px; margin-top: 24px; li{ display: inline-block; margin: 0 12px; a{ padding:3px 10px; } a:hover,a.current{ border-bottom: 2px solid @blue2; } } .bottom-line(12px); } .setting-panel{ display: none; } .setting-form { width: 820px; .admin; .ipt { width: 480px; } .invalid { margin-left: 75px; } label{ min-width: 10em; } .tip.block{ margin-left: 12em; } } #setting-custom-form{ width: 1000px; input.key{ width: 240px; } input.value{ width: 640px; } .item{ .bottom-line(12px); } .del{ margin-left: 12px; color: @red1; font-size: 12px; } .tip{ margin-left: 0; } } #setting-nav-form{ width:1000px; .item{ .bottom-line(12px); } span.label{ margin-right: 6px; } input.order{ width: 2.5em; min-width: 0; } input.text{ width: 80px; min-width: 0; } input.title{ width: 150px; min-width: 0; } input.link{ width: 340px; } .del{ margin-left: 12px; color: @red1; } } #comment-list{ .c-avatar{ width: 48px; height: 48px; padding: 2px; border: 1px solid @gray1; .border-radius(2px); margin-right: 18px; } .comment{ .bottom-line(12px); } .c-meta{ > *{ margin-right: 16px; } } .c-time{ color: @black3; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; .fa{ margin-right: 6px; } } .c-cnt,.c-email{ color: @black3; font-size: 12px; } .c-author{ font-size: 13px; } .c-author.admin{ .lbl-red; } .c-p-md{ margin-top: 8px; font-size: 12px; line-height: 18px; color: @black2; } .c-section{ max-width: 830px; } .c-check,.c-del{ color: @red1; .fa{ margin-right: 6px; } &:hover{ color: @red3; } } .c-reply,.c-check,.c-del{ font-size: 12px; } } #comment-form{ padding-top: 12px; .btn{ margin-right: 24px; } display: none; margin-left: 72px; } #comment-content{ width: 500px; height: 80px; margin-right: 24px; } #files-list{ li.file{ .bottom-line(8px); >*{ margin-right: 16px; } &:hover{ .del{ opacity: 1 !important; } } } .upload-time{ color: @black3; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .del{ color: @red1; } .file-progress{ padding: 0 12px; background: fade(@blue0,20%); color: @black2; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; box-sizing: border-box; .border-radius(2px); } .file-progress.err{ background: fade(@red0,20%); color: @red3; } .size{ width: 4em; display: inline-block; } } #plugin-list{ li{ .bottom-line(16px); .desc{ margin-bottom: 0; width: 99%; color: @black3; } a.lbl{ padding: 0 8px; margin-left: 16px; } .version{ color: @green3; margin-left: 16px; } .name{ font-size: 16px; } .active{ width: 12px; height: 12px; margin-right: 16px; padding: 0; margin-top: 10px; } .setting{ margin-left: 16px; } } } #plugin-setting-form{ p.item{ clear: both; } label{ float: left; min-width: 6em; text-align: right; margin-right: 2em; } .title{ padding-top: 0; margin-bottom: 18px; } input.ipt{ width: 600px; } } #dashboard{ .grid-1-5{ margin-right: 2%; } .quick-link{ li{ list-style: inside disc; .bottom-line(6px); } } .stats{ .lbl{ padding: 1px 5px; margin: 0 3px; } } .activity{ .msg{ padding: 8px 12px; .bottom-line(8px); line-height: 24px; font-size: 12px; .time{ font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .data{ color: @black2; margin-left: 1.2em; p{ margin-bottom: 0; line-height: 24px; } } .read{ top:0; right:12px; opacity: 0; &:hover{ color: @red1; } } &:hover{ background: fade(@blue0,6%); .read{ opacity: 1; } } } } } ================================================ FILE: static/less/cmd.less ================================================ @import "common"; .cmd { margin: 24px 48px } .cmd-header { .bottom-line(12px); } #backup-btn,#theme-cache-btn{ margin: 10px 0 0 30px; min-width: 0; padding: 0 2em; } #theme-cache-btn{ .btn-red; } #theme-cache-btn.true{ .btn-green; } .cmd-list li{ .bottom-line(12px); } #backup-list{ li{ list-style: disc inside; >span,>a{ margin-right: 16px; } font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; .del{ color: @red1; opacity: 0; } .link{ margin-left: 12px; } &:hover{ .del{ opacity: 1; } } } } #message-list{ .message{ padding: 8px 12px; .bottom-line(8px); line-height: 24px; font-size: 12px; .time{ font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .data{ color: @black2; margin-left: 1.2em; p{ margin-bottom: 0; line-height: 24px; } } .read{ top:0; right:12px; opacity: 0; &:hover{ color: @red1; } } &:hover{ .read{ opacity: 1; } } } } #log-list{ .log{ font-size: 12px; } .name{ margin-right: 1.5em; font-weight: bold; } .time,.name{ font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .text{ line-height: 20px; font-family: Consolas, "Courier New", Arial; color: @black2; padding: 8px 12px; background: @white4; } .remove{ top:0; right:12px; color: @red1; } } #theme-list{ span{ margin-left: 12px; } span.file{ color: @blue1; } span.error-file{ color: @red2; } h5{ cursor: pointer; } } #reader-list{ li{ > *{ margin-right: 18px; } } .email{ color: @black3; } .comments{ font-family:Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; font-size: 12px; padding: 2px 6px; } } ================================================ FILE: static/less/common/base.less ================================================ @import "var"; // ------------- basic ui ------------------- html, body { font-family: Ubuntu, Consolas, "Microsoft YaHei", Verdana, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 30px; color: @black1; background-color: @white1; } a { text-decoration: none; color: @blue1; &:hover { color: @blue2; } } p { margin-bottom: 18px; } h1, h2, h3, h4, h5, h6 { padding: 12px 0; } h1 { font-size: 28px; } h2 { font-size: 24px; } h3 { font-size: 21px; } h4 { font-size: 19px; } h5 { font-size: 16px; } h6 { font-size: 14px; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } .left { float: left; } .right { float: right; } .absolute { position: absolute; } .relative { position: relative; } .clear:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0 } .vertical-middle { vertical-align: middle; } .inline { display: inline; } .inline-block { display: inline-block; } .block { display: block; } .fade-out { opacity: 0; } .hide { display: none !important; } ================================================ FILE: static/less/common/form.less ================================================ @import "base"; input,textarea,select,button{ font-family: Ubuntu, Consolas, "Microsoft YaHei", Verdana, Tahoma, Arial, sans-serif; } .form { legend { font-size: 18px; margin-bottom: 14px; } label { .inline-block; margin-right: 12px; } .ipt { padding: 8px 12px; border: 1px solid @black3; .border-radius(2px); &:focus { border-color: @blue1; } outline: none; min-width: 180px; } .chk { display: inline-block; margin: 2px 6px 0 0; line-height: normal; } .field { margin-bottom: 24px; } .invalid{ margin-right: 12px; } .tip{ font-size: 13px; color: @black3; margin-left: 12px; } } .form-vertical { label { display: block; margin-bottom: 8px; } .ipt{ width: 100%; box-sizing: border-box; } .invalid{ margin-right: 0; margin-top: 6px; } } .form-align { label { .inline-block; min-width: 60px; text-align: right; } .invalid{ margin-right: 0; margin-top: 6px; } } .btn{ min-width: 120px; height: 36px; background-color: @gray1; color: @black1; .border-radius(2px); outline: none; border: none; &:hover{ background-color: @black3; cursor: pointer; } margin: 0; } a.btn{ line-height: 36px; color: @white0; } .btn-red{ background-color: @red1; &:hover{ background-color: @red2; } color: @white1; } .btn-blue{ background-color: @blue1; &:hover{ background-color: @blue2; } color: @white1; } .btn-green{ background-color: @green1; &:hover{ background-color: @green2; } color: @white1; } ================================================ FILE: static/less/common/grid.less ================================================ @import "base"; .container { max-width: 1200px; margin: auto; } .container960 { max-width: 960px; margin: auto; } .grid-1-2 { width: 50%; } .grid-1-3 { width: 33.3333%; } .grid-1-4 { width: 25%; } .grid-1-5 { width: 20%; } .grid-1-6 { width: 16.6666%; } .grid-2-3 { width: 66.6666%; } .grid-3-4 { width: 75%; } .grid-3-5{ width: 60%; } .grid-4-5{ width: 80%; } .grid-5-6 { width: 83.3333%; } ================================================ FILE: static/less/common/label.less ================================================ @import "base"; .lbl { padding: 4px 12px; background-color: @gray1; color: @black1; .border-radius(2px); } .lbl-red { background-color: @red1; color: @white1; } a.lbl{ line-height: 26px; } a.lbl-red { &:hover { background-color: @red2; color: @white1; } } .lbl-blue { background-color: @blue1; color: @white1; } a.lbl-blue { &:hover { background-color: @blue2; color: @white1; } } .lbl-green { background-color: @green1; color: @white1; } a.lbl-green { &:hover { background-color: @green2; color: @white1; } } ================================================ FILE: static/less/common/markdown.less ================================================ @import "var"; .markdown{ h1,h2,h3,h4,h5,h6{ padding:18px 0 9px 0; font-weight: bold; } h1{ font-size: 24px; } h2{ font-size: 21px; } h1,h2{ .bottom-line(10px); } h3{ font-size: 19px; } h4{ font-size: 18px; } h5{ font-size: 16px; } h6{ font-size: 14px; } p{ margin-bottom: 10px; } ul{ list-style: disc inside; } ol{ list-style: decimal inside; } code{ font-family: Consolas, "Courier New", Arial; } p code{ color: @red2; } blockquote{ padding: 8px 18px; border-left: 4px solid @gray1; background-color: @white1; p{ margin-bottom: 0; } } pre code{ font-size: 12px; line-height: 18px !important; padding: 8px 18px; display: block; margin: 12px 0 18px 0; } ol,ul{ margin: 12px 24px; } p img{ max-width: 99%; height: auto; margin: 0 auto; display: block; } table{ margin: 12px 0; width: 98%; th,td{ border: 1px solid @gray1; padding: 4px 12px; } thead{ background: @white3; } } } ================================================ FILE: static/less/common/pager.less ================================================ @import "var"; .pager { .item { padding: 2px 8px; margin: 0 6px; color: @black1; display: inline-block; line-height: 20px; a { color: @black1; } &:hover { background-color: @blue1; .border-radius(2px); a { color: @white0; } } } .current { background-color: @black2; color: @white1; .border-radius(2px); a { color: @white1; } &:hover { background-color: @blue1; } } } ================================================ FILE: static/less/common/reset.less ================================================ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin: 0; padding: 0; } header, footer, section, article, aside, nav, hgroup, address, figure, figcaption, menu, details { display: block; } audio, canvas, video { display: inline-block; } table { border-collapse: collapse; border-spacing: 0; } fieldset, img { border: 0; } address, caption, cite, code, dfn, em, th, var { font-style: normal; font-weight: normal; } ol, ul { list-style: none; } caption, th { text-align: left; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } q:before, q:after { content: ''; } abbr, acronym { border: 0; font-variant: normal; } sup { vertical-align: text-top; } sub { vertical-align: text-bottom; } input, textarea, select { font-family: inherit; font-size: inherit; font-weight: inherit; } legend { color: #000; } ================================================ FILE: static/less/common/var.less ================================================ @black0: #000; @black1: #333; @black2: #666; @black3: #999; @black4: #BBB; @white0: #FFFFFF; @white1: #FBFBFB; @white2: #F9F9F9; @white3: #F6F6F6; @white4: #F3F3F3; @gray0: #BBB; @gray1: #CCC; @gray2: #DDD; @gray3: #EEE; @blue0: #0096df; @blue1: #0079bc; @blue2: #005b9b; @blue3: #00377a; @red0: #ff4447; @red1: #E64346; @red2: #c7383a; @red3: #aa393c; @green0: #93d090; @green1: #7ab277; @green2: #649462; @green3: #507650; .bottom-line(@distance,@color:@gray2,@style:dashed) { margin-bottom: @distance; padding-bottom: @distance; border-bottom: 1px @style @color; } .border-radius (@radius) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; } .box-shadow (@x: 0, @y: 0, @blur: 1px, @color: @black1) { box-shadow: @arguments; -moz-box-shadow: @arguments; -webkit-box-shadow: @arguments; } .text-shadow (@x: 0, @y: 0, @blur: 1px, @color: @black3) { text-shadow: @arguments; -moz-text-shadow: @arguments; -webkit-text-shadow: @arguments; } ================================================ FILE: static/less/common.less ================================================ @import "common/var"; @import "common/reset"; @import "common/base"; @import "common/grid"; @import "common/form"; @import "common/label"; @import "common/pager"; @import "common/markdown"; ::-webkit-scrollbar{width:8px;margin-right:2px;} ::-webkit-scrollbar-track-piece{background-color:#F5F5F5;border-left:1px solid #D2D2D2;} ::-webkit-scrollbar-thumb{background:#9FA09C;width:8px;} ::-webkit-scrollbar-thumb:hover{background:#B7B8AD;} ================================================ FILE: static/less/ling.less ================================================ @import "common"; html, body { background: @white4; } #header { background: #0093C4; min-width: 120px; padding: 40px 0 48px 0; color: @white1; a { &:hover { color: @white0; .text-shadow(0, 0, 3px, @black1); } } } #header-img { width: 96px; height: 96px; .border-radius(50px); } #header-h { line-height: 94px; a { color: @white1; } color: @white1; padding: 0; margin-left: 24px; } #header-sub { color: @white4; margin-left: 1.2em; font-size: 16px; } #nav { line-height: 90px; li { line-height: 50px; margin-left: 44px; a { font-size: 18px; color: @white4; display: block; &:hover { color: @white0; .text-shadow(0, 0, 3px, @black1); } } } } #footer { padding: 30px 40px; color: @black3; } #main { margin: 30px auto; } #go-top { bottom: 50px; right: 40px; position: fixed; color: @white0; padding-top: 6px; padding-bottom: 8px; opacity: 0.4; } #article-container { height: 100%; .comments, .views { font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .comments { width: 56px; height: 56px; a { color: @white0; } .border-radius(36px); line-height: 56px; font-size: 24px; padding: 0; margin-top: 40px; margin-left: 8px; border: 6px solid @white0; .box-shadow(0, 0, 2px, @black3); &:hover { .box-shadow(0, 0, 4px, @black2); } } .views { top: 14px; left: 0; width: 36px; height: 36px; line-height: 36px; .border-radius(30px); padding: 0; border: 4px solid @white0; .box-shadow(0, 0, 2px, @black3); } .main { margin-left: 116px; .border-radius(4px); .box-shadow(0, 1px, 2px, @gray0); background: @white0; padding: 18px 24px; &:before { content: ""; display: block; border: 11px solid transparent; border-right-color: @white0; position: absolute; top: 63px; left: -22px; } h3.title { font-size: 28px; padding-bottom: 24px; } .time-info { color: @black3; .bottom-line(20px); text-indent: 1em; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } } article { margin-bottom: 50px; } .article-single { .main { margin-left: 0; &:before { display: none; } } .meta { right: 44px; top: -36px; } .views { width: 56px; height: 56px; .border-radius(36px); line-height: 56px; font-size: 24px; padding: 0; border: 6px solid @white0; } } .tag { a { margin: 0 4px; color: @black3; } } } #article-pager { margin-left: 116px; .item { margin: 0; color: @white0; background: @black3; padding: 12px 18px; &:hover { background: @blue1; } .border-radius(4px); } } #comment { .border-radius(4px); .box-shadow(0, 1px, 2px, @gray0); background: @white0; padding: 18px 24px; .meta { right: -24px; top: -30px; .comments { margin-left: 0; margin-top: 0; } } } #comment-list { .comment { margin-bottom: 32px; } .c-avatar { margin-right: 18px; .border-radius(4px); margin-top: 6px; } .c-meta { p { margin-bottom: 0; } .c-time { color: @black3; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .c-author { font-size: 16px; color: @black1; display: block; &:hover { color: @blue2; } } .c-reply { color: @white0; background: @gray2; padding: 3px 10px; &:hover { background-color: @blue1; } } } .c-content { padding-top: 4px; } .c-check { font-size: 13px; color: @red1; margin-left: 12px; } .c-p-md { margin-top: 12px; font-size: 12px; line-height: 20px; color: @black2; } } #comment-show { margin-bottom: 32px; } #comment-title { .bottom-line(20px); } #comment-form { width: 80%; margin: auto; margin-bottom: 30px; .c-info { width: 26%; .ipt { width: 100%; box-sizing: border-box; min-width: 0; } } .c-content { width: 70%; } .c-avatar { .border-radius(4px); margin-top: 6px; width: 50px; } .reply-md { margin-bottom: 16px; font-size: 12px; line-height: 20px; color: @black2; } .cancel-reply { border: none; &:hover { cursor: pointer; } margin-left: 18px; display: none; } } #comment-content { width: 100%; box-sizing: border-box; height: 180px; resize: none; } @media only screen and (max-width: 960px) { .container960 { padding: 0 24px; width: auto; } } @media only screen and (max-width: 760px) { .container960 { padding: 0 24px; width: auto; } #article-container { .main { margin-left: 0; } .meta { display: none; } .main:before { display: none; } } #comment-form { .c-info, .c-content { width: 100%; float: left; } .c-info { text-align: left; } } #nav, #header-h { line-height: 50px; } #footer { span { float: none; text-align: center; } } #article-pager { margin-left: 0; } } @media only screen and (max-width: 560px) { .container960 { padding: 0; width: auto; } #article-pager{ margin: 0 12px; } #header-h { margin-left: 24px; } #header-img { display: none; } #comment-form { width: 100%; } #nav { float: left; margin-left: 24px; li { margin-left: 0; margin-right: 44px; } } #footer { span { float: none; display: block; } } } @media only screen and (max-width: 480px) { #header-sub { display: none; } } ================================================ FILE: static/less/saber.less ================================================ @import "common"; html, body { background: @white2; } #header { background: #FFF; box-shadow: 0 0 4px @black2; line-height: 60px; padding: 12px 0 18px 0; position: fixed; width: 100%; top:0; z-index: 99; } #header-img { width: 60px; height: 60px; margin-right: 24px; border-radius: 30px; vertical-align: middle; } #header-h, #header-sub { padding: 0 18px 0 0; } #header-sub { font-size: 13px; color: @black3; } #nav { margin-right: -18px; li { a { margin-left: 24px; padding: 0 18px; &:hover { .lbl; .lbl-blue; padding: 6px 18px; } font-size: 15px; } } } #footer { padding: 30px 40px; color: @black3; } #main { margin-top: 132px; margin-bottom: 48px; } #go-top { bottom: 50px; right: 40px; position: fixed; color: @white0; padding-top: 6px; padding-bottom: 8px; opacity: 0.4; } #article-container { article { .bottom-line(40px, @black4); margin-bottom: 50px; } .tag-banner { font-size: 16px; .bottom-line(20px, @black4); margin-bottom: 28px; } .meta { .comments { margin-bottom: 0; margin-top: 8px; margin-right: 18px; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; padding-bottom: 2px; a { color: @white0; font-size: 18px; display: block; cursor: pointer; } } .views { top: -8px; left: -12px; padding: 2px 6px; line-height: 20px; text-align: center; font-size: 12px; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; margin-bottom: 0; } } .title { .bottom-line(24px); font-size: 24px; } .content { margin-top: -12px; } .info { margin-bottom: 0; span { border-right: 1px dashed @black3; padding-right: 12px; margin-right: 12px; } color: @black3; font-size: 12px; .tag { a { margin-left: 4px; } } } .article-single { h3.title { padding-top: 0; } .views { color: #fff; font-size: 18px; } } } #article-pager { a { margin: 0; } a:hover { color: @white1; } } #article-sidebar { .sidebar { .title { padding-top: 0; } margin-bottom: 24px; } } #pop-article-sidebar { .list { li { .bottom-line(8px); } } .pop-num { padding: 4px; margin-left: 12px; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; font-size: 12px; } } #recent-comment-sidebar { .list { li { .bottom-line(8px); } } .author { padding: 4px 6px; margin-right: 6px; } } #comment { h4 { padding-top: 0; } .comments { a { color: #fff; font-size: 18px; } } } #comment-list { .comment { margin-bottom: 32px; } .c-avatar { margin-right: 18px; .border-radius(4px); margin-top: 6px; } .c-meta { p { margin-bottom: 0; } .c-time { color: @black3; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .c-author { font-size: 16px; color: @black1; display: block; &:hover { color: @blue2; } } .c-reply { color: @white0; background: @gray2; padding: 3px 10px; &:hover { background-color: @blue1; } } } .c-content { padding-top: 4px; } .c-check { font-size: 13px; color: @red1; margin-left: 12px; } .c-p-md { margin-top: 12px; font-size: 12px; line-height: 20px; color: @black2; } } #comment-show { margin-bottom: 32px; } #comment-title { .bottom-line(20px); } #comment-form { width: 80%; margin: auto; margin-bottom: 30px; .c-info { width: 26%; .ipt { width: 100%; box-sizing: border-box; min-width: 0; } } .c-content { width: 70%; } .c-avatar { .border-radius(4px); margin-top: 6px; width: 50px; } .reply-md { margin-bottom: 16px; font-size: 12px; line-height: 20px; color: @black2; } .cancel-reply { border: none; &:hover { cursor: pointer; } margin-left: 18px; display: none; } } #comment-content { width: 100%; box-sizing: border-box; height: 180px; resize: none; } @media only screen and (max-width: 1248px) { .container { padding: 0 24px; width: auto; } } @media only screen and (max-width: 960px) { .container960 { padding: 0 24px; width: auto; } #article-container.left{ width: 100%; } #article-sidebar{ display: none; } } @media only screen and (max-width: 760px) { #header-sub{ display: none; } #header{ padding: 12px 0; } #article-container { .main { margin-left: 0; } .meta { display: none; } .main:before { display: none; } } #comment-form { .c-info, .c-content { width: 100%; float: left; } .c-info { text-align: left; } } #footer { span { display: block; float: none; text-align: center; } } #article-pager { margin-left: 0; } } @media only screen and (max-width: 560px) { #article-container{ .views{ display: none; } } } ================================================ FILE: static/less/style.less ================================================ @import "common"; html,body{ background: url("../img/bg.png") repeat; } #header{ background: url("../img/header.gif") repeat #4c7298; min-width: 120px; padding: 30px 0; color: @white1; } #header-img{ width: 96px; height: 96px; background-color: @white0; border: 1px solid @gray1; .border-radius(50px); } #header-h{ padding-top: 24px; a{ color: @white0; font-weight: bold; } font-size: 32px; } #nav{ height: 54px; background-color: @white1; .box-shadow(0,0,2px,@gray0); border-bottom: 1px solid @gray1; li{ line-height: 50px; padding: 0 18px; a{ font-size: 16px; color: @black1; padding: 0 32px; display: block; &:hover{ border-bottom: 4px solid @blue1; } } } } #nav.fixed{ position: fixed; width: 100%; top:0; } #main{ margin: 30px auto; } #footer{ color: @gray1; background-color: #1c2429; padding: 24px 0; a{ color: @gray1; } p{ margin-bottom: 9px; font-weight: bold; letter-spacing: 1px; a{ margin: 0 16px; &:hover{ color: @white1; } .fa{ margin-right: 8px; } } } } #go-top{ bottom:50px; right:40px; position: fixed; color: @white0; padding-top: 6px; padding-bottom: 8px; opacity: 0.4; } #article-container{ .meta{ width: 108px; line-height: 24px; .fa{ margin-right: 8px; } .comments,.views,.time{ font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .time{ color: @white0; } a{ color: @white0; &:hover{ color: @white0; } } } .main{ margin-left: 140px; } h3.title{ padding: 8px 16px; background-color: #4c7298; border-top-left-radius: 2px; border-top-right-radius: 2px; a{ color: @gray3; &:hover{ color: @white0; } } } .content{ background-color: @white0; border:1px solid @gray1; border-top: none; padding: 18px 24px 24px; } .info{ margin-bottom: 0; background-color: @white1; border:1px solid @gray1; border-top: none; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; .fa{ margin-right: 8px; } .share .fa{ margin-right: 0; } /* .weibo .fa:hover{ color: @red1; }*/ >*{ padding: 6px 18px; } > span{ border-right: 1px solid @gray1; } .right{ border-left: 1px solid @gray1; border-right: none; } color: @black3; .read{ color: @black3; &:hover{ background-color: @blue1; color: @white1; } } .time,.views span{ font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; } .tag a{ margin: 0 4px; color: @black3; &:hover{ color: @black1; } } } article{ margin-bottom: 48px; } .tag-banner{ text-align: center; font-size: 18px; margin-bottom: 30px; } } #comment{ margin-top: -24px; border: 1px solid @gray1; .border-radius(2px); padding:24px; background: @white0; } #comment-form{ width: 80%; margin: auto; .c-info{ width: 26%; .ipt{ width: 100%; box-sizing: border-box; min-width:0; } } .c-content{ width: 70%; } .c-avatar{ width: 48px; height: 48px; padding: 2px; border: 1px solid @gray1; .border-radius(2px); } .reply-md{ margin-bottom: 16px; font-size: 12px; line-height: 20px; color: @black2; } .cancel-reply{ border: none; &:hover{ cursor: pointer; } margin-left: 18px; display: none; } } #comment-content{ width: 100%; box-sizing: border-box; height: 180px; resize: none; } #comment-list{ .c-avatar{ width: 48px; height: 48px; padding: 2px; border: 1px solid @gray1; .border-radius(2px); margin-right: 18px; } .comment{ .bottom-line(18px); } .c-meta{ > *{ margin-right: 16px; } } .c-time{ color: @black3; font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif; .fa{ margin-right: 6px; } } .c-reply{ color: @black3; &:hover{ color: @black1; } } .c-author{ font-size: 13px; } .c-author.admin{ .lbl-red; } .c-p-md{ margin-top: 12px; font-size: 12px; line-height: 20px; color: @black2; } .c-section{ max-width: 830px; } .c-check{ font-size: 13px; color: @red1; .fa{ margin-right: 6px; } } } @media only screen and (max-width: 960px) { .container960{ padding:0 24px; width: auto; } } @media only screen and (max-width: 760px) { .container960{ padding:0 24px; width: auto; } #article-container{ .main{ margin-left: 0; } .meta.left{ display: none; } } #comment-form{ .c-info,.c-content{ width: 100%; float: left; } .c-info{ text-align: left; } } } @media only screen and (max-width: 560px) { .container960{ padding:0; width: auto; } #nav{ li{ padding: 0 10px; } } #header-img{ float: left; width: 64px; height: 64px; margin-left: 24px; } #header-h{ padding:17px; font-size: 24px; float: left; } #header-sub{ display: none; } #article-container{ .tag,.time{ display: none; } } #comment-form{ width: 100%; } } @media only screen and (max-width: 480px) { .container960{ padding:0; width: auto; } #header-h{ float: none; } #header-img{ display: none; } #header-sub{ display: none; } #comment-list{ .c-avatar{ display: none; } } #nav li a{ padding: 0 16px; } } ================================================ FILE: view/admin/admin.layout ================================================ {{.Title}} - Fxh.Go {@Content} ================================================ FILE: view/admin/articles.html ================================================
  • 添加文章
  • {{range .Articles}}
  • {{DateInt64 .CreateTime "MM.DD"}}

    {{.Title}}

    {{if ne .Status "publish"}} 草稿{{end}} {{.Slug}}{{if eq .IsComment false}} 关评{{end}} {{.CommentNum}} / {{.Hits}} 编辑 删除
  • {{end}}
    {{range .Pager.PageSlice}}
  • {{.}}
  • {{end}}
================================================ FILE: view/admin/cmd/backup.html ================================================

备份数据

    {{range .Files}}
  • {{DateTime .ModTime "MM.DD HH:mm"}} {{.Name}} 下载 {{FileSize .Size}} 删除
  • {{end}}
================================================ FILE: view/admin/cmd/log.html ================================================

错误日志

    {{range .Logs}}
  • {{.Name}} {{DateInt64 .CreateTime "MM.DD HH:mm"}}
    {{.Text}}
    删除
  • {{end}}
================================================ FILE: view/admin/cmd/message.html ================================================

消息记录

    {{range .Messages}}
  • {{DateInt64 .CreateTime "MM.DD HH:mm"}}
    {{Html .Data}}
  • {{end}}
================================================ FILE: view/admin/cmd/monitor.html ================================================

系统监控

  • Goroutine数量{{.M.NumGoroutine}}
  • 系统内存分配{{.M.MemSys}}
  • 实际内存占用{{.M.MemHeap}}
  • 强制回收极限{{.M.MemGc}}
  • 上次回收时间{{.M.LastGcTime}} ago
================================================ FILE: view/admin/cmd/reader.html ================================================

读者

  • 如果删除读者,不会影响读者已有的评论;但此后该读者的新评论需要审核。
  • {{range .Readers}}
  • {{.Author}} {{.Comments}} 删除
  • {{end}}
================================================ FILE: view/admin/cmd/theme.html ================================================

主题风格

    {{range .Themes}}
  • {{if eq .Name $.CurrentTheme}}
    {{.Name}}
    {{else}}
    {{.Name}}
    {{end}}{{range .Layout}} {{.}}{{end}}{{range .Files}} {{.}}{{end}}{{range .ErrorFiles}} {{.}}{{end}}
  • {{end}}

主题名对应视图中的目录。高亮的主题即当前使用的主题。单击主题名即可切换现用主题。

================================================ FILE: view/admin/cmd.layout ================================================ {{.Title}} - Fxh.Go {@Content}

Back

================================================ FILE: view/admin/comments.html ================================================
{{range .Comments}}
{{.Author}}
{{.Author}}{{if .IsAdmin}}  (admin){{end}} {{DateInt64 .CreateTime "MM.DD HH:mm"}} {{if .GetContent}} @{{.GetContent.Title}}{{else}} @无效{{end}}{{if ne .Status "approved"}} 审核中{{end}} 回复 删除
{{Html .Content}}
{{if .ParentMd}}
{{Html .ParentMd}}
{{end}}
{{end}}
    {{range .Pager.PageSlice}}
  • {{.}}
  • {{end}}
================================================ FILE: view/admin/edit_article.html ================================================

固定链接   

标签  

保存状态  

允许评论  

固定链接由字母,数字和-组成

================================================ FILE: view/admin/edit_page.html ================================================

固定链接   

保存状态  

允许评论  

置顶链接  

固定链接由字母,数字和-组成

================================================ FILE: view/admin/files.html ================================================
  • {{range .Files}}
  • {{DateInt64 .UploadTime "MM.DD"}} {{FileSize .Size}} {{.Name}} 查看 删除
  • {{end}} {{range .Pager.PageSlice}}
  • {{.}}
  • {{end}}
================================================ FILE: view/admin/home.html ================================================

Welcome

欢迎回来, {{.User.Nick}}

最新活动

{{range .Messages}}
{{DateInt64 .CreateTime "MM.DD HH:mm"}}
{{Html .Data}}
隐藏
{{end}}{{if lt (len .Messages) 1}}

没有新的活动信息

{{end}}

数据统计

已经发布文章 {{.Statis.Articles}} 篇, 页面 {{.Statis.Pages}} 个,
收到评论 {{.Statis.Comments}} 次, 上传 {{.Statis.Files}} 个附件,
评论者 {{.Statis.Readers}}

当前程序版本:{{.Statis.Version}}

官方消息

还没有消息

================================================ FILE: view/admin/login.html ================================================ 登录 - Fxh.Go

登录 - Fxh.Go

用户名为字母+数字,长度4-20个字符

密码长度4-20个字符

默认记住登陆3天
================================================ FILE: view/admin/pages.html ================================================
  • 添加页面
  • {{range .Pages}}
  • {{DateInt64 .CreateTime "MM.DD"}}

    {{.Title}}

    {{if ne .Status "publish"}} 草稿{{end}} {{.Slug}}{{if eq .IsComment false}} 关评{{end}} {{.CommentNum}} / {{.Hits}} 编辑 删除
  • {{end}}
    {{range .Pager.PageSlice}}
  • {{.}}
  • {{end}}
================================================ FILE: view/admin/password.html ================================================

验证旧密码
密码长度4-20个字符


密码长度4-20个字符


确认密码不匹配

================================================ FILE: view/admin/plugin.html ================================================
    {{range .Plugins}}
  • {{if .IsActive}}  {{end}} {{.Name}} {{.Version}}{{if .HasSetting}} 选项{{end}}{{if .IsActive}} 封印{{else}} 激活{{end}}

    {{.Desc}}

  • {{end}}
================================================ FILE: view/admin/plugin_setting.html ================================================
{{Html .Form}}
================================================ FILE: view/admin/profile.html ================================================
{{.User.Nick}} 头像由 Gravatar 提供

修改密码

登录的用户名
用户名为字母+数字,长度4-20个字符

显示在前台的称呼
昵称长度2-20个字符

联系邮箱,十分重要!
邮箱格式错误


网址格式错误

================================================ FILE: view/admin/setting.html ================================================

默认关闭,使用前端marked.js渲染,填true时开启

{{range .Navigators}}

排序     文本     标题     链接     删除

{{end}}

     添加一项

{{range $k,$v := .Custom}}

     删除

{{end}}

     添加一项 使用函数自定义配置,需要加前缀"c_",如GetSetting("c_key")

================================================ FILE: view/admin/write_article.html ================================================

固定链接   

标签  

保存状态  

允许评论  

固定链接由字母,数字和-组成

================================================ FILE: view/admin/write_page.html ================================================

固定链接   

保存状态  

允许评论  

置顶链接  

固定链接由字母,数字和-组成

================================================ FILE: view/default/article.html ================================================
{{with .Article}}

{{.Title}}

{{Html .Content}}

{{if .User}} {{.User.Nick}}{{end}} {{DateInt64 .CreateTime "MM.DD"}}{{if .TagString}} {{range .GetTags}}{{.Name}}{{end}}{{end}} 阅读  {{.Hits}}  次

{{end}}
{{Html .CommentHtml}}
================================================ FILE: view/default/comment.html ================================================
{{range .Comments}}{{if .IsValid}}
{{.Author}}
{{.Author}}{{if .IsAdmin}}  (admin){{end}} {{DateInt64 .CreateTime "MM.DD HH:mm"}}
{{Html .Content}}
{{if .ParentMd}}
{{Html .ParentMd}}
{{end}}
{{end}}{{end}}
{{if .Content.IsComment}} {{else}} {{end}}
{{if .Content.IsComment}}
{{end}}
================================================ FILE: view/default/error/error.html ================================================ 错误提示

您访问的页面正在打瞌睡


程序员正在努力唤醒,请稍候访问...

返回首页

================================================ FILE: view/default/error/notfound.html ================================================ 错误提示

您访问的页面离家出走


程序员正在四处寻找,请稍候访问...

返回首页

================================================ FILE: view/default/home.layout ================================================ {{if .Title}}{{.Title}} - {{end}}{{Setting "site_title"}}
{@Content}
================================================ FILE: view/default/index.html ================================================
{{if .Tag}}
标签:{{.Tag}}
{{end}}{{range .Articles}} {{end}}
{{range .Pager.PageSlice}} {{.}}{{end}}
================================================ FILE: view/default/page.html ================================================
{{with .Page}}

{{.Title}}

{{Html .Content}}

{{if .User}} {{.User.Nick}}{{end}} {{DateInt64 .CreateTime "MM.DD"}} 阅读  {{.Hits}}  次

{{end}}
================================================ FILE: view/ling/article.html ================================================
{{with .Article}}

{{.Hits}}

{{.Title}}

{{if .User}}{{.User.Nick}}   {{end}}发表于   {{DateInt64 .CreateTime "YYYY 年 MM 月 DD 日"}}

{{Html .Content}}

标签:{{.TagString}}

{{end}}
{{Html .CommentHtml}}
================================================ FILE: view/ling/comment.html ================================================

文章评论

{{range .Comments}}{{if .IsValid}}
{{.Author}}
回复

{{.Author}}{{if .IsAdmin}}  (admin){{end}}

{{DateInt64 .CreateTime "MM 月 DD 日 HH 时 mm 分"}}

{{Html .Content}}
{{if .ParentMd}}
{{Html .ParentMd}}
{{end}}
{{end}}{{end}}
{{if .Content.IsComment}} {{else}} {{end}}
{{if .Content.IsComment}}
{{end}}
================================================ FILE: view/ling/error/error.html ================================================ 错误提示

您访问的页面正在打瞌睡


程序员正在努力唤醒,请稍候访问...

返回首页

================================================ FILE: view/ling/error/notfound.html ================================================ 错误提示

您访问的页面离家出走


程序员正在四处寻找,请稍候访问...

返回首页

================================================ FILE: view/ling/home.layout ================================================ {{if .Title}}{{.Title}} - {{end}}{{Setting "site_title"}}
{@Content}
Go © 2014 All rights reserved. RSS . Proudly Powered by Fxh.Go.
{{Setting `c_footer_ga` | Html}}
{{Html ""}} ================================================ FILE: view/ling/index.html ================================================
{{range .Articles}} {{end}}
{{if .Pager.IsNext}}较旧的文章{{end}} {{if .Pager.IsPrev}}较新的文章{{end}}
================================================ FILE: view/ling/page.html ================================================
{{with .Page}}

{{.Hits}}

{{.Title}}

{{if .User}}{{.User.Nick}}   {{end}}发表于   {{DateInt64 .CreateTime "YYYY 年 MM 月 DD 日"}}

{{Html .Content}}
{{end}}
================================================ FILE: view/rss.xml ================================================ {{Html ``}} {{.Title}} {{.Link}}/ {{.Desc}} {{.Created}}{{range .Articles}} {{.Title}} {{.Link}} {{.Desc}} {{.Author}} {{.Created}} {{end}} ================================================ FILE: view/saber/article.html ================================================
{{with .Article}}
{{.Hits}}

{{.Title}}

{{Html .Content}}

{{if .User}}{{.User.Nick}}   {{end}}发表于   {{DateInt64 .CreateTime "YYYY 年 MM 月 DD 日"}} 标签:{{range .GetTags}}{{.Name}}{{end}}

{{end}}
{{Html .CommentHtml}}
================================================ FILE: view/saber/comment.html ================================================
{{.Content.CommentNum}}

文章评论

{{range .Comments}}{{if .IsValid}}
{{.Author}}
回复

{{.Author}}{{if .IsAdmin}}  (admin){{end}}

{{DateInt64 .CreateTime "MM 月 DD 日 HH 时 mm 分"}}

{{Html .Content}}
{{if .ParentMd}}
{{Html .ParentMd}}
{{end}}
{{end}}{{end}}
{{if .Content.IsComment}} {{else}} {{end}}
{{if .Content.IsComment}}
{{end}}
================================================ FILE: view/saber/error/error.html ================================================ 错误提示

您访问的页面正在打瞌睡


程序员正在努力唤醒,请稍候访问...

返回首页

================================================ FILE: view/saber/error/notfound.html ================================================ 错误提示

您访问的页面离家出走


程序员正在四处寻找,请稍候访问...

返回首页

================================================ FILE: view/saber/home.layout ================================================ {{if .Title}}{{.Title}} - {{end}}{{Setting "site_title"}}
{@Content}
Go © 2014 All rights reserved. GitHub     Feed     Proudly Powered by Fxh.Go.
Top {{Setting `c_footer_ga` | Html}}
================================================ FILE: view/saber/index.html ================================================
{{if .Tag}}
标签:{{.Tag}}
{{end}}{{range .Articles}} {{end}}
{{if .Pager.IsNext}}较旧的文章{{end}} {{if .Pager.IsPrev}}较新的文章{{end}}
{{Html .SidebarHtml}} ================================================ FILE: view/saber/page.html ================================================
{{with .Page}}
{{.Hits}}

{{.Title}}

{{Html .Content}}

{{if .User}}{{.User.Nick}}   {{end}}发表于   {{DateInt64 .CreateTime "YYYY 年 MM 月 DD 日"}}

{{end}}
================================================ FILE: view/saber/sidebar.html ================================================
热评文章
    {{range .Popular}}
  • {{.Title}} {{.CommentNum}}
  • {{end}}
================================================ FILE: view/sitemap.xml ================================================ {{Html ``}}{{Html ``}} {{.Link}} {{.Created}} daily 1.0 {{range .Navigators}} {{.Link}} {{.Created}} weekly 0.6 {{end}}{{range .Articles}} {{.Link}} {{.Created}} monthly 0.3 {{end}}